btrfs: zoned: locate superblock position using zone capacity
authorNaohiro Aota <naohiro.aota@wdc.com>
Thu, 19 Aug 2021 12:19:13 +0000 (21:19 +0900)
committerDavid Sterba <dsterba@suse.com>
Tue, 26 Oct 2021 17:07:59 +0000 (19:07 +0200)
sb_write_pointer() returns the write position of next superblock. For READ,
we need a previous location. When the pointer is at the head, the previous
one is the last one of the other zone. Calculate the last one's position
from zone capacity.

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 c7c63190fbd66e548111d29c3553b9305d2c7388..9cfb5b741718d0c73c76e3eaf2198b0649bb5c1e 100644 (file)
@@ -683,9 +683,20 @@ static int sb_log_location(struct block_device *bdev, struct blk_zone *zones,
                        reset->wp = reset->start;
                }
        } else if (ret != -ENOENT) {
-               /* For READ, we want the precious one */
+               /*
+                * For READ, we want the previous one. Move write pointer to
+                * the end of a zone, if it is at the head of a zone.
+                */
+               u64 zone_end = 0;
+
                if (wp == zones[0].start << SECTOR_SHIFT)
-                       wp = (zones[1].start + zones[1].len) << SECTOR_SHIFT;
+                       zone_end = zones[1].start + zones[1].capacity;
+               else if (wp == zones[1].start << SECTOR_SHIFT)
+                       zone_end = zones[0].start + zones[0].capacity;
+               if (zone_end)
+                       wp = ALIGN_DOWN(zone_end << SECTOR_SHIFT,
+                                       BTRFS_SUPER_INFO_SIZE);
+
                wp -= BTRFS_SUPER_INFO_SIZE;
        }