Skip to content

Commit 760e69c

Browse files
naotakdave
authored andcommitted
btrfs: zoned: activate block group only for extent allocation
In btrfs_make_block_group(), we activate the allocated block group, expecting that the block group is soon used for allocation. However, the chunk allocation from flush_space() context broke the assumption. There can be a large time gap between the chunk allocation time and the extent allocation time from the chunk. Activating the empty block groups pre-allocated from flush_space() context can exhaust the active zone counter of a device. Once we use all the active zone counts for empty pre-allocated block groups, we cannot activate new block group for the other things: metadata, tree-log, or data relocation block group. That failure results in a fake -ENOSPC. This patch introduces CHUNK_ALLOC_FORCE_FOR_EXTENT to distinguish the chunk allocation from find_free_extent(). Now, the new block group is activated only in that context. Fixes: eb66a01 ("btrfs: zoned: activate new block group") CC: stable@vger.kernel.org # 5.16+ Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Tested-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 820c363 commit 760e69c

3 files changed

Lines changed: 21 additions & 9 deletions

File tree

fs/btrfs/block-group.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2503,12 +2503,6 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran
25032503
return ERR_PTR(ret);
25042504
}
25052505

2506-
/*
2507-
* New block group is likely to be used soon. Try to activate it now.
2508-
* Failure is OK for now.
2509-
*/
2510-
btrfs_zone_activate(cache);
2511-
25122506
ret = exclude_super_stripes(cache);
25132507
if (ret) {
25142508
/* We may have excluded something, so call this just in case */
@@ -3660,8 +3654,14 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
36603654
struct btrfs_block_group *ret_bg;
36613655
bool wait_for_alloc = false;
36623656
bool should_alloc = false;
3657+
bool from_extent_allocation = false;
36633658
int ret = 0;
36643659

3660+
if (force == CHUNK_ALLOC_FORCE_FOR_EXTENT) {
3661+
from_extent_allocation = true;
3662+
force = CHUNK_ALLOC_FORCE;
3663+
}
3664+
36653665
/* Don't re-enter if we're already allocating a chunk */
36663666
if (trans->allocating_chunk)
36673667
return -ENOSPC;
@@ -3754,9 +3754,17 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
37543754
ret_bg = do_chunk_alloc(trans, flags);
37553755
trans->allocating_chunk = false;
37563756

3757-
if (IS_ERR(ret_bg))
3757+
if (IS_ERR(ret_bg)) {
37583758
ret = PTR_ERR(ret_bg);
3759-
else
3759+
} else if (from_extent_allocation) {
3760+
/*
3761+
* New block group is likely to be used soon. Try to activate
3762+
* it now. Failure is OK for now.
3763+
*/
3764+
btrfs_zone_activate(ret_bg);
3765+
}
3766+
3767+
if (!ret)
37603768
btrfs_put_block_group(ret_bg);
37613769

37623770
spin_lock(&space_info->lock);

fs/btrfs/block-group.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,15 @@ enum btrfs_discard_state {
3535
* the FS with empty chunks
3636
*
3737
* CHUNK_ALLOC_FORCE means it must try to allocate one
38+
*
39+
* CHUNK_ALLOC_FORCE_FOR_EXTENT like CHUNK_ALLOC_FORCE but called from
40+
* find_free_extent() that also activaes the zone
3841
*/
3942
enum btrfs_chunk_alloc_enum {
4043
CHUNK_ALLOC_NO_FORCE,
4144
CHUNK_ALLOC_LIMITED,
4245
CHUNK_ALLOC_FORCE,
46+
CHUNK_ALLOC_FORCE_FOR_EXTENT,
4347
};
4448

4549
struct btrfs_caching_control {

fs/btrfs/extent-tree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4082,7 +4082,7 @@ static int find_free_extent_update_loop(struct btrfs_fs_info *fs_info,
40824082
}
40834083

40844084
ret = btrfs_chunk_alloc(trans, ffe_ctl->flags,
4085-
CHUNK_ALLOC_FORCE);
4085+
CHUNK_ALLOC_FORCE_FOR_EXTENT);
40864086

40874087
/* Do not bail out on ENOSPC since we can do more. */
40884088
if (ret == -ENOSPC)

0 commit comments

Comments
 (0)