• Naohiro Aota's avatar
    btrfs: zoned: fix zone_unusable accounting on making block group read-write again · 8cd44dd1
    Naohiro Aota authored
    When btrfs makes a block group read-only, it adds all free regions in the
    block group to space_info->bytes_readonly. That free space excludes
    reserved and pinned regions. OTOH, when btrfs makes the block group
    read-write again, it moves all the unused regions into the block group's
    zone_unusable. That unused region includes reserved and pinned regions.
    As a result, it counts too much zone_unusable bytes.
    
    Fortunately (or unfortunately), having erroneous zone_unusable does not
    affect the calculation of space_info->bytes_readonly, because free
    space (num_bytes in btrfs_dec_block_group_ro) calculation is done based on
    the erroneous zone_unusable and it reduces the num_bytes just to cancel the
    error.
    
    This behavior can be easily discovered by adding a WARN_ON to check e.g,
    "bg->pinned > 0" in btrfs_dec_block_group_ro(), and running fstests test
    case like btrfs/282.
    
    Fix it by properly considering pinned and reserved in
    btrfs_dec_block_group_ro(). Also, add a WARN_ON and introduce
    btrfs_space_info_update_bytes_zone_unusable() to catch a similar mistake.
    
    Fixes: 169e0da9 ("btrfs: zoned: track unusable bytes for zones")
    CC: stable@vger.kernel.org # 5.15+
    Signed-off-by: default avatarNaohiro Aota <naohiro.aota@wdc.com>
    Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
    Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    8cd44dd1
block-group.c 140 KB