This patch is according to Jan Kara's suggestion: I guess I would just get rid of sb_getblk() in read_mmp_block() and always expect valid bh passed. The only place that passes NULL bh after this patch is one case in ext4_multi_mount_protect() and that can call sb_getblk() on its own. That way we can also simplify read_mmp_block() prototype to: static int read_mmp_block(struct super_block *sb, struct buffer_head *bh); Signed-off-by: Ye Bin <yebin10@xxxxxxxxxx> Reviewed-by: Jan Kara <jack@xxxxxxx> --- fs/ext4/mmp.c | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c index 9788c617e593..d46239a0e36b 100644 --- a/fs/ext4/mmp.c +++ b/fs/ext4/mmp.c @@ -64,33 +64,26 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh) /* * Read the MMP block. It _must_ be read from disk and hence we clear the * uptodate flag on the buffer. + * Caller must ensure pass valid 'bh'. */ -static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, - ext4_fsblk_t mmp_block) +static int read_mmp_block(struct super_block *sb, struct buffer_head *bh) { struct mmp_struct *mmp; int ret; - if (*bh) - clear_buffer_uptodate(*bh); - - /* This would be sb_bread(sb, mmp_block), except we need to be sure - * that the MD RAID device cache has been bypassed, and that the read - * is not blocked in the elevator. */ - if (!*bh) { - *bh = sb_getblk(sb, mmp_block); - if (!*bh) { - ret = -ENOMEM; - goto warn_exit; - } + if (!bh) { + ret = -EINVAL; + goto warn_exit; } - lock_buffer(*bh); - ret = ext4_read_bh(*bh, REQ_META | REQ_PRIO, NULL); + clear_buffer_uptodate(bh); + + lock_buffer(bh); + ret = ext4_read_bh(bh, REQ_META | REQ_PRIO, NULL); if (ret) 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) { ret = -EFSCORRUPTED; goto warn_exit; @@ -101,10 +94,7 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, } return 0; warn_exit: - brelse(*bh); - *bh = NULL; - ext4_warning(sb, "Error %d while reading MMP block %llu", - ret, mmp_block); + ext4_warning(sb, "Error %d while reading MMP block", ret); return ret; } @@ -131,7 +121,6 @@ static int kmmpd(void *data) struct ext4_super_block *es = EXT4_SB(sb)->s_es; struct buffer_head *bh = EXT4_SB(sb)->s_mmp_bh; struct mmp_struct *mmp; - ext4_fsblk_t mmp_block; u32 seq = 0; unsigned long failed_writes = 0; int mmp_update_interval = le16_to_cpu(es->s_mmp_update_interval); @@ -141,7 +130,6 @@ static int kmmpd(void *data) char nodename[EXT4_MMP_NODENAME_LEN]; int retval = 0; - mmp_block = le64_to_cpu(es->s_mmp_block); mmp = (struct mmp_struct *)(bh->b_data); mmp->mmp_time = cpu_to_le64(ktime_get_real_seconds()); /* @@ -195,7 +183,7 @@ static int kmmpd(void *data) */ diff = jiffies - last_update_time; if (diff > mmp_check_interval * HZ) { - retval = read_mmp_block(sb, &bh, mmp_block); + retval = read_mmp_block(sb, bh); if (retval) { ext4_error_err(sb, -retval, "error reading MMP data: %d", @@ -289,7 +277,11 @@ int ext4_multi_mount_protect(struct super_block *sb, goto failed; } - retval = read_mmp_block(sb, &bh, mmp_block); + bh = sb_getblk(sb, mmp_block); + if (!bh) + goto failed; + + retval = read_mmp_block(sb, bh); if (retval) goto failed; @@ -327,7 +319,7 @@ int ext4_multi_mount_protect(struct super_block *sb, goto failed; } - retval = read_mmp_block(sb, &bh, mmp_block); + retval = read_mmp_block(sb, bh); if (retval) goto failed; mmp = (struct mmp_struct *)(bh->b_data); @@ -356,7 +348,7 @@ int ext4_multi_mount_protect(struct super_block *sb, goto failed; } - retval = read_mmp_block(sb, &bh, mmp_block); + retval = read_mmp_block(sb, bh); if (retval) goto failed; mmp = (struct mmp_struct *)(bh->b_data); -- 2.31.1