Commit 03046886 authored by vikram.jadhav07's avatar vikram.jadhav07 Committed by Theodore Ts'o

ext4: clean up error handling in the MMP support

There is memory leak as both caller function kmmpd() and callee
read_mmp_block() not releasing bh_check  (i.e buffer_head).
Given patch fixes this problem.

[ Additional changes suggested by Andreas Dilger -- TYT ]
Signed-off-by: default avatarJadhav Vikram <vikramjadhavpucsd2007@gmail.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent 490c1b44
...@@ -91,21 +91,22 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, ...@@ -91,21 +91,22 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh,
submit_bh(READ_SYNC | REQ_META | REQ_PRIO, *bh); submit_bh(READ_SYNC | REQ_META | REQ_PRIO, *bh);
wait_on_buffer(*bh); wait_on_buffer(*bh);
if (!buffer_uptodate(*bh)) { if (!buffer_uptodate(*bh)) {
brelse(*bh);
*bh = NULL;
ret = -EIO; ret = -EIO;
goto warn_exit; goto warn_exit;
} }
mmp = (struct mmp_struct *)((*bh)->b_data); mmp = (struct mmp_struct *)((*bh)->b_data);
if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC) if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC) {
ret = -EFSCORRUPTED; ret = -EFSCORRUPTED;
else if (!ext4_mmp_csum_verify(sb, mmp)) goto warn_exit;
}
if (!ext4_mmp_csum_verify(sb, mmp)) {
ret = -EFSBADCRC; ret = -EFSBADCRC;
else goto warn_exit;
}
return 0; return 0;
warn_exit: warn_exit:
brelse(*bh);
*bh = NULL;
ext4_warning(sb, "Error %d while reading MMP block %llu", ext4_warning(sb, "Error %d while reading MMP block %llu",
ret, mmp_block); ret, mmp_block);
return ret; return ret;
...@@ -181,15 +182,13 @@ static int kmmpd(void *data) ...@@ -181,15 +182,13 @@ static int kmmpd(void *data)
EXT4_FEATURE_INCOMPAT_MMP)) { EXT4_FEATURE_INCOMPAT_MMP)) {
ext4_warning(sb, "kmmpd being stopped since MMP feature" ext4_warning(sb, "kmmpd being stopped since MMP feature"
" has been disabled."); " has been disabled.");
EXT4_SB(sb)->s_mmp_tsk = NULL; goto exit_thread;
goto failed;
} }
if (sb->s_flags & MS_RDONLY) { if (sb->s_flags & MS_RDONLY) {
ext4_warning(sb, "kmmpd being stopped since filesystem " ext4_warning(sb, "kmmpd being stopped since filesystem "
"has been remounted as readonly."); "has been remounted as readonly.");
EXT4_SB(sb)->s_mmp_tsk = NULL; goto exit_thread;
goto failed;
} }
diff = jiffies - last_update_time; diff = jiffies - last_update_time;
...@@ -211,9 +210,7 @@ static int kmmpd(void *data) ...@@ -211,9 +210,7 @@ static int kmmpd(void *data)
if (retval) { if (retval) {
ext4_error(sb, "error reading MMP data: %d", ext4_error(sb, "error reading MMP data: %d",
retval); retval);
goto exit_thread;
EXT4_SB(sb)->s_mmp_tsk = NULL;
goto failed;
} }
mmp_check = (struct mmp_struct *)(bh_check->b_data); mmp_check = (struct mmp_struct *)(bh_check->b_data);
...@@ -225,7 +222,9 @@ static int kmmpd(void *data) ...@@ -225,7 +222,9 @@ static int kmmpd(void *data)
"The filesystem seems to have been" "The filesystem seems to have been"
" multiply mounted."); " multiply mounted.");
ext4_error(sb, "abort"); ext4_error(sb, "abort");
goto failed; put_bh(bh_check);
retval = -EBUSY;
goto exit_thread;
} }
put_bh(bh_check); put_bh(bh_check);
} }
...@@ -248,7 +247,8 @@ static int kmmpd(void *data) ...@@ -248,7 +247,8 @@ static int kmmpd(void *data)
retval = write_mmp_block(sb, bh); retval = write_mmp_block(sb, bh);
failed: exit_thread:
EXT4_SB(sb)->s_mmp_tsk = NULL;
kfree(data); kfree(data);
brelse(bh); brelse(bh);
return retval; return retval;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment