btrfs: zoned: fix full zone super block reading on ZNS
authorNaohiro Aota <Naohiro.Aota@wdc.com>
Tue, 9 May 2023 18:29:15 +0000 (18:29 +0000)
committerDavid Sterba <dsterba@suse.com>
Wed, 10 May 2023 12:50:22 +0000 (14:50 +0200)
When both of the superblock zones are full, we need to check which
superblock is newer. The calculation of last superblock position is wrong
as it does not consider zone_capacity and uses the length.

Fixes: 9658b72ef300 ("btrfs: zoned: locate superblock position using zone capacity")
CC: stable@vger.kernel.org # 6.1+
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 d510576..4243b04 100644 (file)
@@ -122,10 +122,9 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
                int i;
 
                for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) {
-                       u64 bytenr;
-
-                       bytenr = ((zones[i].start + zones[i].len)
-                                  << SECTOR_SHIFT) - BTRFS_SUPER_INFO_SIZE;
+                       u64 zone_end = (zones[i].start + zones[i].capacity) << SECTOR_SHIFT;
+                       u64 bytenr = ALIGN_DOWN(zone_end, BTRFS_SUPER_INFO_SIZE) -
+                                               BTRFS_SUPER_INFO_SIZE;
 
                        page[i] = read_cache_page_gfp(mapping,
                                        bytenr >> PAGE_SHIFT, GFP_NOFS);