]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 May 2023 09:53:43 +0000 (11:53 +0200)
commit 02ca9e6fb5f66a031df4fac508b8e477ca69e918 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/btrfs/zoned.c

index 1feb68ae2a8ecab4d4dedbf3d02feb8fa74656c7..836babd23db52e10dc1535884fdcfa5217c86b63 100644 (file)
@@ -119,10 +119,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);