btrfs: zoned: consider zone as full when no more SB can be written
authorNaohiro Aota <naohiro.aota@wdc.com>
Thu, 19 Aug 2021 12:19:12 +0000 (21:19 +0900)
committerDavid Sterba <dsterba@suse.com>
Tue, 26 Oct 2021 17:07:59 +0000 (19:07 +0200)
We cannot write beyond zone capacity. So, we should consider a zone as
"full" when the write pointer goes beyond capacity - the size of super
info.

Also, take this opportunity to replace a subtle duplicated code with a loop
and fix a typo in comment.

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 a92d6e5..c7c6319 100644 (file)
  */
 #define BTRFS_MAX_ZONE_SIZE            SZ_8G
 
+#define SUPER_INFO_SECTORS     ((u64)BTRFS_SUPER_INFO_SIZE >> SECTOR_SHIFT)
+
+static inline bool sb_zone_is_full(const struct blk_zone *zone)
+{
+       return (zone->cond == BLK_ZONE_COND_FULL) ||
+               (zone->wp + SUPER_INFO_SECTORS > zone->start + zone->capacity);
+}
+
 static int copy_zone_info_cb(struct blk_zone *zone, unsigned int idx, void *data)
 {
        struct blk_zone *zones = data;
@@ -60,14 +68,13 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
        bool empty[BTRFS_NR_SB_LOG_ZONES];
        bool full[BTRFS_NR_SB_LOG_ZONES];
        sector_t sector;
+       int i;
 
-       ASSERT(zones[0].type != BLK_ZONE_TYPE_CONVENTIONAL &&
-              zones[1].type != BLK_ZONE_TYPE_CONVENTIONAL);
-
-       empty[0] = (zones[0].cond == BLK_ZONE_COND_EMPTY);
-       empty[1] = (zones[1].cond == BLK_ZONE_COND_EMPTY);
-       full[0] = (zones[0].cond == BLK_ZONE_COND_FULL);
-       full[1] = (zones[1].cond == BLK_ZONE_COND_FULL);
+       for (i = 0; i < BTRFS_NR_SB_LOG_ZONES; i++) {
+               ASSERT(zones[i].type != BLK_ZONE_TYPE_CONVENTIONAL);
+               empty[i] = (zones[i].cond == BLK_ZONE_COND_EMPTY);
+               full[i] = sb_zone_is_full(&zones[i]);
+       }
 
        /*
         * Possible states of log buffer zones
@@ -664,7 +671,7 @@ static int sb_log_location(struct block_device *bdev, struct blk_zone *zones,
                        reset = &zones[1];
 
                if (reset && reset->cond != BLK_ZONE_COND_EMPTY) {
-                       ASSERT(reset->cond == BLK_ZONE_COND_FULL);
+                       ASSERT(sb_zone_is_full(reset));
 
                        ret = blkdev_zone_mgmt(bdev, REQ_OP_ZONE_RESET,
                                               reset->start, reset->len,