[ 3.8.y.z extended stable ] Patch "ext4: fix error handling in ext4_ext_truncate()" has been added to staging queue

Kamal Mostafa kamal at canonical.com
Thu Jul 25 19:28:56 UTC 2013


This is a note to let you know that I have just added a patch titled

    ext4: fix error handling in ext4_ext_truncate()

to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue

This patch is scheduled to be released in version 3.8.13.6.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

>From 0859b5267e468c6c003c1598d78941a095e87717 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso at mit.edu>
Date: Mon, 15 Jul 2013 00:09:19 -0400
Subject: ext4: fix error handling in ext4_ext_truncate()

commit 8acd5e9b1217e58a57124d9e225afa12efeae20d upstream.

Previously ext4_ext_truncate() was ignoring potential error returns
from ext4_es_remove_extent() and ext4_ext_remove_space().  This can
lead to the on-diks extent tree and the extent status tree cache
getting out of sync, which is particuarlly bad, and can lead to file
system corruption and potential data loss.

Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
[ kamal: backport to 3.8 (context) ]
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
 fs/ext4/extents.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index a5ce6ce..728c8f6 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4326,9 +4326,20 @@ void ext4_ext_truncate(struct inode *inode)

 	last_block = (inode->i_size + sb->s_blocksize - 1)
 			>> EXT4_BLOCK_SIZE_BITS(sb);
+retry:
 	err = ext4_es_remove_extent(inode, last_block,
 				    EXT_MAX_BLOCKS - last_block);
+	if (err == ENOMEM) {
+		cond_resched();
+		congestion_wait(BLK_RW_ASYNC, HZ/50);
+		goto retry;
+	}
+	if (err) {
+		ext4_std_error(inode->i_sb, err);
+		return;
+	}
 	err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1);
+	ext4_std_error(inode->i_sb, err);

 	/* In a multi-transaction truncate, we only make the final
 	 * transaction synchronous.
--
1.8.1.2





More information about the kernel-team mailing list