summaryrefslogtreecommitdiffstats
path: root/block/blk-zoned.c
diff options
context:
space:
mode:
authorDamien Le Moal <dlemoal@kernel.org>2024-05-01 13:09:07 +0200
committerJens Axboe <axboe@kernel.dk>2024-05-01 16:08:43 +0200
commitd7580149efc5c86c4e72f9263b97c062616a84dd (patch)
tree6b8c68ac7f7f03adb57920c1e23010faf46cc494 /block/blk-zoned.c
parentblock: Simplify zone write plug BIO abort (diff)
downloadlinux-d7580149efc5c86c4e72f9263b97c062616a84dd.tar.xz
linux-d7580149efc5c86c4e72f9263b97c062616a84dd.zip
block: Cleanup blk_revalidate_zone_cb()
Define the code for checking conventional and sequential write required zones suing the functions blk_revalidate_conv_zone() and blk_revalidate_seq_zone() respectively. This simplifies the zone type switch-case in blk_revalidate_zone_cb(). No functional changes. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20240501110907.96950-15-dlemoal@kernel.org Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-zoned.c')
-rw-r--r--block/blk-zoned.c129
1 files changed, 77 insertions, 52 deletions
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 15e4e14e16f7..48e5e3bbb89c 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -1656,6 +1656,74 @@ static int disk_update_zone_resources(struct gendisk *disk,
return queue_limits_commit_update(q, &lim);
}
+static int blk_revalidate_conv_zone(struct blk_zone *zone, unsigned int idx,
+ struct blk_revalidate_zone_args *args)
+{
+ struct gendisk *disk = args->disk;
+ struct request_queue *q = disk->queue;
+
+ if (zone->capacity != zone->len) {
+ pr_warn("%s: Invalid conventional zone capacity\n",
+ disk->disk_name);
+ return -ENODEV;
+ }
+
+ if (!disk_need_zone_resources(disk))
+ return 0;
+
+ if (!args->conv_zones_bitmap) {
+ args->conv_zones_bitmap =
+ blk_alloc_zone_bitmap(q->node, args->nr_zones);
+ if (!args->conv_zones_bitmap)
+ return -ENOMEM;
+ }
+
+ set_bit(idx, args->conv_zones_bitmap);
+
+ return 0;
+}
+
+static int blk_revalidate_seq_zone(struct blk_zone *zone, unsigned int idx,
+ struct blk_revalidate_zone_args *args)
+{
+ struct gendisk *disk = args->disk;
+ struct blk_zone_wplug *zwplug;
+ unsigned int wp_offset;
+ unsigned long flags;
+
+ /*
+ * Remember the capacity of the first sequential zone and check
+ * if it is constant for all zones.
+ */
+ if (!args->zone_capacity)
+ args->zone_capacity = zone->capacity;
+ if (zone->capacity != args->zone_capacity) {
+ pr_warn("%s: Invalid variable zone capacity\n",
+ disk->disk_name);
+ return -ENODEV;
+ }
+
+ /*
+ * We need to track the write pointer of all zones that are not
+ * empty nor full. So make sure we have a zone write plug for
+ * such zone if the device has a zone write plug hash table.
+ */
+ if (!disk->zone_wplugs_hash)
+ return 0;
+
+ wp_offset = blk_zone_wp_offset(zone);
+ if (!wp_offset || wp_offset >= zone->capacity)
+ return 0;
+
+ zwplug = disk_get_and_lock_zone_wplug(disk, zone->wp, GFP_NOIO, &flags);
+ if (!zwplug)
+ return -ENOMEM;
+ spin_unlock_irqrestore(&zwplug->lock, flags);
+ disk_put_zone_wplug(zwplug);
+
+ return 0;
+}
+
/*
* Helper function to check the validity of zones of a zoned block device.
*/
@@ -1664,12 +1732,9 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
{
struct blk_revalidate_zone_args *args = data;
struct gendisk *disk = args->disk;
- struct request_queue *q = disk->queue;
sector_t capacity = get_capacity(disk);
- sector_t zone_sectors = q->limits.chunk_sectors;
- struct blk_zone_wplug *zwplug;
- unsigned long flags;
- unsigned int wp_offset;
+ sector_t zone_sectors = disk->queue->limits.chunk_sectors;
+ int ret;
/* Check for bad zones and holes in the zone report */
if (zone->start != args->sector) {
@@ -1709,62 +1774,22 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
/* Check zone type */
switch (zone->type) {
case BLK_ZONE_TYPE_CONVENTIONAL:
- if (zone->capacity != zone->len) {
- pr_warn("%s: Invalid conventional zone capacity\n",
- disk->disk_name);
- return -ENODEV;
- }
-
- if (!disk_need_zone_resources(disk))
- break;
- if (!args->conv_zones_bitmap) {
- args->conv_zones_bitmap =
- blk_alloc_zone_bitmap(q->node, args->nr_zones);
- if (!args->conv_zones_bitmap)
- return -ENOMEM;
- }
- set_bit(idx, args->conv_zones_bitmap);
+ ret = blk_revalidate_conv_zone(zone, idx, args);
break;
case BLK_ZONE_TYPE_SEQWRITE_REQ:
- /*
- * Remember the capacity of the first sequential zone and check
- * if it is constant for all zones.
- */
- if (!args->zone_capacity)
- args->zone_capacity = zone->capacity;
- if (zone->capacity != args->zone_capacity) {
- pr_warn("%s: Invalid variable zone capacity\n",
- disk->disk_name);
- return -ENODEV;
- }
-
- /*
- * We need to track the write pointer of all zones that are not
- * empty nor full. So make sure we have a zone write plug for
- * such zone if the device has a zone write plug hash table.
- */
- if (!disk->zone_wplugs_hash)
- break;
- wp_offset = blk_zone_wp_offset(zone);
- if (wp_offset && wp_offset < zone->capacity) {
- zwplug = disk_get_and_lock_zone_wplug(disk, zone->wp,
- GFP_NOIO, &flags);
- if (!zwplug)
- return -ENOMEM;
- spin_unlock_irqrestore(&zwplug->lock, flags);
- disk_put_zone_wplug(zwplug);
- }
-
+ ret = blk_revalidate_seq_zone(zone, idx, args);
break;
case BLK_ZONE_TYPE_SEQWRITE_PREF:
default:
pr_warn("%s: Invalid zone type 0x%x at sectors %llu\n",
disk->disk_name, (int)zone->type, zone->start);
- return -ENODEV;
+ ret = -ENODEV;
}
- args->sector += zone->len;
- return 0;
+ if (!ret)
+ args->sector += zone->len;
+
+ return ret;
}
/**