Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1019

kernel-2.6.18-238.el5.src.rpm

From: Eric Sandeen <sandeen@redhat.com>
Date: Tue, 16 Jun 2009 14:40:05 -0500
Subject: [fs] ext4: fix prealloc vs truncate corruption
Message-id: 4A37F515.7020105@redhat.com
O-Subject: [PATCH RHEL5.4] ext4: fix prealloc vs truncate corruption
Bugzilla: 505601
RH-Acked-by: Josef Bacik <josef@redhat.com>
RH-Acked-by: Peter Staubach <staubach@redhat.com>

This is for Bug 505601 - ext4 preallocation corruption with truncate

Backport of the following upstream commit.

Tested with a simplified version of a testcase that ibm provided:

touch ext4_dir/ouch

/root/fallocate -l 416768 ext4_dir/ouch

xfs_io -F -f                                    \
        -c 'pwrite -S 0xAA 0x12000 0x10000'     \
        -c 'fsync'                              \
        -c 'truncate 0x16000'                   \
        ext4_dir/ouch

dd if=ext4_dir/ouch iflag=direct | hexdump -C

Without the fix, the end portion of the file which should
still have the 0xAA data in it is lost, and 0s are returned
instead.

Thanks,
-Eric

From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Date: Wed, 10 Jun 2009 18:22:55 +0000 (-0400)
Subject: ext4: Avoid corrupting the uninitialized bit in the extent during truncate
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=a41f20716975910d9beb90b7efc61107901492b8

ext4: Avoid corrupting the uninitialized bit in the extent during truncate

The unitialized bit was not properly getting preserved in in an extent
which is partially truncated because the it was geting set to the
value of the first extent to be removed or truncated as part of the
truncate operation, and if there are multiple extents are getting
removed or modified as part of the truncate operation, it is only the
last extent which will might be partially truncated, and its
uninitalized bit is not necessarily the same as the first extent to be
truncated.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index fe1645d..1ea04bb 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1996,12 +1996,16 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
 	ex = EXT_LAST_EXTENT(eh);
 
 	ex_ee_block = le32_to_cpu(ex->ee_block);
-	if (ext4_ext_is_uninitialized(ex))
-		uninitialized = 1;
 	ex_ee_len = ext4_ext_get_actual_len(ex);
 
 	while (ex >= EXT_FIRST_EXTENT(eh) &&
 			ex_ee_block + ex_ee_len > start) {
+
+		if (ext4_ext_is_uninitialized(ex))
+			uninitialized = 1;
+		else
+			uninitialized = 0;
+
 		ext_debug("remove ext %lu:%u\n", ex_ee_block, ex_ee_len);
 		path[depth].p_ext = ex;