aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/namei.c
diff options
context:
space:
mode:
authorKonstantin Khlebnikov <khlebnikov@yandex-team.ru>2015-04-02 16:32:15 -0400
committerTheodore Ts'o <tytso@mit.edu>2015-04-02 16:32:15 -0400
commit7071b715873a66b69a9c0c5839963bb51aeae41b (patch)
tree098e6c33b06dd3ede2d81f1edd4ea1ab1ad3cf05 /fs/ext4/namei.c
parent1efff914afac8a965ad63817ecf8861a927c2ace (diff)
ext4: fix bh leak on error paths in ext4_rename() and ext4_cross_rename()
Release references to buffer-heads if ext4_journal_start() fails. Fixes: 5b61de757535 ("ext4: start handle at least possible moment when renaming files") Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Reviewed-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r--fs/ext4/namei.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 28fe71a2904c..8110dd20ad3f 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -3264,12 +3264,18 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
3264 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2); 3264 EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2);
3265 if (!(flags & RENAME_WHITEOUT)) { 3265 if (!(flags & RENAME_WHITEOUT)) {
3266 handle = ext4_journal_start(old.dir, EXT4_HT_DIR, credits); 3266 handle = ext4_journal_start(old.dir, EXT4_HT_DIR, credits);
3267 if (IS_ERR(handle)) 3267 if (IS_ERR(handle)) {
3268 return PTR_ERR(handle); 3268 retval = PTR_ERR(handle);
3269 handle = NULL;
3270 goto end_rename;
3271 }
3269 } else { 3272 } else {
3270 whiteout = ext4_whiteout_for_rename(&old, credits, &handle); 3273 whiteout = ext4_whiteout_for_rename(&old, credits, &handle);
3271 if (IS_ERR(whiteout)) 3274 if (IS_ERR(whiteout)) {
3272 return PTR_ERR(whiteout); 3275 retval = PTR_ERR(whiteout);
3276 whiteout = NULL;
3277 goto end_rename;
3278 }
3273 } 3279 }
3274 3280
3275 if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir)) 3281 if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir))
@@ -3433,8 +3439,11 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
3433 handle = ext4_journal_start(old.dir, EXT4_HT_DIR, 3439 handle = ext4_journal_start(old.dir, EXT4_HT_DIR,
3434 (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) + 3440 (2 * EXT4_DATA_TRANS_BLOCKS(old.dir->i_sb) +
3435 2 * EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2)); 3441 2 * EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2));
3436 if (IS_ERR(handle)) 3442 if (IS_ERR(handle)) {
3437 return PTR_ERR(handle); 3443 retval = PTR_ERR(handle);
3444 handle = NULL;
3445 goto end_rename;
3446 }
3438 3447
3439 if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir)) 3448 if (IS_DIRSYNC(old.dir) || IS_DIRSYNC(new.dir))
3440 ext4_handle_sync(handle); 3449 ext4_handle_sync(handle);