From: "zhangyi (F)" yi.zhang@huawei.com
mainline inclusion from mainline-5.10-rc1 commit 2d069c0889ef0decda7af6ecbdc63b680b767749 category: bugfix bugzilla: 51832 CVE: NA ---------------------------
Revome all open codes that read metadata buffers, switch to use ext4_read_bh_*() common helpers.
Signed-off-by: zhangyi (F) yi.zhang@huawei.com Suggested-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20200924073337.861472-4-yi.zhang@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu
Conflicts: fs/ext4/balloc.c fs/ext4/inode.c
Signed-off-by: yangerkun yangerkun@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/balloc.c | 5 +---- fs/ext4/extents.c | 3 +-- fs/ext4/ialloc.c | 6 +----- fs/ext4/indirect.c | 2 +- fs/ext4/inode.c | 35 ++++++++++++++--------------------- fs/ext4/mmp.c | 10 +++------- fs/ext4/move_extent.c | 2 +- fs/ext4/resize.c | 2 +- fs/ext4/super.c | 22 +++++++++++----------- 9 files changed, 34 insertions(+), 53 deletions(-)
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 7c92728276951..4fdcde64407b2 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -487,11 +487,8 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group) * submit the buffer_head for reading */ set_buffer_new(bh); - clear_buffer_verified(bh); trace_ext4_read_block_bitmap_load(sb, block_group); - bh->b_end_io = ext4_end_bitmap_read; - get_bh(bh); - submit_bh(REQ_OP_READ, REQ_META | REQ_PRIO, bh); + ext4_read_bh_nowait(bh, REQ_META | REQ_PRIO, ext4_end_bitmap_read); return bh; verify: err = ext4_validate_block_bitmap(sb, desc, block_group, bh); diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3bc2cb4cc5cc5..584c1ffc9a0c2 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -546,8 +546,7 @@ __read_extent_tree_block(const char *function, unsigned int line,
if (!bh_uptodate_or_lock(bh)) { trace_ext4_ext_load_extent(inode, pblk, _RET_IP_); - clear_buffer_verified(bh); - err = bh_submit_read(bh); + err = ext4_read_bh(bh, 0, NULL); if (err < 0) goto errout; } diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 141bfa55ed682..ab1d4590fcbb0 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -188,12 +188,8 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) /* * submit the buffer_head for reading */ - clear_buffer_verified(bh); trace_ext4_load_inode_bitmap(sb, block_group); - bh->b_end_io = ext4_end_bitmap_read; - get_bh(bh); - submit_bh(REQ_OP_READ, REQ_META | REQ_PRIO, bh); - wait_on_buffer(bh); + ext4_read_bh(bh, REQ_META | REQ_PRIO, ext4_end_bitmap_read); ext4_simulate_fail_bh(sb, bh, EXT4_SIM_IBITMAP_EIO); if (!buffer_uptodate(bh)) { put_bh(bh); diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index de42b31728550..87bbbea02c748 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -163,7 +163,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, }
if (!bh_uptodate_or_lock(bh)) { - if (bh_submit_read(bh) < 0) { + if (ext4_read_bh(bh, 0, NULL) < 0) { put_bh(bh); goto failure; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 35b37a2ce8548..23c15124c9ab6 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1023,19 +1023,20 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, ext4_lblk_t block, int map_flags) { struct buffer_head *bh; + int ret;
bh = ext4_getblk(handle, inode, block, map_flags); if (IS_ERR(bh)) return bh; if (!bh || ext4_buffer_uptodate(bh)) return bh; - clear_buffer_verified(bh); - ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1, &bh); - wait_on_buffer(bh); - if (buffer_uptodate(bh)) - return bh; - put_bh(bh); - return ERR_PTR(-EIO); + + ret = ext4_read_bh_lock(bh, REQ_META | REQ_PRIO, true); + if (ret) { + put_bh(bh); + return ERR_PTR(ret); + } + return bh; }
/* Read a contiguous batch of blocks. */ @@ -1055,11 +1056,8 @@ int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count,
for (i = 0; i < bh_count; i++) /* Note that NULL bhs[i] is valid because of holes. */ - if (bhs[i] && !ext4_buffer_uptodate(bhs[i])) { - clear_buffer_verified(bhs[i]); - ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1, - &bhs[i]); - } + if (bhs[i] && !ext4_buffer_uptodate(bhs[i])) + ext4_read_bh_lock(bhs[i], REQ_META | REQ_PRIO, false);
if (!wait) return 0; @@ -1229,7 +1227,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, if (!buffer_uptodate(bh) && !buffer_delay(bh) && !buffer_unwritten(bh) && (block_start < from || block_end > to)) { - ll_rw_block(REQ_OP_READ, 0, 1, &bh); + ext4_read_bh_lock(bh, 0, false); *wait_bh++ = bh; decrypt = ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode); @@ -4086,11 +4084,8 @@ static int __ext4_block_zero_page_range(handle_t *handle, set_buffer_uptodate(bh);
if (!buffer_uptodate(bh)) { - err = -EIO; - ll_rw_block(REQ_OP_READ, 0, 1, &bh); - wait_on_buffer(bh); - /* Uhhuh. Read error. Complain and punt. */ - if (!buffer_uptodate(bh)) + err = ext4_read_bh_lock(bh, 0, true); + if (err) goto unlock; if (S_ISREG(inode->i_mode) && ext4_encrypted_inode(inode)) { @@ -4730,9 +4725,7 @@ static int __ext4_get_inode_loc(struct inode *inode, * Read the block from disk. */ trace_ext4_load_inode(inode); - get_bh(bh); - bh->b_end_io = end_buffer_read_sync; - submit_bh(REQ_OP_READ, REQ_META | REQ_PRIO, bh); + ext4_read_bh_nowait(bh, REQ_META | REQ_PRIO, NULL); wait_on_buffer(bh); if (!buffer_uptodate(bh)) { simulate_eio: diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c index d34cb8c466556..795c3ff2907c2 100644 --- a/fs/ext4/mmp.c +++ b/fs/ext4/mmp.c @@ -85,15 +85,11 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, } }
- get_bh(*bh); lock_buffer(*bh); - (*bh)->b_end_io = end_buffer_read_sync; - submit_bh(REQ_OP_READ, REQ_META | REQ_PRIO, *bh); - wait_on_buffer(*bh); - if (!buffer_uptodate(*bh)) { - ret = -EIO; + ret = ext4_read_bh(*bh, REQ_META | REQ_PRIO, NULL); + if (ret) goto warn_exit; - } + mmp = (struct mmp_struct *)((*bh)->b_data); if (le32_to_cpu(mmp->mmp_magic) != EXT4_MMP_MAGIC) { ret = -EFSCORRUPTED; diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index c2b288cd78839..97512df281e37 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c @@ -215,7 +215,7 @@ mext_page_mkuptodate(struct page *page, unsigned from, unsigned to) for (i = 0; i < nr; i++) { bh = arr[i]; if (!bh_uptodate_or_lock(bh)) { - err = bh_submit_read(bh); + err = ext4_read_bh(bh, 0, NULL); if (err) return err; } diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index cb89381ac5dde..347388e7fae1a 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1250,7 +1250,7 @@ static struct buffer_head *ext4_get_bitmap(struct super_block *sb, __u64 block) if (unlikely(!bh)) return NULL; if (!bh_uptodate_or_lock(bh)) { - if (bh_submit_read(bh) < 0) { + if (ext4_read_bh(bh, 0, NULL) < 0) { brelse(bh); return NULL; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ed75bd2edb539..24dc9137185ff 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -219,19 +219,21 @@ int ext4_read_bh_lock(struct buffer_head *bh, int op_flags, bool wait) struct buffer_head * ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags) { - struct buffer_head *bh = sb_getblk(sb, block); + struct buffer_head *bh; + int ret;
+ bh = sb_getblk(sb, block); if (bh == NULL) return ERR_PTR(-ENOMEM); if (ext4_buffer_uptodate(bh)) return bh; - clear_buffer_verified(bh); - ll_rw_block(REQ_OP_READ, REQ_META | op_flags, 1, &bh); - wait_on_buffer(bh); - if (buffer_uptodate(bh)) - return bh; - put_bh(bh); - return ERR_PTR(-EIO); + + ret = ext4_read_bh_lock(bh, REQ_META | op_flags, true); + if (ret) { + put_bh(bh); + return ERR_PTR(ret); + } + return bh; }
static int ext4_verify_csum_type(struct super_block *sb, @@ -4988,9 +4990,7 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, goto out_bdev; } journal->j_private = sb; - ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1, &journal->j_sb_buffer); - wait_on_buffer(journal->j_sb_buffer); - if (!buffer_uptodate(journal->j_sb_buffer)) { + if (ext4_read_bh_lock(journal->j_sb_buffer, REQ_META | REQ_PRIO, true)) { ext4_msg(sb, KERN_ERR, "I/O error on journal device"); goto out_journal; }