Skip to content

Commit ecfe43b

Browse files
damien-lemoalaxboe
authored andcommitted
block: Remember zone capacity when revalidating zones
In preparation for adding zone write plugging, modify blk_revalidate_disk_zones() to get the capacity of zones of a zoned block device. This capacity value as a number of 512B sectors is stored in the gendisk zone_capacity field. Given that host-managed SMR disks (including zoned UFS drives) and all known NVMe ZNS devices have the same zone capacity for all zones blk_revalidate_disk_zones() returns an error if different capacities are detected for different zones. This also adds check to verify that the values reported by the device for zone capacities are correct, that is, that the zone capacity is never 0, does not exceed the zone size and is equal to the zone size for conventional zones. Signed-off-by: Damien Le Moal <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Tested-by: Hans Holmberg <[email protected]> Tested-by: Dennis Maisenbacher <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Reviewed-by: Johannes Thumshirn <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent dd850ff commit ecfe43b

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

block/blk-zoned.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ struct blk_revalidate_zone_args {
438438
unsigned long *conv_zones_bitmap;
439439
unsigned long *seq_zones_wlock;
440440
unsigned int nr_zones;
441+
unsigned int zone_capacity;
441442
sector_t sector;
442443
};
443444

@@ -482,9 +483,20 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
482483
return -ENODEV;
483484
}
484485

486+
if (!zone->capacity || zone->capacity > zone->len) {
487+
pr_warn("%s: Invalid zone capacity\n",
488+
disk->disk_name);
489+
return -ENODEV;
490+
}
491+
485492
/* Check zone type */
486493
switch (zone->type) {
487494
case BLK_ZONE_TYPE_CONVENTIONAL:
495+
if (zone->capacity != zone->len) {
496+
pr_warn("%s: Invalid conventional zone capacity\n",
497+
disk->disk_name);
498+
return -ENODEV;
499+
}
488500
if (!args->conv_zones_bitmap) {
489501
args->conv_zones_bitmap =
490502
blk_alloc_zone_bitmap(q->node, args->nr_zones);
@@ -500,6 +512,18 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
500512
if (!args->seq_zones_wlock)
501513
return -ENOMEM;
502514
}
515+
516+
/*
517+
* Remember the capacity of the first sequential zone and check
518+
* if it is constant for all zones.
519+
*/
520+
if (!args->zone_capacity)
521+
args->zone_capacity = zone->capacity;
522+
if (zone->capacity != args->zone_capacity) {
523+
pr_warn("%s: Invalid variable zone capacity\n",
524+
disk->disk_name);
525+
return -ENODEV;
526+
}
503527
break;
504528
case BLK_ZONE_TYPE_SEQWRITE_PREF:
505529
default:
@@ -595,6 +619,7 @@ int blk_revalidate_disk_zones(struct gendisk *disk,
595619
blk_mq_freeze_queue(q);
596620
if (ret > 0) {
597621
disk->nr_zones = args.nr_zones;
622+
disk->zone_capacity = args.zone_capacity;
598623
swap(disk->seq_zones_wlock, args.seq_zones_wlock);
599624
swap(disk->conv_zones_bitmap, args.conv_zones_bitmap);
600625
if (update_driver_data)
@@ -608,6 +633,7 @@ int blk_revalidate_disk_zones(struct gendisk *disk,
608633

609634
kfree(args.seq_zones_wlock);
610635
kfree(args.conv_zones_bitmap);
636+
611637
return ret;
612638
}
613639
EXPORT_SYMBOL_GPL(blk_revalidate_disk_zones);

include/linux/blkdev.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ struct gendisk {
191191
* blk_mq_unfreeze_queue().
192192
*/
193193
unsigned int nr_zones;
194+
unsigned int zone_capacity;
194195
unsigned long *conv_zones_bitmap;
195196
unsigned long *seq_zones_wlock;
196197
#endif /* CONFIG_BLK_DEV_ZONED */

0 commit comments

Comments
 (0)