From: Greg Kroah-Hartman Date: Mon, 24 Feb 2014 23:13:24 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.10.33~52 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b9869c7d0c4044b8a534ec009ceace0e72a4ab2a;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches 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 --- 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 index 00000000000..44c524b20f2 --- /dev/null +++ b/queue-3.10/ext4-don-t-leave-i_crtime.tv_sec-uninitialized.patch @@ -0,0 +1,33 @@ +From 19ea80603715d473600cd993b9987bc97d042e02 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 16 Feb 2014 19:29:32 -0500 +Subject: ext4: don't leave i_crtime.tv_sec uninitialized + +From: Theodore Ts'o + +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 +Tested-by: Vegard Nossum +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..12ff1e5ae1f --- /dev/null +++ b/queue-3.10/ext4-don-t-try-to-modify-s_flags-if-the-the-file-system-is-read-only.patch @@ -0,0 +1,55 @@ +From 23301410972330c0ae9a8afc379ba2005e249cc6 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9aaa1a55a2e --- /dev/null +++ b/queue-3.10/ext4-fix-error-paths-in-swap_inode_boot_loader.patch @@ -0,0 +1,43 @@ +From 30d29b119ef01776e0a301444ab24defe8d8bef3 Mon Sep 17 00:00:00 2001 +From: Zheng Liu +Date: Wed, 12 Feb 2014 11:48:31 -0500 +Subject: ext4: fix error paths in swap_inode_boot_loader() + +From: Zheng Liu + +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 +Cc: Andreas Dilger +Cc: Dr. Tilmann Bubeck +Signed-off-by: Zheng Liu +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..94b872e8304 --- /dev/null +++ b/queue-3.10/ext4-fix-online-resize-with-a-non-standard-blocks-per-group-setting.patch @@ -0,0 +1,37 @@ +From 3d2660d0c9c2f296837078c189b68a47f6b2e3b5 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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" +Reported-by: Jon Bernard +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..da2c195e993 --- /dev/null +++ b/queue-3.10/ext4-fix-online-resize-with-very-large-inode-tables.patch @@ -0,0 +1,133 @@ +From b93c95353413041a8cebad915a8109619f66bcc6 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sat, 15 Feb 2014 21:33:13 -0500 +Subject: ext4: fix online resize with very large inode tables + +From: Theodore Ts'o + +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: + [] ext4_flex_group_add+0x1448/0x1830 + [] ext4_resize_fs+0x7b2/0xe80 + [] ext4_ioctl+0xbf0/0xf00 + [] do_vfs_ioctl+0x2dd/0x4b0 + [] ? final_putname+0x22/0x50 + [] sys_ioctl+0x81/0xa0 + [] 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 [] 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" +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-3.10/series b/queue-3.10/series index 25b6b211dd8..74350febe17 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -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