Skip to content

Commit fa2068d

Browse files
naotakdave
authored andcommitted
btrfs: zoned: count fresh BG region as zone unusable
The naming of space_info->active_total_bytes is misleading. It counts not only active block groups but also full ones which are previously active but now inactive. That confusion results in a bug not counting the full BGs into active_total_bytes on mount time. For a background, there are three kinds of block groups in terms of activation. 1. Block groups never activated 2. Block groups currently active 3. Block groups previously active and currently inactive (due to fully written or zone finish) What we really wanted to exclude from "total_bytes" is the total size of BGs #1. They seem empty and allocatable but since they are not activated, we cannot rely on them to do the space reservation. And, since BGs #1 never get activated, they should have no "used", "reserved" and "pinned" bytes. OTOH, BGs #3 can be counted in the "total", since they are already full we cannot allocate from them anyway. For them, "total_bytes == used + reserved + pinned + zone_unusable" should hold. Tracking #2 and #3 as "active_total_bytes" (current implementation) is confusing. And, tracking #1 and subtract that properly from "total_bytes" every time you need space reservation is cumbersome. Instead, we can count the whole region of a newly allocated block group as zone_unusable. Then, once that block group is activated, release [0 .. zone_capacity] from the zone_unusable counters. With this, we can eliminate the confusing ->active_total_bytes and the code will be common among regular and the zoned mode. Also, no additional counter is needed with this approach. Fixes: 6a921de ("btrfs: zoned: introduce space_info->active_total_bytes") CC: [email protected] # 6.1+ Signed-off-by: Naohiro Aota <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent df384da commit fa2068d

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

fs/btrfs/free-space-cache.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2693,8 +2693,13 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
26932693
bg_reclaim_threshold = READ_ONCE(sinfo->bg_reclaim_threshold);
26942694

26952695
spin_lock(&ctl->tree_lock);
2696+
/* Count initial region as zone_unusable until it gets activated. */
26962697
if (!used)
26972698
to_free = size;
2699+
else if (initial &&
2700+
test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &block_group->fs_info->flags) &&
2701+
(block_group->flags & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM)))
2702+
to_free = 0;
26982703
else if (initial)
26992704
to_free = block_group->zone_capacity;
27002705
else if (offset >= block_group->alloc_offset)
@@ -2722,7 +2727,8 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group,
27222727
reclaimable_unusable = block_group->zone_unusable -
27232728
(block_group->length - block_group->zone_capacity);
27242729
/* All the region is now unusable. Mark it as unused and reclaim */
2725-
if (block_group->zone_unusable == block_group->length) {
2730+
if (block_group->zone_unusable == block_group->length &&
2731+
block_group->alloc_offset) {
27262732
btrfs_mark_bg_unused(block_group);
27272733
} else if (bg_reclaim_threshold &&
27282734
reclaimable_unusable >=

fs/btrfs/zoned.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,9 +1580,19 @@ void btrfs_calc_zone_unusable(struct btrfs_block_group *cache)
15801580
return;
15811581

15821582
WARN_ON(cache->bytes_super != 0);
1583-
unusable = (cache->alloc_offset - cache->used) +
1584-
(cache->length - cache->zone_capacity);
1585-
free = cache->zone_capacity - cache->alloc_offset;
1583+
1584+
/* Check for block groups never get activated */
1585+
if (test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &cache->fs_info->flags) &&
1586+
cache->flags & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM) &&
1587+
!test_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &cache->runtime_flags) &&
1588+
cache->alloc_offset == 0) {
1589+
unusable = cache->length;
1590+
free = 0;
1591+
} else {
1592+
unusable = (cache->alloc_offset - cache->used) +
1593+
(cache->length - cache->zone_capacity);
1594+
free = cache->zone_capacity - cache->alloc_offset;
1595+
}
15861596

15871597
/* We only need ->free_space in ALLOC_SEQ block groups */
15881598
cache->cached = BTRFS_CACHE_FINISHED;
@@ -1901,7 +1911,11 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
19011911

19021912
/* Successfully activated all the zones */
19031913
set_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &block_group->runtime_flags);
1904-
space_info->active_total_bytes += block_group->length;
1914+
WARN_ON(block_group->alloc_offset != 0);
1915+
if (block_group->zone_unusable == block_group->length) {
1916+
block_group->zone_unusable = block_group->length - block_group->zone_capacity;
1917+
space_info->bytes_zone_unusable -= block_group->zone_capacity;
1918+
}
19051919
spin_unlock(&block_group->lock);
19061920
btrfs_try_granting_tickets(fs_info, space_info);
19071921
spin_unlock(&space_info->lock);
@@ -2265,7 +2279,7 @@ int btrfs_zone_finish_one_bg(struct btrfs_fs_info *fs_info)
22652279
u64 avail;
22662280

22672281
spin_lock(&block_group->lock);
2268-
if (block_group->reserved ||
2282+
if (block_group->reserved || block_group->alloc_offset == 0 ||
22692283
(block_group->flags & BTRFS_BLOCK_GROUP_SYSTEM)) {
22702284
spin_unlock(&block_group->lock);
22712285
continue;

0 commit comments

Comments
 (0)