Extract the BLOCK_UNINIT initialization logic from ext4_mark_inode_used() and __ext4_new_inode() into a shared ext4_might_init_block_bitmap() helper. Both call sites perform the same sequence: check EXT4_BG_BLOCK_UNINIT, read the block bitmap, dirty it, then clear the flag and establish the correct block bitmap checksum under the group lock. The only difference is whether a journal handle is available (NULL during fast commit replay in ext4_mark_inode_used()). No functional change. Signed-off-by: Baokun Li --- fs/ext4/ialloc.c | 129 +++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 71 deletions(-) diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 5896cdfb2ccf..90896b7f8c73 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -756,6 +756,58 @@ static int find_inode_bit(struct super_block *sb, ext4_group_t group, return 1; } +/* + * If the block bitmap for @group is not yet initialized (EXT4_BG_BLOCK_UNINIT), + * read it into memory, dirty it, and clear the UNINIT flag under the group lock + * so that the on-disk checksum is established. @handle may be NULL during fast + * commit replay (no journal credits needed in that path). + */ +static int ext4_might_init_block_bitmap(handle_t *handle, + struct super_block *sb, + ext4_group_t group, + struct ext4_group_desc *gdp) +{ + int err; + struct buffer_head *block_bitmap_bh; + + if (!ext4_has_group_desc_csum(sb) || + !(gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) + return 0; + + block_bitmap_bh = ext4_read_block_bitmap(sb, group); + if (IS_ERR(block_bitmap_bh)) + return PTR_ERR(block_bitmap_bh); + + if (handle) { + BUFFER_TRACE(block_bitmap_bh, "get block bitmap access"); + err = ext4_journal_get_write_access(handle, sb, + block_bitmap_bh, EXT4_JTR_NONE); + if (err) + goto out_brelse; + } + + BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap"); + err = ext4_handle_dirty_metadata(handle, NULL, block_bitmap_bh); + if (!handle) + sync_dirty_buffer(block_bitmap_bh); + + /* recheck and clear flag under lock if we still need to */ + ext4_lock_group(sb, group); + if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { + gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); + ext4_free_group_clusters_set(sb, gdp, + ext4_free_clusters_after_init(sb, group, gdp)); + ext4_block_bitmap_csum_set(sb, gdp, block_bitmap_bh); + ext4_group_desc_csum_set(sb, group, gdp); + } + ext4_unlock_group(sb, group); + +out_brelse: + brelse(block_bitmap_bh); + ext4_std_error(sb, err); + return err; +} + int ext4_mark_inode_used(struct super_block *sb, int ino, umode_t mode) { unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count); @@ -801,38 +853,9 @@ int ext4_mark_inode_used(struct super_block *sb, int ino, umode_t mode) } /* We may have to initialize the block bitmap if it isn't already */ - if (ext4_has_group_desc_csum(sb) && - gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { - struct buffer_head *block_bitmap_bh; - - block_bitmap_bh = ext4_read_block_bitmap(sb, group); - if (IS_ERR(block_bitmap_bh)) { - err = PTR_ERR(block_bitmap_bh); - goto out; - } - - BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap"); - err = ext4_handle_dirty_metadata(NULL, NULL, block_bitmap_bh); - sync_dirty_buffer(block_bitmap_bh); - - /* recheck and clear flag under lock if we still need to */ - ext4_lock_group(sb, group); - if (ext4_has_group_desc_csum(sb) && - (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { - gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); - ext4_free_group_clusters_set(sb, gdp, - ext4_free_clusters_after_init(sb, group, gdp)); - ext4_block_bitmap_csum_set(sb, gdp, block_bitmap_bh); - ext4_group_desc_csum_set(sb, group, gdp); - } - ext4_unlock_group(sb, group); - brelse(block_bitmap_bh); - - if (err) { - ext4_std_error(sb, err); - goto out; - } - } + err = ext4_might_init_block_bitmap(NULL, sb, group, gdp); + if (err) + goto out; /* Update the relevant bg descriptor fields */ if (ext4_has_group_desc_csum(sb)) { @@ -1154,45 +1177,9 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap, } /* We may have to initialize the block bitmap if it isn't already */ - if (ext4_has_group_desc_csum(sb) && - gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { - struct buffer_head *block_bitmap_bh; - - block_bitmap_bh = ext4_read_block_bitmap(sb, group); - if (IS_ERR(block_bitmap_bh)) { - err = PTR_ERR(block_bitmap_bh); - goto out; - } - BUFFER_TRACE(block_bitmap_bh, "get block bitmap access"); - err = ext4_journal_get_write_access(handle, sb, block_bitmap_bh, - EXT4_JTR_NONE); - if (err) { - brelse(block_bitmap_bh); - ext4_std_error(sb, err); - goto out; - } - - BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap"); - err = ext4_handle_dirty_metadata(handle, NULL, block_bitmap_bh); - - /* recheck and clear flag under lock if we still need to */ - ext4_lock_group(sb, group); - if (ext4_has_group_desc_csum(sb) && - (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { - gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); - ext4_free_group_clusters_set(sb, gdp, - ext4_free_clusters_after_init(sb, group, gdp)); - ext4_block_bitmap_csum_set(sb, gdp, block_bitmap_bh); - ext4_group_desc_csum_set(sb, group, gdp); - } - ext4_unlock_group(sb, group); - brelse(block_bitmap_bh); - - if (err) { - ext4_std_error(sb, err); - goto out; - } - } + err = ext4_might_init_block_bitmap(handle, sb, group, gdp); + if (err) + goto out; /* Update the relevant bg descriptor fields */ if (ext4_has_group_desc_csum(sb)) { -- 2.43.7