btrfs: zoned: fix write time activation failure for metadata block group
authorNaohiro Aota <naohiro.aota@wdc.com>
Wed, 16 Jul 2025 07:59:54 +0000 (16:59 +0900)
committerDavid Sterba <dsterba@suse.com>
Wed, 13 Aug 2025 10:28:52 +0000 (12:28 +0200)
Since commit 13bb483d32ab ("btrfs: zoned: activate metadata block group on
write time"), we activate a metadata block group at the write time. If the
zone capacity is small enough, we can allocate the entire region before the
first write. Then, we hit the btrfs_zoned_bg_is_full() in
btrfs_zone_activate() and the activation fails.

For a data block group, we activate it at the allocation time and we should
check the fullness condition in the caller side. Add, a WARN to check the
fullness condition.

For a metadata block group, we don't need the fullness check because we
activate it at the write time. Instead, activating it once it is written
should be invalid. Catch that with a WARN too.

Fixes: 13bb483d32ab ("btrfs: zoned: activate metadata block group on write time")
CC: stable@vger.kernel.org # 6.6+
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/zoned.c

index 7a3351b1b0c612a4439022f7f0d38427db0b2eb6..ab6844dce8bc13948fb02fe8a69b88d4e9c3e201 100644 (file)
@@ -2169,10 +2169,15 @@ bool btrfs_zone_activate(struct btrfs_block_group *block_group)
                goto out_unlock;
        }
 
-       /* No space left */
-       if (btrfs_zoned_bg_is_full(block_group)) {
-               ret = false;
-               goto out_unlock;
+       if (block_group->flags & BTRFS_BLOCK_GROUP_DATA) {
+               /* The caller should check if the block group is full. */
+               if (WARN_ON_ONCE(btrfs_zoned_bg_is_full(block_group))) {
+                       ret = false;
+                       goto out_unlock;
+               }
+       } else {
+               /* Since it is already written, it should have been active. */
+               WARN_ON_ONCE(block_group->meta_write_pointer != block_group->start);
        }
 
        for (i = 0; i < map->num_stripes; i++) {