]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Feb 2014 23:13:24 +0000 (15:13 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Feb 2014 23:13:24 +0000 (15:13 -0800)
added patches:
ext4-don-t-leave-i_crtime.tv_sec-uninitialized.patch
ext4-don-t-try-to-modify-s_flags-if-the-the-file-system-is-read-only.patch
ext4-fix-error-paths-in-swap_inode_boot_loader.patch
ext4-fix-online-resize-with-a-non-standard-blocks-per-group-setting.patch
ext4-fix-online-resize-with-very-large-inode-tables.patch

queue-3.10/ext4-don-t-leave-i_crtime.tv_sec-uninitialized.patch [new file with mode: 0644]
queue-3.10/ext4-don-t-try-to-modify-s_flags-if-the-the-file-system-is-read-only.patch [new file with mode: 0644]
queue-3.10/ext4-fix-error-paths-in-swap_inode_boot_loader.patch [new file with mode: 0644]
queue-3.10/ext4-fix-online-resize-with-a-non-standard-blocks-per-group-setting.patch [new file with mode: 0644]
queue-3.10/ext4-fix-online-resize-with-very-large-inode-tables.patch [new file with mode: 0644]
queue-3.10/series

diff --git a/queue-3.10/ext4-don-t-leave-i_crtime.tv_sec-uninitialized.patch b/queue-3.10/ext4-don-t-leave-i_crtime.tv_sec-uninitialized.patch
new file mode 100644 (file)
index 0000000..44c524b
--- /dev/null
@@ -0,0 +1,33 @@
+From 19ea80603715d473600cd993b9987bc97d042e02 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 16 Feb 2014 19:29:32 -0500
+Subject: ext4: don't leave i_crtime.tv_sec uninitialized
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 19ea80603715d473600cd993b9987bc97d042e02 upstream.
+
+If the i_crtime field is not present in the inode, don't leave the
+field uninitialized.
+
+Fixes: ef7f38359 ("ext4: Add nanosecond timestamps")
+Reported-by: Vegard Nossum <vegard.nossum@oracle.com>
+Tested-by: Vegard Nossum <vegard.nossum@oracle.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ext4.h |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -774,6 +774,8 @@ do {                                                                              \
+       if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime))                      \
+               (einode)->xtime.tv_sec =                                       \
+                       (signed)le32_to_cpu((raw_inode)->xtime);               \
++      else                                                                   \
++              (einode)->xtime.tv_sec = 0;                                    \
+       if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra))            \
+               ext4_decode_extra_time(&(einode)->xtime,                       \
+                                      raw_inode->xtime ## _extra);            \
diff --git a/queue-3.10/ext4-don-t-try-to-modify-s_flags-if-the-the-file-system-is-read-only.patch b/queue-3.10/ext4-don-t-try-to-modify-s_flags-if-the-the-file-system-is-read-only.patch
new file mode 100644 (file)
index 0000000..12ff1e5
--- /dev/null
@@ -0,0 +1,55 @@
+From 23301410972330c0ae9a8afc379ba2005e249cc6 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 12 Feb 2014 12:16:04 -0500
+Subject: ext4: don't try to modify s_flags if the the file system is read-only
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 23301410972330c0ae9a8afc379ba2005e249cc6 upstream.
+
+If an ext4 file system is created by some tool other than mke2fs
+(perhaps by someone who has a pathalogical fear of the GPL) that
+doesn't set one or the other of the EXT2_FLAGS_{UN}SIGNED_HASH flags,
+and that file system is then mounted read-only, don't try to modify
+the s_flags field.  Otherwise, if dm_verity is in use, the superblock
+will change, causing an dm_verity failure.
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c |   20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3592,16 +3592,22 @@ static int ext4_fill_super(struct super_
+       for (i = 0; i < 4; i++)
+               sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
+       sbi->s_def_hash_version = es->s_def_hash_version;
+-      i = le32_to_cpu(es->s_flags);
+-      if (i & EXT2_FLAGS_UNSIGNED_HASH)
+-              sbi->s_hash_unsigned = 3;
+-      else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
++      if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
++              i = le32_to_cpu(es->s_flags);
++              if (i & EXT2_FLAGS_UNSIGNED_HASH)
++                      sbi->s_hash_unsigned = 3;
++              else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
+ #ifdef __CHAR_UNSIGNED__
+-              es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
+-              sbi->s_hash_unsigned = 3;
++                      if (!(sb->s_flags & MS_RDONLY))
++                              es->s_flags |=
++                                      cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
++                      sbi->s_hash_unsigned = 3;
+ #else
+-              es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
++                      if (!(sb->s_flags & MS_RDONLY))
++                              es->s_flags |=
++                                      cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
+ #endif
++              }
+       }
+       /* Handle clustersize */
diff --git a/queue-3.10/ext4-fix-error-paths-in-swap_inode_boot_loader.patch b/queue-3.10/ext4-fix-error-paths-in-swap_inode_boot_loader.patch
new file mode 100644 (file)
index 0000000..9aaa1a5
--- /dev/null
@@ -0,0 +1,43 @@
+From 30d29b119ef01776e0a301444ab24defe8d8bef3 Mon Sep 17 00:00:00 2001
+From: Zheng Liu <wenqing.lz@taobao.com>
+Date: Wed, 12 Feb 2014 11:48:31 -0500
+Subject: ext4: fix error paths in swap_inode_boot_loader()
+
+From: Zheng Liu <wenqing.lz@taobao.com>
+
+commit 30d29b119ef01776e0a301444ab24defe8d8bef3 upstream.
+
+In swap_inode_boot_loader() we forgot to release ->i_mutex and resume
+unlocked dio for inode and inode_bl if there is an error starting the
+journal handle.  This commit fixes this issue.
+
+Reported-by: Ahmed Tamrawi <ahmedtamrawi@gmail.com>
+Cc: Andreas Dilger <adilger.kernel@dilger.ca>
+Cc: Dr. Tilmann Bubeck <t.bubeck@reinform.de>
+Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/ioctl.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -145,7 +145,7 @@ static long swap_inode_boot_loader(struc
+       handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
+       if (IS_ERR(handle)) {
+               err = -EINVAL;
+-              goto swap_boot_out;
++              goto journal_err_out;
+       }
+       /* Protect extent tree against block allocations via delalloc */
+@@ -203,6 +203,7 @@ static long swap_inode_boot_loader(struc
+       ext4_double_up_write_data_sem(inode, inode_bl);
++journal_err_out:
+       ext4_inode_resume_unlocked_dio(inode);
+       ext4_inode_resume_unlocked_dio(inode_bl);
diff --git a/queue-3.10/ext4-fix-online-resize-with-a-non-standard-blocks-per-group-setting.patch b/queue-3.10/ext4-fix-online-resize-with-a-non-standard-blocks-per-group-setting.patch
new file mode 100644 (file)
index 0000000..94b872e
--- /dev/null
@@ -0,0 +1,37 @@
+From 3d2660d0c9c2f296837078c189b68a47f6b2e3b5 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 15 Feb 2014 22:42:25 -0500
+Subject: ext4: fix online resize with a non-standard blocks per group setting
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 3d2660d0c9c2f296837078c189b68a47f6b2e3b5 upstream.
+
+The set_flexbg_block_bitmap() function assumed that the number of
+blocks in a blockgroup was sb->blocksize * 8, which is normally true,
+but not always!  Use EXT4_BLOCKS_PER_GROUP(sb) instead, to fix block
+bitmap corruption after:
+
+mke2fs -t ext4 -g 3072 -i 4096 /dev/vdd 1G
+mount -t ext4 /dev/vdd /vdd
+resize2fs /dev/vdd 8G
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Reported-by: Jon Bernard <jbernard@tuxion.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -404,7 +404,7 @@ static int set_flexbg_block_bitmap(struc
+               start = ext4_group_first_block_no(sb, group);
+               group -= flex_gd->groups[0].group;
+-              count2 = sb->s_blocksize * 8 - (block - start);
++              count2 = EXT4_BLOCKS_PER_GROUP(sb) - (block - start);
+               if (count2 > count)
+                       count2 = count;
diff --git a/queue-3.10/ext4-fix-online-resize-with-very-large-inode-tables.patch b/queue-3.10/ext4-fix-online-resize-with-very-large-inode-tables.patch
new file mode 100644 (file)
index 0000000..da2c195
--- /dev/null
@@ -0,0 +1,133 @@
+From b93c95353413041a8cebad915a8109619f66bcc6 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 15 Feb 2014 21:33:13 -0500
+Subject: ext4: fix online resize with very large inode tables
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit b93c95353413041a8cebad915a8109619f66bcc6 upstream.
+
+If a file system has a large number of inodes per block group, all of
+the metadata blocks in a flex_bg may be larger than what can fit in a
+single block group.  Unfortunately, ext4_alloc_group_tables() in
+resize.c was never tested to see if it would handle this case
+correctly, and there were a large number of bugs which caused the
+following sequence to result in a BUG_ON:
+
+kernel bug at fs/ext4/resize.c:409!
+   ...
+call trace:
+ [<ffffffff81256768>] ext4_flex_group_add+0x1448/0x1830
+ [<ffffffff81257de2>] ext4_resize_fs+0x7b2/0xe80
+ [<ffffffff8123ac50>] ext4_ioctl+0xbf0/0xf00
+ [<ffffffff811c111d>] do_vfs_ioctl+0x2dd/0x4b0
+ [<ffffffff811b9df2>] ? final_putname+0x22/0x50
+ [<ffffffff811c1371>] sys_ioctl+0x81/0xa0
+ [<ffffffff81676aa9>] system_call_fastpath+0x16/0x1b
+code: c8 4c 89 df e8 41 96 f8 ff 44 89 e8 49 01 c4 44 29 6d d4 0
+rip  [<ffffffff81254fa1>] set_flexbg_block_bitmap+0x171/0x180
+
+
+This can be reproduced with the following command sequence:
+
+   mke2fs -t ext4 -i 4096 /dev/vdd 1G
+   mount -t ext4 /dev/vdd /vdd
+   resize2fs /dev/vdd 8G
+
+To fix this, we need to make sure the right thing happens when a block
+group's inode table straddles two block groups, which means the
+following bugs had to be fixed:
+
+1) Not clearing the BLOCK_UNINIT flag in the second block group in
+   ext4_alloc_group_tables --- the was proximate cause of the BUG_ON.
+
+2) Incorrectly determining how many block groups contained contiguous
+   free blocks in ext4_alloc_group_tables().
+
+3) Incorrectly setting the start of the next block range to be marked
+   in use after a discontinuity in setup_new_flex_group_blocks().
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/resize.c |   32 ++++++++++++++++++++------------
+ 1 file changed, 20 insertions(+), 12 deletions(-)
+
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -238,6 +238,7 @@ static int ext4_alloc_group_tables(struc
+       ext4_group_t group;
+       ext4_group_t last_group;
+       unsigned overhead;
++      __u16 uninit_mask = (flexbg_size > 1) ? ~EXT4_BG_BLOCK_UNINIT : ~0;
+       BUG_ON(flex_gd->count == 0 || group_data == NULL);
+@@ -261,7 +262,7 @@ next_group:
+       src_group++;
+       for (; src_group <= last_group; src_group++) {
+               overhead = ext4_group_overhead_blocks(sb, src_group);
+-              if (overhead != 0)
++              if (overhead == 0)
+                       last_blk += group_data[src_group - group].blocks_count;
+               else
+                       break;
+@@ -275,8 +276,7 @@ next_group:
+               group = ext4_get_group_number(sb, start_blk - 1);
+               group -= group_data[0].group;
+               group_data[group].free_blocks_count--;
+-              if (flexbg_size > 1)
+-                      flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
++              flex_gd->bg_flags[group] &= uninit_mask;
+       }
+       /* Allocate inode bitmaps */
+@@ -287,22 +287,30 @@ next_group:
+               group = ext4_get_group_number(sb, start_blk - 1);
+               group -= group_data[0].group;
+               group_data[group].free_blocks_count--;
+-              if (flexbg_size > 1)
+-                      flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
++              flex_gd->bg_flags[group] &= uninit_mask;
+       }
+       /* Allocate inode tables */
+       for (; it_index < flex_gd->count; it_index++) {
+-              if (start_blk + EXT4_SB(sb)->s_itb_per_group > last_blk)
++              unsigned int itb = EXT4_SB(sb)->s_itb_per_group;
++              ext4_fsblk_t next_group_start;
++
++              if (start_blk + itb > last_blk)
+                       goto next_group;
+               group_data[it_index].inode_table = start_blk;
+-              group = ext4_get_group_number(sb, start_blk - 1);
++              group = ext4_get_group_number(sb, start_blk);
++              next_group_start = ext4_group_first_block_no(sb, group + 1);
+               group -= group_data[0].group;
+-              group_data[group].free_blocks_count -=
+-                                      EXT4_SB(sb)->s_itb_per_group;
+-              if (flexbg_size > 1)
+-                      flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
++              if (start_blk + itb > next_group_start) {
++                      flex_gd->bg_flags[group + 1] &= uninit_mask;
++                      overhead = start_blk + itb - next_group_start;
++                      group_data[group + 1].free_blocks_count -= overhead;
++                      itb -= overhead;
++              }
++
++              group_data[group].free_blocks_count -= itb;
++              flex_gd->bg_flags[group] &= uninit_mask;
+               start_blk += EXT4_SB(sb)->s_itb_per_group;
+       }
+@@ -615,7 +623,7 @@ handle_ib:
+                       if (err)
+                               goto out;
+                       count = group_table_count[j];
+-                      start = group_data[i].block_bitmap;
++                      start = (&group_data[i].block_bitmap)[j];
+                       block = start;
+               }
index 25b6b211dd8f44a0a3badd10d660f93a126ff0da..74350febe173b060331cf885a052947fadd80ed0 100644 (file)
@@ -1,2 +1,7 @@
 drm-nouveau-set-irq_enabled-manually.patch
 drm-nv50-disp-use-correct-register-to-determine-dp-display-bpp.patch
+ext4-fix-error-paths-in-swap_inode_boot_loader.patch
+ext4-don-t-try-to-modify-s_flags-if-the-the-file-system-is-read-only.patch
+ext4-fix-online-resize-with-very-large-inode-tables.patch
+ext4-fix-online-resize-with-a-non-standard-blocks-per-group-setting.patch
+ext4-don-t-leave-i_crtime.tv_sec-uninitialized.patch