提交 5de440a2 编写于 作者: Z zhangyi (F) 提交者: Yang Yingliang

ext4: introduce ext4_sb_bread_unmovable() to replace sb_bread_unmovable()

mainline inclusion
from mainline-5.10-rc1
commit 8394a6ab
category: bugfix
bugzilla: 51832
CVE: NA
---------------------------

Now we only use sb_bread_unmovable() to read superblock and descriptor
block at mount time, so there is no opportunity that we need to clear
buffer verified bit and also handle buffer write_io error bit. But for
the sake of unification, let's introduce ext4_sb_bread_unmovable() to
replace all sb_bread_unmovable(). After this patch, we stop using read
helpers in fs/buffer.c.
Signed-off-by: Nzhangyi (F) <yi.zhang@huawei.com>
Link: https://lore.kernel.org/r/20200924073337.861472-8-yi.zhang@huawei.comSigned-off-by: NTheodore Ts'o <tytso@mit.edu>
Signed-off-by: Nyangerkun <yangerkun@huawei.com>
Reviewed-by: Nzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 91ae4685
...@@ -2722,6 +2722,8 @@ extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count); ...@@ -2722,6 +2722,8 @@ extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count);
/* super.c */ /* super.c */
extern struct buffer_head *ext4_sb_bread(struct super_block *sb, extern struct buffer_head *ext4_sb_bread(struct super_block *sb,
sector_t block, int op_flags); sector_t block, int op_flags);
extern struct buffer_head *ext4_sb_bread_unmovable(struct super_block *sb,
sector_t block);
extern void ext4_read_bh_nowait(struct buffer_head *bh, int op_flags, extern void ext4_read_bh_nowait(struct buffer_head *bh, int op_flags,
bh_end_io_t *end_io); bh_end_io_t *end_io);
extern int ext4_read_bh(struct buffer_head *bh, int op_flags, extern int ext4_read_bh(struct buffer_head *bh, int op_flags,
......
...@@ -211,18 +211,19 @@ int ext4_read_bh_lock(struct buffer_head *bh, int op_flags, bool wait) ...@@ -211,18 +211,19 @@ int ext4_read_bh_lock(struct buffer_head *bh, int op_flags, bool wait)
} }
/* /*
* This works like sb_bread() except it uses ERR_PTR for error * This works like __bread_gfp() except it uses ERR_PTR for error
* returns. Currently with sb_bread it's impossible to distinguish * returns. Currently with sb_bread it's impossible to distinguish
* between ENOMEM and EIO situations (since both result in a NULL * between ENOMEM and EIO situations (since both result in a NULL
* return. * return.
*/ */
struct buffer_head * static struct buffer_head *__ext4_sb_bread_gfp(struct super_block *sb,
ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags) sector_t block, int op_flags,
gfp_t gfp)
{ {
struct buffer_head *bh; struct buffer_head *bh;
int ret; int ret;
bh = sb_getblk(sb, block); bh = sb_getblk_gfp(sb, block, gfp);
if (bh == NULL) if (bh == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (ext4_buffer_uptodate(bh)) if (ext4_buffer_uptodate(bh))
...@@ -236,6 +237,18 @@ ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags) ...@@ -236,6 +237,18 @@ ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags)
return bh; return bh;
} }
struct buffer_head *ext4_sb_bread(struct super_block *sb, sector_t block,
int op_flags)
{
return __ext4_sb_bread_gfp(sb, block, op_flags, __GFP_MOVABLE);
}
struct buffer_head *ext4_sb_bread_unmovable(struct super_block *sb,
sector_t block)
{
return __ext4_sb_bread_gfp(sb, block, 0, 0);
}
void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block) void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block)
{ {
struct buffer_head *bh = sb_getblk_gfp(sb, block, 0); struct buffer_head *bh = sb_getblk_gfp(sb, block, 0);
...@@ -3811,8 +3824,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -3811,8 +3824,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
logical_sb_block = sb_block; logical_sb_block = sb_block;
} }
if (!(bh = sb_bread_unmovable(sb, logical_sb_block))) { bh = ext4_sb_bread_unmovable(sb, logical_sb_block);
if (IS_ERR(bh)) {
ext4_msg(sb, KERN_ERR, "unable to read superblock"); ext4_msg(sb, KERN_ERR, "unable to read superblock");
ret = PTR_ERR(bh);
bh = NULL;
goto out_fail; goto out_fail;
} }
/* /*
...@@ -4166,10 +4182,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4166,10 +4182,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
brelse(bh); brelse(bh);
logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
offset = do_div(logical_sb_block, blocksize); offset = do_div(logical_sb_block, blocksize);
bh = sb_bread_unmovable(sb, logical_sb_block); bh = ext4_sb_bread_unmovable(sb, logical_sb_block);
if (!bh) { if (IS_ERR(bh)) {
ext4_msg(sb, KERN_ERR, ext4_msg(sb, KERN_ERR,
"Can't read superblock on 2nd try"); "Can't read superblock on 2nd try");
ret = PTR_ERR(bh);
bh = NULL;
goto failed_mount; goto failed_mount;
} }
es = (struct ext4_super_block *)(bh->b_data + offset); es = (struct ext4_super_block *)(bh->b_data + offset);
...@@ -4391,11 +4409,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) ...@@ -4391,11 +4409,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
struct buffer_head *bh; struct buffer_head *bh;
block = descriptor_loc(sb, logical_sb_block, i); block = descriptor_loc(sb, logical_sb_block, i);
bh = sb_bread_unmovable(sb, block); bh = ext4_sb_bread_unmovable(sb, block);
if (!bh) { if (IS_ERR(bh)) {
ext4_msg(sb, KERN_ERR, ext4_msg(sb, KERN_ERR,
"can't read group descriptor %d", i); "can't read group descriptor %d", i);
db_count = i; db_count = i;
ret = PTR_ERR(bh);
bh = NULL;
goto failed_mount2; goto failed_mount2;
} }
rcu_read_lock(); rcu_read_lock();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册