From: Greg Kroah-Hartman Date: Tue, 7 Aug 2012 21:19:09 +0000 (-0700) Subject: 3.5-stable patches X-Git-Tag: v3.5.1~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=48ae63a8f9a713d36ebb6cc473ef72acb8f9f7c5;p=thirdparty%2Fkernel%2Fstable-queue.git 3.5-stable patches added patches: ext4-use-proper-csum-calculation-in-ext4_rename.patch ext4-use-s_csum_seed-instead-of-i_csum_seed-for-xattr-block.patch --- diff --git a/queue-3.5/ext4-use-proper-csum-calculation-in-ext4_rename.patch b/queue-3.5/ext4-use-proper-csum-calculation-in-ext4_rename.patch new file mode 100644 index 00000000000..b2c739103d4 --- /dev/null +++ b/queue-3.5/ext4-use-proper-csum-calculation-in-ext4_rename.patch @@ -0,0 +1,49 @@ +From ef58f69c3c34f6377f1e21d3533c806dbd980ad0 Mon Sep 17 00:00:00 2001 +From: Tao Ma +Date: Mon, 9 Jul 2012 16:29:05 -0400 +Subject: ext4: use proper csum calculation in ext4_rename + +From: Tao Ma + +commit ef58f69c3c34f6377f1e21d3533c806dbd980ad0 upstream. + +In ext4_rename, when the old name is a dir, we need to +change ".." to its new parent and journal the change, so +with metadata_csum enabled, we have to re-calc the csum. + +As the first block of the dir can be either a htree root +or a normal directory block and we have different csum +calculation for these 2 types, we have to choose the right +one in ext4_rename. + +btw, it is found by xfstests 013. + +Signed-off-by: Tao Ma +Signed-off-by: "Theodore Ts'o" +Acked-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/namei.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2918,8 +2918,15 @@ static int ext4_rename(struct inode *old + PARENT_INO(dir_bh->b_data, new_dir->i_sb->s_blocksize) = + cpu_to_le32(new_dir->i_ino); + BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata"); +- retval = ext4_handle_dirty_dirent_node(handle, old_inode, +- dir_bh); ++ if (is_dx(old_inode)) { ++ retval = ext4_handle_dirty_dx_node(handle, ++ old_inode, ++ dir_bh); ++ } else { ++ retval = ext4_handle_dirty_dirent_node(handle, ++ old_inode, ++ dir_bh); ++ } + if (retval) { + ext4_std_error(old_dir->i_sb, retval); + goto end_rename; diff --git a/queue-3.5/ext4-use-s_csum_seed-instead-of-i_csum_seed-for-xattr-block.patch b/queue-3.5/ext4-use-s_csum_seed-instead-of-i_csum_seed-for-xattr-block.patch new file mode 100644 index 00000000000..f39472ff5ae --- /dev/null +++ b/queue-3.5/ext4-use-s_csum_seed-instead-of-i_csum_seed-for-xattr-block.patch @@ -0,0 +1,62 @@ +From 41eb70dde42b2360074a559a6f1fc49860a50179 Mon Sep 17 00:00:00 2001 +From: Tao Ma +Date: Mon, 9 Jul 2012 16:29:27 -0400 +Subject: ext4: use s_csum_seed instead of i_csum_seed for xattr block + +From: Tao Ma + +commit 41eb70dde42b2360074a559a6f1fc49860a50179 upstream. + +In xattr block operation, we use h_refcount to indicate whether the +xattr block is shared among many inodes. And xattr block csum uses +s_csum_seed if it is shared and i_csum_seed if it belongs to +one inode. But this has a problem. So consider the block is shared +first bewteen inode A and B, and B has some xattr update and CoW +the xattr block. When it updates the *old* xattr block(because +of the h_refcount change) and calls ext4_xattr_release_block, we +has no idea that inode A is the real owner of the *old* xattr +block and we can't use the i_csum_seed of inode A either in xattr +block csum calculation. And I don't think we have an easy way to +find inode A. + +So this patch just removes the tricky i_csum_seed and we now uses +s_csum_seed every time for the xattr block csum. The corresponding +patch for the e2fsprogs will be sent in another patch. + +This is spotted by xfstests 117. + +Signed-off-by: Tao Ma +Signed-off-by: "Theodore Ts'o" +Acked-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -127,19 +127,16 @@ static __le32 ext4_xattr_block_csum(stru + struct ext4_xattr_header *hdr) + { + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); +- struct ext4_inode_info *ei = EXT4_I(inode); + __u32 csum, old; + + old = hdr->h_checksum; + hdr->h_checksum = 0; +- if (le32_to_cpu(hdr->h_refcount) != 1) { +- block_nr = cpu_to_le64(block_nr); +- csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&block_nr, +- sizeof(block_nr)); +- } else +- csum = ei->i_csum_seed; ++ block_nr = cpu_to_le64(block_nr); ++ csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&block_nr, ++ sizeof(block_nr)); + csum = ext4_chksum(sbi, csum, (__u8 *)hdr, + EXT4_BLOCK_SIZE(inode->i_sb)); ++ + hdr->h_checksum = old; + return cpu_to_le32(csum); + } diff --git a/queue-3.5/series b/queue-3.5/series index 8a09c3c359b..342add3d992 100644 --- a/queue-3.5/series +++ b/queue-3.5/series @@ -95,3 +95,5 @@ ext4-fix-overhead-calculation-used-by-ext4_statfs.patch ext4-fix-hole-punch-failure-when-depth-is-greater-than-0.patch ext4-don-t-let-i_reserved_meta_blocks-go-negative.patch ext4-undo-ext4_calc_metadata_amount-if-we-fail-to-claim-space.patch +ext4-use-proper-csum-calculation-in-ext4_rename.patch +ext4-use-s_csum_seed-instead-of-i_csum_seed-for-xattr-block.patch