btrfs: tweak extent/chunk allocation for space_info sub-space

Make the extent allocator and the chunk allocator aware of the sub-space.
It now uses BTRFS_SUB_GROUP_DATA_RELOC sub-space for data relocation block
group, and uses BTRFS_SUB_GROUP_TREELOG for metadata tree-log block group.

And, it needs to check the space_info is the right one when a block group
candidate is given. Also, new block group should now belong to the
specified one.

Now that, block_group->space_info is always set before
btrfs_add_bg_to_space_info(), we no longer need to "find" the space_info.
So, rename the variable name to address that as well.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Naohiro Aota
2025-04-23 11:43:50 +09:00
committed by David Sterba
parent 9a3023b828
commit cc0517fe77
3 changed files with 31 additions and 18 deletions

View File

@@ -2371,6 +2371,7 @@ static int read_one_block_group(struct btrfs_fs_info *info,
cache->commit_used = cache->used;
cache->flags = btrfs_stack_block_group_flags(bgi);
cache->global_root_id = btrfs_stack_block_group_chunk_objectid(bgi);
cache->space_info = btrfs_find_space_info(info, cache->flags);
set_free_space_tree_thresholds(cache);
@@ -2449,6 +2450,7 @@ static int read_one_block_group(struct btrfs_fs_info *info,
btrfs_remove_free_space_cache(cache);
goto error;
}
trace_btrfs_add_block_group(info, cache, 0);
btrfs_add_bg_to_space_info(info, cache);
@@ -2493,6 +2495,7 @@ static int fill_dummy_bgs(struct btrfs_fs_info *fs_info)
bg->cached = BTRFS_CACHE_FINISHED;
bg->used = map->chunk_len;
bg->flags = map->type;
bg->space_info = btrfs_find_space_info(fs_info, bg->flags);
ret = btrfs_add_block_group_cache(bg);
/*
* We may have some valid block group cache added already, in

View File

@@ -4405,8 +4405,19 @@ static noinline int find_free_extent(struct btrfs_root *root,
trace_btrfs_find_free_extent(root, ffe_ctl);
space_info = btrfs_find_space_info(fs_info, ffe_ctl->flags);
if (btrfs_is_zoned(fs_info) && space_info) {
/* Use dedicated sub-space_info for dedicated block group users. */
if (ffe_ctl->for_data_reloc) {
space_info = space_info->sub_group[0];
ASSERT(space_info->subgroup_id == BTRFS_SUB_GROUP_DATA_RELOC);
} else if (ffe_ctl->for_treelog) {
space_info = space_info->sub_group[0];
ASSERT(space_info->subgroup_id == BTRFS_SUB_GROUP_TREELOG);
}
}
if (!space_info) {
btrfs_err(fs_info, "No space info for %llu", ffe_ctl->flags);
btrfs_err(fs_info, "no space info for %llu, tree-log %d, relocation %d",
ffe_ctl->flags, ffe_ctl->for_treelog, ffe_ctl->for_data_reloc);
return -ENOSPC;
}
@@ -4428,6 +4439,7 @@ static noinline int find_free_extent(struct btrfs_root *root,
* picked out then we don't care that the block group is cached.
*/
if (block_group && block_group_bits(block_group, ffe_ctl->flags) &&
block_group->space_info == space_info &&
block_group->cached != BTRFS_CACHE_NO) {
down_read(&space_info->groups_sem);
if (list_empty(&block_group->list) ||

View File

@@ -359,31 +359,29 @@ out:
void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info,
struct btrfs_block_group *block_group)
{
struct btrfs_space_info *found;
struct btrfs_space_info *space_info = block_group->space_info;
int factor, index;
factor = btrfs_bg_type_to_factor(block_group->flags);
found = btrfs_find_space_info(info, block_group->flags);
ASSERT(found);
spin_lock(&found->lock);
found->total_bytes += block_group->length;
found->disk_total += block_group->length * factor;
found->bytes_used += block_group->used;
found->disk_used += block_group->used * factor;
found->bytes_readonly += block_group->bytes_super;
btrfs_space_info_update_bytes_zone_unusable(found, block_group->zone_unusable);
spin_lock(&space_info->lock);
space_info->total_bytes += block_group->length;
space_info->disk_total += block_group->length * factor;
space_info->bytes_used += block_group->used;
space_info->disk_used += block_group->used * factor;
space_info->bytes_readonly += block_group->bytes_super;
btrfs_space_info_update_bytes_zone_unusable(space_info, block_group->zone_unusable);
if (block_group->length > 0)
found->full = 0;
btrfs_try_granting_tickets(info, found);
spin_unlock(&found->lock);
space_info->full = 0;
btrfs_try_granting_tickets(info, space_info);
spin_unlock(&space_info->lock);
block_group->space_info = found;
block_group->space_info = space_info;
index = btrfs_bg_flags_to_raid_index(block_group->flags);
down_write(&found->groups_sem);
list_add_tail(&block_group->list, &found->block_groups[index]);
up_write(&found->groups_sem);
down_write(&space_info->groups_sem);
list_add_tail(&block_group->list, &space_info->block_groups[index]);
up_write(&space_info->groups_sem);
}
struct btrfs_space_info *btrfs_find_space_info(struct btrfs_fs_info *info,