btrfs: remove remapped block groups from the free-space-tree

No new allocations can be done from block groups that have the REMAPPED
flag set, so there's no value in their having entries in the free-space
tree.

Prevent a search through the free-space tree being scheduled for such a
block group, and prevent any additions to the in-memory free-space tree.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Mark Harmstone <mark@harmstone.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Mark Harmstone 2026-01-07 14:09:04 +00:00 committed by David Sterba
parent c3d6dda60c
commit 76377db18a
2 changed files with 19 additions and 3 deletions

View File

@ -933,6 +933,13 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait)
if (btrfs_is_zoned(fs_info))
return 0;
/*
* No allocations can be done from remapped block groups, so they have
* no entries in the free-space tree.
*/
if (cache->flags & BTRFS_BLOCK_GROUP_REMAPPED)
return 0;
caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS);
if (!caching_ctl)
return -ENOMEM;
@ -1246,10 +1253,16 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
* deletes the block group item from the extent tree, allowing for
* another task to attempt to create another block group with the same
* item key (and failing with -EEXIST and a transaction abort).
*
* If the REMAPPED flag has been set the block group's free space
* has already been removed, so we can skip the call to
* btrfs_remove_block_group_free_space().
*/
ret = btrfs_remove_block_group_free_space(trans, block_group);
if (ret)
goto out;
if (!(block_group->flags & BTRFS_BLOCK_GROUP_REMAPPED)) {
ret = btrfs_remove_block_group_free_space(trans, block_group);
if (ret)
goto out;
}
ret = remove_block_group_item(trans, path, block_group);
if (ret < 0)

View File

@ -2756,6 +2756,9 @@ int btrfs_add_free_space(struct btrfs_block_group *block_group,
{
enum btrfs_trim_state trim_state = BTRFS_TRIM_STATE_UNTRIMMED;
if (block_group->flags & BTRFS_BLOCK_GROUP_REMAPPED)
return 0;
if (btrfs_is_zoned(block_group->fs_info))
return __btrfs_add_free_space_zoned(block_group, bytenr, size,
true);