add patch bail-out-from-make_indexed_dir-on-first-error
[ext4-patch-queue.git] / bail-out-from-make_indexed_dir-on-first-error
blob430957e321ecb1a852f9a71eff5fbf8a9cc53d34
1 ext4: bail out from make_indexed_dir() on first error
3 From: Jan Kara <jack@suse.cz>
5 When ext4_handle_dirty_dx_node() or ext4_handle_dirty_dirent_node()
6 fail, there's really something wrong with the fs and there's no point in
7 continuing further. Just return error from make_indexed_dir() in that
8 case. Also initialize frames array so that if we return early due to
9 error, dx_release() doesn't try to dereference uninitialized memory
10 (which could happen also due to error in do_split()).
12 Coverity-id: 741300
13 Signed-off-by: Jan Kara <jack@suse.cz>
14 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
15 Cc: stable@vger.kernel.org
16 ---
17  fs/ext4/namei.c | 28 ++++++++++++++++++----------
18  1 file changed, 18 insertions(+), 10 deletions(-)
20 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
21 index adb559de23c1..cec7257aa74a 100644
22 --- a/fs/ext4/namei.c
23 +++ b/fs/ext4/namei.c
24 @@ -1816,31 +1816,39 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
25                 hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
26         hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
27         ext4fs_dirhash(name, namelen, &hinfo);
28 +       memset(frames, 0, sizeof(frames));
29         frame = frames;
30         frame->entries = entries;
31         frame->at = entries;
32         frame->bh = bh;
33         bh = bh2;
35 -       ext4_handle_dirty_dx_node(handle, dir, frame->bh);
36 -       ext4_handle_dirty_dirent_node(handle, dir, bh);
37 +       retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
38 +       if (retval)
39 +               goto out_frames;        
40 +       retval = ext4_handle_dirty_dirent_node(handle, dir, bh);
41 +       if (retval)
42 +               goto out_frames;        
44         de = do_split(handle,dir, &bh, frame, &hinfo);
45         if (IS_ERR(de)) {
46 -               /*
47 -                * Even if the block split failed, we have to properly write
48 -                * out all the changes we did so far. Otherwise we can end up
49 -                * with corrupted filesystem.
50 -                */
51 -               ext4_mark_inode_dirty(handle, dir);
52 -               dx_release(frames);
53 -               return PTR_ERR(de);
54 +               retval = PTR_ERR(de);
55 +               goto out_frames;
56         }
57         dx_release(frames);
59         retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
60         brelse(bh);
61         return retval;
62 +out_frames:
63 +       /*
64 +        * Even if the block split failed, we have to properly write
65 +        * out all the changes we did so far. Otherwise we can end up
66 +        * with corrupted filesystem.
67 +        */
68 +       ext4_mark_inode_dirty(handle, dir);
69 +       dx_release(frames);
70 +       return retval;
71  }
73  /*
74 -- 
75 1.8.1.4
78 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
79 the body of a message to majordomo@vger.kernel.org
80 More majordomo info at  http://vger.kernel.org/majordomo-info.html