Fix make-fsync-to-sync-parent-dir-in-no-journal-for-real-this-time
[ext4-patch-queue.git] / fix-bh-leak-on-error-paths
blob31129f0cc61890378effd55ecded2e3804408a6b
1 ext4: fix bh leak on error paths in ext4_rename() and ext4_cross_rename()
3 From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
5 Release references to buffer-heads if ext4_journal_start() fails.
7 Fixes: 5b61de757535 ("ext4: start handle at least possible moment when renaming files")
8 Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
9 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
10 Reviewed-by: Jan Kara <jack@suse.cz>
11 ---
12  fs/ext4/namei.c |   21 +++++++++++++++------
13  1 file changed, 15 insertions(+), 6 deletions(-)
15 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
16 index 28fe71a2904c..8110dd20ad3f 100644
17 --- a/fs/ext4/namei.c
18 +++ b/fs/ext4/namei.c
19 @@ -3264,12 +3264,18 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
20                    EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2);
21         if (!(flags & RENAME_WHITEOUT)) {
22                 handle = ext4_journal_start(old.dir, EXT4_HT_DIR, credits);
23 -               if (IS_ERR(handle))
24 -                       return PTR_ERR(handle);
25 +               if (IS_ERR(handle)) {
26 +                       retval = PTR_ERR(handle);
27 +                       handle = NULL;
28 +                       goto end_rename;
29 +               }
30         } else {
31                 whiteout = ext4_whiteout_for_rename(&old, credits, &handle);
32 -               if (IS_ERR(whiteout))
33 -                       return PTR_ERR(whiteout);
34 +               if (IS_ERR(whiteout)) {
35 +                       retval = PTR_ERR(whiteout);
36 +                       whiteout = NULL;
37 +                       goto end_rename;
38 +               }
39         }
41         if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir))
42 @@ -3433,8 +3439,11 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
43         handle = ext4_journal_start(old.dir, EXT4_HT_DIR,
44                 (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) +
45                  2 * EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2));
46 -       if (IS_ERR(handle))
47 -               return PTR_ERR(handle);
48 +       if (IS_ERR(handle)) {
49 +               retval = PTR_ERR(handle);
50 +               handle = NULL;
51 +               goto end_rename;
52 +       }
54         if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir))
55                 ext4_handle_sync(handle);
58 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
59 the body of a message to majordomo@vger.kernel.org
60 More majordomo info at  http://vger.kernel.org/majordomo-info.html