]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Oct 2017 11:33:46 +0000 (13:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Oct 2017 11:33:46 +0000 (13:33 +0200)
added patches:
ext4-avoid-deadlock-when-expanding-inode-size.patch

queue-3.18/ext4-avoid-deadlock-when-expanding-inode-size.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/ext4-avoid-deadlock-when-expanding-inode-size.patch b/queue-3.18/ext4-avoid-deadlock-when-expanding-inode-size.patch
new file mode 100644 (file)
index 0000000..816a435
--- /dev/null
@@ -0,0 +1,88 @@
+From 109f9ac01393e2c1e1a18683396191a8e0c2e8ce Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 11 Aug 2016 12:38:55 -0400
+Subject: [PATCH] ext4: avoid deadlock when expanding inode size
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 2e81a4eeedcaa66e35f58b81e0755b87057ce392 ]
+
+When we need to move xattrs into external xattr block, we call
+ext4_xattr_block_set() from ext4_expand_extra_isize_ea(). That may end
+up calling ext4_mark_inode_dirty() again which will recurse back into
+the inode expansion code leading to deadlocks.
+
+Protect from recursion using EXT4_STATE_NO_EXPAND inode flag and move
+its management into ext4_expand_extra_isize_ea() since its manipulation
+is safe there (due to xattr_sem) from possible races with
+ext4_xattr_set_handle() which plays with it as well.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c |    2 --
+ fs/ext4/xattr.c |   19 +++++++++++++------
+ 2 files changed, 13 insertions(+), 8 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4895,8 +4895,6 @@ int ext4_mark_inode_dirty(handle_t *hand
+                                                     sbi->s_want_extra_isize,
+                                                     iloc, handle);
+                       if (ret) {
+-                              ext4_set_inode_state(inode,
+-                                                   EXT4_STATE_NO_EXPAND);
+                               if (mnt_count !=
+                                       le16_to_cpu(sbi->s_es->s_mnt_count)) {
+                                       ext4_warning(inode->i_sb,
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1291,11 +1291,13 @@ int ext4_expand_extra_isize_ea(struct in
+       int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
+       down_write(&EXT4_I(inode)->xattr_sem);
++      /*
++       * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty
++       */
++      ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
+ retry:
+-      if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
+-              up_write(&EXT4_I(inode)->xattr_sem);
+-              return 0;
+-      }
++      if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
++              goto out;
+       header = IHDR(inode, raw_inode);
+       entry = IFIRST(header);
+@@ -1324,8 +1326,7 @@ retry:
+                               (void *)header, total_ino,
+                               inode->i_sb->s_blocksize);
+               EXT4_I(inode)->i_extra_isize = new_extra_isize;
+-              error = 0;
+-              goto cleanup;
++              goto out;
+       }
+       /*
+@@ -1485,6 +1486,8 @@ retry:
+               kfree(bs);
+       }
+       brelse(bh);
++out:
++      ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
+       up_write(&EXT4_I(inode)->xattr_sem);
+       return 0;
+@@ -1496,6 +1499,10 @@ cleanup:
+       kfree(is);
+       kfree(bs);
+       brelse(bh);
++      /*
++       * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode
++       * size expansion failed.
++       */
+       up_write(&EXT4_I(inode)->xattr_sem);
+       return error;
+ }
index 785376ee02ce3c2bdde291a2000350d8ea797532..b0ee32c3be45884d1bfe694203bfe3b6e35b3654 100644 (file)
@@ -1,2 +1,3 @@
 x86-mm-disable-preemption-during-cr3-read-write.patch
 drm-dp-mst-save-vcpi-with-payloads.patch
+ext4-avoid-deadlock-when-expanding-inode-size.patch