Skip to content

Commit 1ada69f

Browse files
naotakdave
authored andcommitted
btrfs: zoned: unset dedicated block group on allocation failure
Allocating an extent from a block group can fail for various reasons. When an allocation from a dedicated block group (for tree-log or relocation data) fails, we need to unregister it as a dedicated one so that we can allocate a new block group for the dedicated one. However, we are returning early when the block group in case it is read-only, fully used, or not be able to activate the zone. As a result, we keep the non-usable block group as a dedicated one, leading to further allocation failure. With many block groups, the allocator will iterate hopeless loop to find a free extent, results in a hung task. Fix the issue by delaying the return and doing the proper cleanups. CC: [email protected] # 5.16 Signed-off-by: Naohiro Aota <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 7367271 commit 1ada69f

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

fs/btrfs/extent-tree.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3805,23 +3805,35 @@ static int do_allocation_zoned(struct btrfs_block_group *block_group,
38053805
spin_unlock(&fs_info->relocation_bg_lock);
38063806
if (skip)
38073807
return 1;
3808+
38083809
/* Check RO and no space case before trying to activate it */
38093810
spin_lock(&block_group->lock);
38103811
if (block_group->ro ||
38113812
block_group->alloc_offset == block_group->zone_capacity) {
3812-
spin_unlock(&block_group->lock);
3813-
return 1;
3813+
ret = 1;
3814+
/*
3815+
* May need to clear fs_info->{treelog,data_reloc}_bg.
3816+
* Return the error after taking the locks.
3817+
*/
38143818
}
38153819
spin_unlock(&block_group->lock);
38163820

3817-
if (!btrfs_zone_activate(block_group))
3818-
return 1;
3821+
if (!ret && !btrfs_zone_activate(block_group)) {
3822+
ret = 1;
3823+
/*
3824+
* May need to clear fs_info->{treelog,data_reloc}_bg.
3825+
* Return the error after taking the locks.
3826+
*/
3827+
}
38193828

38203829
spin_lock(&space_info->lock);
38213830
spin_lock(&block_group->lock);
38223831
spin_lock(&fs_info->treelog_bg_lock);
38233832
spin_lock(&fs_info->relocation_bg_lock);
38243833

3834+
if (ret)
3835+
goto out;
3836+
38253837
ASSERT(!ffe_ctl->for_treelog ||
38263838
block_group->start == fs_info->treelog_bg ||
38273839
fs_info->treelog_bg == 0);

0 commit comments

Comments
 (0)