block: Modify revalidate zones

Modify the interface of blk_revalidate_disk_zones() to add an optional
driver callback function that a driver can use to extend processing
done during zone revalidation. The callback, if defined, is executed
with the device request queue frozen, after all zones have been
inspected.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Damien Le Moal 2020-05-12 17:55:49 +09:00 committed by Jens Axboe
parent 1392d37018
commit e732671aa5
3 changed files with 11 additions and 3 deletions

View File

@ -471,14 +471,19 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx,
/** /**
* blk_revalidate_disk_zones - (re)allocate and initialize zone bitmaps * blk_revalidate_disk_zones - (re)allocate and initialize zone bitmaps
* @disk: Target disk * @disk: Target disk
* @update_driver_data: Callback to update driver data on the frozen disk
* *
* Helper function for low-level device drivers to (re) allocate and initialize * Helper function for low-level device drivers to (re) allocate and initialize
* a disk request queue zone bitmaps. This functions should normally be called * a disk request queue zone bitmaps. This functions should normally be called
* within the disk ->revalidate method for blk-mq based drivers. For BIO based * within the disk ->revalidate method for blk-mq based drivers. For BIO based
* drivers only q->nr_zones needs to be updated so that the sysfs exposed value * drivers only q->nr_zones needs to be updated so that the sysfs exposed value
* is correct. * is correct.
* If the @update_driver_data callback function is not NULL, the callback is
* executed with the device request queue frozen after all zones have been
* checked.
*/ */
int blk_revalidate_disk_zones(struct gendisk *disk) int blk_revalidate_disk_zones(struct gendisk *disk,
void (*update_driver_data)(struct gendisk *disk))
{ {
struct request_queue *q = disk->queue; struct request_queue *q = disk->queue;
struct blk_revalidate_zone_args args = { struct blk_revalidate_zone_args args = {
@ -512,6 +517,8 @@ int blk_revalidate_disk_zones(struct gendisk *disk)
q->nr_zones = args.nr_zones; q->nr_zones = args.nr_zones;
swap(q->seq_zones_wlock, args.seq_zones_wlock); swap(q->seq_zones_wlock, args.seq_zones_wlock);
swap(q->conv_zones_bitmap, args.conv_zones_bitmap); swap(q->conv_zones_bitmap, args.conv_zones_bitmap);
if (update_driver_data)
update_driver_data(disk);
ret = 0; ret = 0;
} else { } else {
pr_warn("%s: failed to revalidate zones\n", disk->disk_name); pr_warn("%s: failed to revalidate zones\n", disk->disk_name);

View File

@ -73,7 +73,7 @@ int null_register_zoned_dev(struct nullb *nullb)
struct request_queue *q = nullb->q; struct request_queue *q = nullb->q;
if (queue_is_mq(q)) if (queue_is_mq(q))
return blk_revalidate_disk_zones(nullb->disk); return blk_revalidate_disk_zones(nullb->disk, NULL);
blk_queue_chunk_sectors(q, nullb->dev->zone_size_sects); blk_queue_chunk_sectors(q, nullb->dev->zone_size_sects);
q->nr_zones = blkdev_nr_zones(nullb->disk); q->nr_zones = blkdev_nr_zones(nullb->disk);

View File

@ -358,7 +358,8 @@ unsigned int blkdev_nr_zones(struct gendisk *disk);
extern int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op, extern int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op,
sector_t sectors, sector_t nr_sectors, sector_t sectors, sector_t nr_sectors,
gfp_t gfp_mask); gfp_t gfp_mask);
extern int blk_revalidate_disk_zones(struct gendisk *disk); int blk_revalidate_disk_zones(struct gendisk *disk,
void (*update_driver_data)(struct gendisk *disk));
extern int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode, extern int blkdev_report_zones_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);