Re: [PATCH v6 06/11] ext4: call ext4_mb_mark_context in ext4_mb_clear_bb

From: IBM
Date: Fri Sep 01 2023 - 05:38:09 EST


Kemeng Shi <shikemeng@xxxxxxxxxxxxxxx> writes:

> Call ext4_mb_mark_context in ext4_mb_clear_bb to remove repeat code.
>
> Signed-off-by: Kemeng Shi <shikemeng@xxxxxxxxxxxxxxx>
> ---
> fs/ext4/mballoc.c | 83 +++++++++++------------------------------------
> 1 file changed, 19 insertions(+), 64 deletions(-)
>
> diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
> index 01ad36a1cc96..25265531cb6a 100644
> --- a/fs/ext4/mballoc.c
> +++ b/fs/ext4/mballoc.c
> @@ -6424,21 +6424,20 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
> ext4_fsblk_t block, unsigned long count,
> int flags)
> {
> - struct buffer_head *bitmap_bh = NULL;
> + struct ext4_mark_context mc;
> struct super_block *sb = inode->i_sb;
> - struct ext4_group_desc *gdp;
> struct ext4_group_info *grp;
> unsigned int overflow;
> ext4_grpblk_t bit;
> - struct buffer_head *gd_bh;
> ext4_group_t block_group;
> struct ext4_sb_info *sbi;
> struct ext4_buddy e4b;
> unsigned int count_clusters;
> int err = 0;
> - int ret;
> + int mark_flags = 0;
>
> sbi = EXT4_SB(sb);
> + ext4_mb_prepare_mark_context(&mc, handle, sb, 0);
>
> if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
> !ext4_inode_block_valid(inode, block, count)) {
> @@ -6468,18 +6467,6 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
> /* The range changed so it's no longer validated */
> flags &= ~EXT4_FREE_BLOCKS_VALIDATED;
> }
> - count_clusters = EXT4_NUM_B2C(sbi, count);
> - bitmap_bh = ext4_read_block_bitmap(sb, block_group);
> - if (IS_ERR(bitmap_bh)) {
> - err = PTR_ERR(bitmap_bh);
> - bitmap_bh = NULL;
> - goto error_return;
> - }
> - gdp = ext4_get_group_desc(sb, block_group, &gd_bh);
> - if (!gdp) {
> - err = -EIO;
> - goto error_return;
> - }
>
> if (!(flags & EXT4_FREE_BLOCKS_VALIDATED) &&
> !ext4_inode_block_valid(inode, block, count)) {
> @@ -6489,28 +6476,7 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
> goto error_return;
> }
>
> - BUFFER_TRACE(bitmap_bh, "getting write access");
> - err = ext4_journal_get_write_access(handle, sb, bitmap_bh,
> - EXT4_JTR_NONE);
> - if (err)
> - goto error_return;
> -
> - /*
> - * We are about to modify some metadata. Call the journal APIs
> - * to unshare ->b_data if a currently-committing transaction is
> - * using it
> - */
> - BUFFER_TRACE(gd_bh, "get_write_access");
> - err = ext4_journal_get_write_access(handle, sb, gd_bh, EXT4_JTR_NONE);
> - if (err)
> - goto error_return;
> -#ifdef AGGRESSIVE_CHECK
> - {
> - int i;
> - for (i = 0; i < count_clusters; i++)
> - BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data));
> - }
> -#endif
> + count_clusters = EXT4_NUM_B2C(sbi, count);
> trace_ext4_mballoc_free(sb, inode, block_group, bit, count_clusters);
>
> /* __GFP_NOFAIL: retry infinitely, ignore TIF_MEMDIE and memcg limit. */
> @@ -6519,13 +6485,21 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
> if (err)
> goto error_return;
>
> - ext4_lock_group(sb, block_group);
> - mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
> - ret = ext4_free_group_clusters(sb, gdp) + count_clusters;
> - ext4_free_group_clusters_set(sb, gdp, ret);
> - ext4_block_bitmap_csum_set(sb, gdp, bitmap_bh);
> - ext4_group_desc_csum_set(sb, block_group, gdp);
> - ext4_unlock_group(sb, block_group);
> +#ifdef AGGRESSIVE_CHECK
> + mark_flags |= EXT4_MB_BITMAP_MARKED_CHECK;
> +#endif
> + err = ext4_mb_mark_context(&mc, block_group, bit, count_clusters,
> + mark_flags);
> +
> +
> + if (err && mc.changed == 0) {
> + ext4_mb_unload_buddy(&e4b);
> + goto error_return;
> + }
> +
> +#ifdef AGGRESSIVE_CHECK
> + BUG_ON(mc.changed != count_clusters);
> +#endif
>
> /*
> * We need to make sure we don't reuse the freed block until after the
> @@ -6568,13 +6542,6 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
>
> ext4_unlock_group(sb, block_group);
>
> - if (sbi->s_log_groups_per_flex) {
> - ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
> - atomic64_add(count_clusters,
> - &sbi_array_rcu_deref(sbi, s_flex_groups,
> - flex_group)->free_clusters);
> - }
> -
> /*
> * on a bigalloc file system, defer the s_freeclusters_counter
> * update to the caller (ext4_remove_space and friends) so they
> @@ -6589,26 +6556,14 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
>
> ext4_mb_unload_buddy(&e4b);
>
> - /* We dirtied the bitmap block */
> - BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
> - err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
> -
> - /* And the group descriptor block */
> - BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
> - ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
> - if (!err)
> - err = ret;
> -

As commented out in previous patch, it would be much simpler if we can
move all the required peices for bitmap freeing logic at one place.
So then this patch just becomes removing them all and using already
created ext4_mb_mark_context() function.

-ritesh