| From 31a074a0c62dc0d2bfb9b543142db4fe27f9e5eb Mon Sep 17 00:00:00 2001 |
| From: Xin Yin <yinxin.x@bytedance.com> |
| Date: Mon, 10 Jan 2022 11:51:41 +0800 |
| Subject: ext4: modify the logic of ext4_mb_new_blocks_simple |
| |
| From: Xin Yin <yinxin.x@bytedance.com> |
| |
| commit 31a074a0c62dc0d2bfb9b543142db4fe27f9e5eb upstream. |
| |
| For now in ext4_mb_new_blocks_simple, if we found a block which |
| should be excluded then will switch to next group, this may |
| probably cause 'group' run out of range. |
| |
| Change to check next block in the same group when get a block should |
| be excluded. Also change the search range to EXT4_CLUSTERS_PER_GROUP |
| and add error checking. |
| |
| Signed-off-by: Xin Yin <yinxin.x@bytedance.com> |
| Reviewed-by: Harshad Shirwadkar <harshadshirwadkar@gmail.com> |
| Link: https://lore.kernel.org/r/20220110035141.1980-3-yinxin.x@bytedance.com |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Cc: stable@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/ext4/mballoc.c | 26 +++++++++++++++++--------- |
| 1 file changed, 17 insertions(+), 9 deletions(-) |
| |
| --- a/fs/ext4/mballoc.c |
| +++ b/fs/ext4/mballoc.c |
| @@ -5173,7 +5173,8 @@ static ext4_fsblk_t ext4_mb_new_blocks_s |
| struct super_block *sb = ar->inode->i_sb; |
| ext4_group_t group; |
| ext4_grpblk_t blkoff; |
| - int i = sb->s_blocksize; |
| + ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb); |
| + ext4_grpblk_t i = 0; |
| ext4_fsblk_t goal, block; |
| struct ext4_super_block *es = EXT4_SB(sb)->s_es; |
| |
| @@ -5195,19 +5196,26 @@ static ext4_fsblk_t ext4_mb_new_blocks_s |
| ext4_get_group_no_and_offset(sb, |
| max(ext4_group_first_block_no(sb, group), goal), |
| NULL, &blkoff); |
| - i = mb_find_next_zero_bit(bitmap_bh->b_data, sb->s_blocksize, |
| + while (1) { |
| + i = mb_find_next_zero_bit(bitmap_bh->b_data, max, |
| blkoff); |
| + if (i >= max) |
| + break; |
| + if (ext4_fc_replay_check_excluded(sb, |
| + ext4_group_first_block_no(sb, group) + i)) { |
| + blkoff = i + 1; |
| + } else |
| + break; |
| + } |
| brelse(bitmap_bh); |
| - if (i >= sb->s_blocksize) |
| - continue; |
| - if (ext4_fc_replay_check_excluded(sb, |
| - ext4_group_first_block_no(sb, group) + i)) |
| - continue; |
| - break; |
| + if (i < max) |
| + break; |
| } |
| |
| - if (group >= ext4_get_groups_count(sb) && i >= sb->s_blocksize) |
| + if (group >= ext4_get_groups_count(sb) || i >= max) { |
| + *errp = -ENOSPC; |
| return 0; |
| + } |
| |
| block = ext4_group_first_block_no(sb, group) + i; |
| ext4_mb_mark_bb(sb, block, 1, 1); |