Skip to content

Commit 2f94711

Browse files
Kemeng Shitytso
authored andcommitted
ext4: call ext4_mb_mark_context in ext4_mb_mark_diskspace_used
Call ext4_mb_mark_context in ext4_mb_mark_diskspace_used to: 1. Remove repeat code to normally update bitmap and group descriptor on disk. 2. Now that we have a common API for marking blocks inuse/free in block bitmap, use that instead of open coding it in function ext4_mb_mark_diskspace_used(). The current code was not updating checksum and other counters. ext4_mb_mark_context() should fix these consistency problems. Signed-off-by: Kemeng Shi <[email protected]> Reviewed-by: "Ritesh Harjani (IBM)" <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent c431d38 commit 2f94711

File tree

1 file changed

+20
-66
lines changed

1 file changed

+20
-66
lines changed

fs/ext4/mballoc.c

Lines changed: 20 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4053,46 +4053,27 @@ static noinline_for_stack int
40534053
ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
40544054
handle_t *handle, unsigned int reserv_clstrs)
40554055
{
4056-
struct buffer_head *bitmap_bh = NULL;
40574056
struct ext4_group_desc *gdp;
4058-
struct buffer_head *gdp_bh;
40594057
struct ext4_sb_info *sbi;
40604058
struct super_block *sb;
40614059
ext4_fsblk_t block;
40624060
int err, len;
4061+
int flags = 0;
4062+
ext4_grpblk_t changed;
40634063

40644064
BUG_ON(ac->ac_status != AC_STATUS_FOUND);
40654065
BUG_ON(ac->ac_b_ex.fe_len <= 0);
40664066

40674067
sb = ac->ac_sb;
40684068
sbi = EXT4_SB(sb);
40694069

4070-
bitmap_bh = ext4_read_block_bitmap(sb, ac->ac_b_ex.fe_group);
4071-
if (IS_ERR(bitmap_bh)) {
4072-
return PTR_ERR(bitmap_bh);
4073-
}
4074-
4075-
BUFFER_TRACE(bitmap_bh, "getting write access");
4076-
err = ext4_journal_get_write_access(handle, sb, bitmap_bh,
4077-
EXT4_JTR_NONE);
4078-
if (err)
4079-
goto out_err;
4080-
4081-
err = -EIO;
4082-
gdp = ext4_get_group_desc(sb, ac->ac_b_ex.fe_group, &gdp_bh);
4070+
gdp = ext4_get_group_desc(sb, ac->ac_b_ex.fe_group, NULL);
40834071
if (!gdp)
4084-
goto out_err;
4085-
4072+
return -EIO;
40864073
ext4_debug("using block group %u(%d)\n", ac->ac_b_ex.fe_group,
40874074
ext4_free_group_clusters(sb, gdp));
40884075

4089-
BUFFER_TRACE(gdp_bh, "get_write_access");
4090-
err = ext4_journal_get_write_access(handle, sb, gdp_bh, EXT4_JTR_NONE);
4091-
if (err)
4092-
goto out_err;
4093-
40944076
block = ext4_grp_offs_to_block(sb, &ac->ac_b_ex);
4095-
40964077
len = EXT4_C2B(sbi, ac->ac_b_ex.fe_len);
40974078
if (!ext4_inode_block_valid(ac->ac_inode, block, len)) {
40984079
ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
@@ -4101,41 +4082,29 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
41014082
* Fix the bitmap and return EFSCORRUPTED
41024083
* We leak some of the blocks here.
41034084
*/
4104-
ext4_lock_group(sb, ac->ac_b_ex.fe_group);
4105-
mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,
4106-
ac->ac_b_ex.fe_len);
4107-
ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
4108-
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
4085+
err = ext4_mb_mark_context(handle, sb, true,
4086+
ac->ac_b_ex.fe_group,
4087+
ac->ac_b_ex.fe_start,
4088+
ac->ac_b_ex.fe_len,
4089+
0, NULL);
41094090
if (!err)
41104091
err = -EFSCORRUPTED;
4111-
goto out_err;
4092+
return err;
41124093
}
41134094

4114-
ext4_lock_group(sb, ac->ac_b_ex.fe_group);
41154095
#ifdef AGGRESSIVE_CHECK
4116-
{
4117-
int i;
4118-
for (i = 0; i < ac->ac_b_ex.fe_len; i++) {
4119-
BUG_ON(mb_test_bit(ac->ac_b_ex.fe_start + i,
4120-
bitmap_bh->b_data));
4121-
}
4122-
}
4096+
flags |= EXT4_MB_BITMAP_MARKED_CHECK;
41234097
#endif
4124-
mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,
4125-
ac->ac_b_ex.fe_len);
4126-
if (ext4_has_group_desc_csum(sb) &&
4127-
(gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
4128-
gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
4129-
ext4_free_group_clusters_set(sb, gdp,
4130-
ext4_free_clusters_after_init(sb,
4131-
ac->ac_b_ex.fe_group, gdp));
4132-
}
4133-
len = ext4_free_group_clusters(sb, gdp) - ac->ac_b_ex.fe_len;
4134-
ext4_free_group_clusters_set(sb, gdp, len);
4135-
ext4_block_bitmap_csum_set(sb, gdp, bitmap_bh);
4136-
ext4_group_desc_csum_set(sb, ac->ac_b_ex.fe_group, gdp);
4098+
err = ext4_mb_mark_context(handle, sb, true, ac->ac_b_ex.fe_group,
4099+
ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len,
4100+
flags, &changed);
4101+
4102+
if (err && changed == 0)
4103+
return err;
41374104

4138-
ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
4105+
#ifdef AGGRESSIVE_CHECK
4106+
BUG_ON(changed != ac->ac_b_ex.fe_len);
4107+
#endif
41394108
percpu_counter_sub(&sbi->s_freeclusters_counter, ac->ac_b_ex.fe_len);
41404109
/*
41414110
* Now reduce the dirty block count also. Should not go negative
@@ -4145,21 +4114,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
41454114
percpu_counter_sub(&sbi->s_dirtyclusters_counter,
41464115
reserv_clstrs);
41474116

4148-
if (sbi->s_log_groups_per_flex) {
4149-
ext4_group_t flex_group = ext4_flex_group(sbi,
4150-
ac->ac_b_ex.fe_group);
4151-
atomic64_sub(ac->ac_b_ex.fe_len,
4152-
&sbi_array_rcu_deref(sbi, s_flex_groups,
4153-
flex_group)->free_clusters);
4154-
}
4155-
4156-
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
4157-
if (err)
4158-
goto out_err;
4159-
err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh);
4160-
4161-
out_err:
4162-
brelse(bitmap_bh);
41634117
return err;
41644118
}
41654119

0 commit comments

Comments
 (0)