]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
btrfs: zoned: fix conventional zone capacity calculation
authorNaohiro Aota <naohiro.aota@wdc.com>
Fri, 12 Sep 2025 06:43:21 +0000 (15:43 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Nov 2025 09:36:03 +0000 (10:36 +0100)
commit 94f54924b96d3565c6b559294b3401b5496c21ac upstream.

When a block group contains both conventional zone and sequential zone, the
capacity of the block group is wrongly set to the block group's full
length. The capacity should be calculated in btrfs_load_block_group_* using
the last allocation offset.

Fixes: 568220fa9657 ("btrfs: zoned: support RAID0/1/10 on top of raid stripe tree")
CC: stable@vger.kernel.org # v6.12+
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/btrfs/zoned.c

index 64e0a5bf5f9a5dbb7a29ea136178d34840423daa..181cb3f56ab410688ad8b285c59540ef45a74504 100644 (file)
@@ -1300,6 +1300,7 @@ static int btrfs_load_zone_info(struct btrfs_fs_info *fs_info, int zone_idx,
        if (!btrfs_dev_is_sequential(device, info->physical)) {
                up_read(&dev_replace->rwsem);
                info->alloc_offset = WP_CONVENTIONAL;
+               info->capacity = device->zone_info->zone_size;
                return 0;
        }
 
@@ -1598,8 +1599,6 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
                set_bit(BLOCK_GROUP_FLAG_SEQUENTIAL_ZONE, &cache->runtime_flags);
 
        if (num_conventional > 0) {
-               /* Zone capacity is always zone size in emulation */
-               cache->zone_capacity = cache->length;
                ret = calculate_alloc_pointer(cache, &last_alloc, new);
                if (ret) {
                        btrfs_err(fs_info,
@@ -1608,6 +1607,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
                        goto out;
                } else if (map->num_stripes == num_conventional) {
                        cache->alloc_offset = last_alloc;
+                       cache->zone_capacity = cache->length;
                        set_bit(BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE, &cache->runtime_flags);
                        goto out;
                }