diff options
| author | vikram.jadhav07 <vikramjadhavpucsd2007@gmail.com> | 2016-03-13 17:56:52 -0400 |
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2016-03-13 17:56:52 -0400 |
| commit | 0304688676bdfc8159e165313d71da19c118ba27 (patch) | |
| tree | 029ff2743a674d77d37e2c27d1c651b72fb4500e | |
| parent | 490c1b444ce653d0784a9a5fa4d11287029feeb9 (diff) | |
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: Jadhav Vikram <vikramjadhavpucsd2007@gmail.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
| -rw-r--r-- | fs/ext4/mmp.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c index 0a512aa81bf7..24445275d330 100644 --- a/fs/ext4/mmp.c +++ b/fs/ext4/mmp.c | |||
| @@ -91,21 +91,22 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, | |||
| 91 | submit_bh(READ_SYNC | REQ_META | REQ_PRIO, *bh); | 91 | submit_bh(READ_SYNC | REQ_META | REQ_PRIO, *bh); |
| 92 | wait_on_buffer(*bh); | 92 | wait_on_buffer(*bh); |
| 93 | if (!buffer_uptodate(*bh)) { | 93 | if (!buffer_uptodate(*bh)) { |
| 94 | brelse(*bh); | ||
| 95 | *bh = NULL; | ||
| 96 | ret = -EIO; | 94 | ret = -EIO; |
| 97 | goto warn_exit; | 95 | goto warn_exit; |
| 98 | } | 96 | } |
| 99 | |||
| 100 | mmp = (struct mmp_struct *)((*bh)->b_data); | 97 | mmp = (struct mmp_struct *)((*bh)->b_data); |
| 101 | if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC) | 98 | if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC) { |
| 102 | ret = -EFSCORRUPTED; | 99 | ret = -EFSCORRUPTED; |
| 103 | else if (!ext4_mmp_csum_verify(sb, mmp)) | 100 | goto warn_exit; |
| 101 | } | ||
| 102 | if (!ext4_mmp_csum_verify(sb, mmp)) { | ||
| 104 | ret = -EFSBADCRC; | 103 | ret = -EFSBADCRC; |
| 105 | else | 104 | goto warn_exit; |
| 106 | return 0; | 105 | } |
| 107 | 106 | return 0; | |
| 108 | warn_exit: | 107 | warn_exit: |
| 108 | brelse(*bh); | ||
| 109 | *bh = NULL; | ||
| 109 | ext4_warning(sb, "Error %d while reading MMP block %llu", | 110 | ext4_warning(sb, "Error %d while reading MMP block %llu", |
| 110 | ret, mmp_block); | 111 | ret, mmp_block); |
| 111 | return ret; | 112 | return ret; |
| @@ -181,15 +182,13 @@ static int kmmpd(void *data) | |||
| 181 | EXT4_FEATURE_INCOMPAT_MMP)) { | 182 | EXT4_FEATURE_INCOMPAT_MMP)) { |
| 182 | ext4_warning(sb, "kmmpd being stopped since MMP feature" | 183 | ext4_warning(sb, "kmmpd being stopped since MMP feature" |
| 183 | " has been disabled."); | 184 | " has been disabled."); |
| 184 | EXT4_SB(sb)->s_mmp_tsk = NULL; | 185 | goto exit_thread; |
| 185 | goto failed; | ||
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | if (sb->s_flags & MS_RDONLY) { | 188 | if (sb->s_flags & MS_RDONLY) { |
| 189 | ext4_warning(sb, "kmmpd being stopped since filesystem " | 189 | ext4_warning(sb, "kmmpd being stopped since filesystem " |
| 190 | "has been remounted as readonly."); | 190 | "has been remounted as readonly."); |
| 191 | EXT4_SB(sb)->s_mmp_tsk = NULL; | 191 | goto exit_thread; |
| 192 | goto failed; | ||
| 193 | } | 192 | } |
| 194 | 193 | ||
| 195 | diff = jiffies - last_update_time; | 194 | diff = jiffies - last_update_time; |
| @@ -211,9 +210,7 @@ static int kmmpd(void *data) | |||
| 211 | if (retval) { | 210 | if (retval) { |
| 212 | ext4_error(sb, "error reading MMP data: %d", | 211 | ext4_error(sb, "error reading MMP data: %d", |
| 213 | retval); | 212 | retval); |
| 214 | 213 | goto exit_thread; | |
| 215 | EXT4_SB(sb)->s_mmp_tsk = NULL; | ||
| 216 | goto failed; | ||
| 217 | } | 214 | } |
| 218 | 215 | ||
| 219 | mmp_check = (struct mmp_struct *)(bh_check->b_data); | 216 | mmp_check = (struct mmp_struct *)(bh_check->b_data); |
| @@ -225,7 +222,9 @@ static int kmmpd(void *data) | |||
| 225 | "The filesystem seems to have been" | 222 | "The filesystem seems to have been" |
| 226 | " multiply mounted."); | 223 | " multiply mounted."); |
| 227 | ext4_error(sb, "abort"); | 224 | ext4_error(sb, "abort"); |
| 228 | goto failed; | 225 | put_bh(bh_check); |
| 226 | retval = -EBUSY; | ||
| 227 | goto exit_thread; | ||
| 229 | } | 228 | } |
| 230 | put_bh(bh_check); | 229 | put_bh(bh_check); |
| 231 | } | 230 | } |
| @@ -248,7 +247,8 @@ static int kmmpd(void *data) | |||
| 248 | 247 | ||
| 249 | retval = write_mmp_block(sb, bh); | 248 | retval = write_mmp_block(sb, bh); |
| 250 | 249 | ||
| 251 | failed: | 250 | exit_thread: |
| 251 | EXT4_SB(sb)->s_mmp_tsk = NULL; | ||
| 252 | kfree(data); | 252 | kfree(data); |
| 253 | brelse(bh); | 253 | brelse(bh); |
| 254 | return retval; | 254 | return retval; |
