| From 20e01a2dc7f9ed144995a1d68bbf4b4b7a6e90c6 Mon Sep 17 00:00:00 2001 |
| From: Jan Kara <jack@suse.cz> |
| Date: Tue, 3 May 2011 11:05:55 -0400 |
| Subject: [PATCH] ext4: Fix fs corruption when make_indexed_dir() fails |
| |
| commit 7ad8e4e6ae2a7c95445ee1715b1714106fb95037 upstream. |
| |
| When make_indexed_dir() fails (e.g. because of ENOSPC) after it has |
| allocated block for index tree root, we did not properly mark all |
| changed buffers dirty. This lead to only some of these buffers being |
| written out and thus effectively corrupting the directory. |
| |
| Fix the issue by marking all changed data dirty even in the error |
| failure case. |
| |
| Signed-off-by: Jan Kara <jack@suse.cz> |
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| --- |
| fs/ext4/namei.c | 14 ++++++++++++-- |
| 1 file changed, 12 insertions(+), 2 deletions(-) |
| |
| diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c |
| index 2f31631935ba..caa3c77f1743 100644 |
| --- a/fs/ext4/namei.c |
| +++ b/fs/ext4/namei.c |
| @@ -1452,9 +1452,19 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, |
| frame->bh = bh; |
| bh = bh2; |
| de = do_split(handle,dir, &bh, frame, &hinfo, &retval); |
| - dx_release (frames); |
| - if (!(de)) |
| + if (!de) { |
| + /* |
| + * Even if the block split failed, we have to properly write |
| + * out all the changes we did so far. Otherwise we can end up |
| + * with corrupted filesystem. |
| + */ |
| + ext4_mark_inode_dirty(handle, dir); |
| + ext4_handle_dirty_metadata(handle, dir, frame->bh); |
| + ext4_handle_dirty_metadata(handle, dir, bh); |
| + dx_release(frames); |
| return retval; |
| + } |
| + dx_release(frames); |
| |
| retval = add_dirent_to_buf(handle, dentry, inode, de, bh); |
| brelse(bh); |
| -- |
| 1.8.5.2 |
| |