Skip to content

Commit c431d38

Browse files
Kemeng Shitytso
authored andcommitted
ext4: extend ext4_mb_mark_context to support allocation under journal
Previously, ext4_mb_mark_context is only called under fast commit replay path, so there is no valid handle when we update block bitmap and group descriptor. This patch try to extend ext4_mb_mark_context to be used by code under journal. There are several improvement: 1. Add "handle_t *handle" to struct ext4_mark_context to journal block bitmap and group descriptor update inside ext4_mb_mark_context (the added journal code is based on ext4_mb_mark_diskspace_used where ext4_mb_mark_context is going to be used.) 2. Adds a flag argument to ext4_mb_mark_context() which controls a. EXT4_MB_BITMAP_MARKED_CHECK - whether block bitmap checking is needed. b. EXT4_MB_SYNC_UPDATE - whether dirty buffers (bitmap and group descriptor) needs sync. 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 26d0f87 commit c431d38

File tree

1 file changed

+49
-15
lines changed

1 file changed

+49
-15
lines changed

fs/ext4/mballoc.c

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3943,26 +3943,47 @@ void ext4_exit_mballoc(void)
39433943
ext4_groupinfo_destroy_slabs();
39443944
}
39453945

3946+
#define EXT4_MB_BITMAP_MARKED_CHECK 0x0001
3947+
#define EXT4_MB_SYNC_UPDATE 0x0002
39463948
static int
3947-
ext4_mb_mark_context(struct super_block *sb, bool state, ext4_group_t group,
3948-
ext4_grpblk_t blkoff, ext4_grpblk_t len)
3949+
ext4_mb_mark_context(handle_t *handle, struct super_block *sb, bool state,
3950+
ext4_group_t group, ext4_grpblk_t blkoff,
3951+
ext4_grpblk_t len, int flags, ext4_grpblk_t *ret_changed)
39493952
{
39503953
struct ext4_sb_info *sbi = EXT4_SB(sb);
39513954
struct buffer_head *bitmap_bh = NULL;
39523955
struct ext4_group_desc *gdp;
39533956
struct buffer_head *gdp_bh;
39543957
int err;
3955-
unsigned int i, already, changed;
3958+
unsigned int i, already, changed = len;
39563959

3960+
if (ret_changed)
3961+
*ret_changed = 0;
39573962
bitmap_bh = ext4_read_block_bitmap(sb, group);
39583963
if (IS_ERR(bitmap_bh))
39593964
return PTR_ERR(bitmap_bh);
39603965

3966+
if (handle) {
3967+
BUFFER_TRACE(bitmap_bh, "getting write access");
3968+
err = ext4_journal_get_write_access(handle, sb, bitmap_bh,
3969+
EXT4_JTR_NONE);
3970+
if (err)
3971+
goto out_err;
3972+
}
3973+
39613974
err = -EIO;
39623975
gdp = ext4_get_group_desc(sb, group, &gdp_bh);
39633976
if (!gdp)
39643977
goto out_err;
39653978

3979+
if (handle) {
3980+
BUFFER_TRACE(gdp_bh, "get_write_access");
3981+
err = ext4_journal_get_write_access(handle, sb, gdp_bh,
3982+
EXT4_JTR_NONE);
3983+
if (err)
3984+
goto out_err;
3985+
}
3986+
39663987
ext4_lock_group(sb, group);
39673988
if (ext4_has_group_desc_csum(sb) &&
39683989
(gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
@@ -3971,12 +3992,14 @@ ext4_mb_mark_context(struct super_block *sb, bool state, ext4_group_t group,
39713992
ext4_free_clusters_after_init(sb, group, gdp));
39723993
}
39733994

3974-
already = 0;
3975-
for (i = 0; i < len; i++)
3976-
if (mb_test_bit(blkoff + i, bitmap_bh->b_data) ==
3977-
state)
3978-
already++;
3979-
changed = len - already;
3995+
if (flags & EXT4_MB_BITMAP_MARKED_CHECK) {
3996+
already = 0;
3997+
for (i = 0; i < len; i++)
3998+
if (mb_test_bit(blkoff + i, bitmap_bh->b_data) ==
3999+
state)
4000+
already++;
4001+
changed = len - already;
4002+
}
39804003

39814004
if (state) {
39824005
mb_set_bits(bitmap_bh->b_data, blkoff, len);
@@ -3991,6 +4014,8 @@ ext4_mb_mark_context(struct super_block *sb, bool state, ext4_group_t group,
39914014
ext4_block_bitmap_csum_set(sb, gdp, bitmap_bh);
39924015
ext4_group_desc_csum_set(sb, group, gdp);
39934016
ext4_unlock_group(sb, group);
4017+
if (ret_changed)
4018+
*ret_changed = changed;
39944019

39954020
if (sbi->s_log_groups_per_flex) {
39964021
ext4_group_t flex_group = ext4_flex_group(sbi, group);
@@ -4003,15 +4028,17 @@ ext4_mb_mark_context(struct super_block *sb, bool state, ext4_group_t group,
40034028
atomic64_add(changed, &fg->free_clusters);
40044029
}
40054030

4006-
err = ext4_handle_dirty_metadata(NULL, NULL, bitmap_bh);
4031+
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
40074032
if (err)
40084033
goto out_err;
4009-
err = ext4_handle_dirty_metadata(NULL, NULL, gdp_bh);
4034+
err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh);
40104035
if (err)
40114036
goto out_err;
40124037

4013-
sync_dirty_buffer(bitmap_bh);
4014-
sync_dirty_buffer(gdp_bh);
4038+
if (flags & EXT4_MB_SYNC_UPDATE) {
4039+
sync_dirty_buffer(bitmap_bh);
4040+
sync_dirty_buffer(gdp_bh);
4041+
}
40154042

40164043
out_err:
40174044
brelse(bitmap_bh);
@@ -4171,7 +4198,11 @@ void ext4_mb_mark_bb(struct super_block *sb, ext4_fsblk_t block,
41714198
break;
41724199
}
41734200

4174-
err = ext4_mb_mark_context(sb, state, group, blkoff, clen);
4201+
err = ext4_mb_mark_context(NULL, sb, state,
4202+
group, blkoff, clen,
4203+
EXT4_MB_BITMAP_MARKED_CHECK |
4204+
EXT4_MB_SYNC_UPDATE,
4205+
NULL);
41754206
if (err)
41764207
break;
41774208

@@ -6363,7 +6394,10 @@ static void ext4_free_blocks_simple(struct inode *inode, ext4_fsblk_t block,
63636394
ext4_grpblk_t blkoff;
63646395

63656396
ext4_get_group_no_and_offset(sb, block, &group, &blkoff);
6366-
ext4_mb_mark_context(sb, false, group, blkoff, count);
6397+
ext4_mb_mark_context(NULL, sb, false, group, blkoff, count,
6398+
EXT4_MB_BITMAP_MARKED_CHECK |
6399+
EXT4_MB_SYNC_UPDATE,
6400+
NULL);
63676401
}
63686402

63696403
/**

0 commit comments

Comments
 (0)