Message ID | 20200427113153.31246-7-johannes.thumshirn@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introduce Zone Append for writing to zoned block devices | expand |
On 4/27/20 1:31 PM, Johannes Thumshirn wrote: > From: Damien Le Moal <damien.lemoal@wdc.com> > > 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> > --- > block/blk-zoned.c | 9 ++++++++- > drivers/block/null_blk_zoned.c | 2 +- > include/linux/blkdev.h | 3 ++- > 3 files changed, 11 insertions(+), 3 deletions(-) > > diff --git a/block/blk-zoned.c b/block/blk-zoned.c > index c822cfa7a102..23831fa8701d 100644 > --- a/block/blk-zoned.c > +++ b/block/blk-zoned.c > @@ -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 > * @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 > * 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 > * drivers only q->nr_zones needs to be updated so that the sysfs exposed value > * 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 blk_revalidate_zone_args args = { > @@ -512,6 +517,8 @@ int blk_revalidate_disk_zones(struct gendisk *disk) > q->nr_zones = args.nr_zones; > swap(q->seq_zones_wlock, args.seq_zones_wlock); > swap(q->conv_zones_bitmap, args.conv_zones_bitmap); > + if (update_driver_data) > + update_driver_data(disk); > ret = 0; > } else { > pr_warn("%s: failed to revalidate zones\n", disk->disk_name); > diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c > index 9e4bcdad1a80..46641df2e58e 100644 > --- a/drivers/block/null_blk_zoned.c > +++ b/drivers/block/null_blk_zoned.c > @@ -73,7 +73,7 @@ int null_register_zoned_dev(struct nullb *nullb) > struct request_queue *q = nullb->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); > q->nr_zones = blkdev_nr_zones(nullb->disk); > diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h > index d6e6ce3dc656..fd405dac8eb0 100644 > --- a/include/linux/blkdev.h > +++ b/include/linux/blkdev.h > @@ -357,7 +357,8 @@ unsigned int blkdev_nr_zones(struct gendisk *disk); > extern int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op, > sector_t sectors, sector_t nr_sectors, > 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, > unsigned int cmd, unsigned long arg); > Reviewed-by: Hannes Reinecke <hare@suse.de> Cheers, Hannes
diff --git a/block/blk-zoned.c b/block/blk-zoned.c index c822cfa7a102..23831fa8701d 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -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 * @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 * 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 * drivers only q->nr_zones needs to be updated so that the sysfs exposed value * 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 blk_revalidate_zone_args args = { @@ -512,6 +517,8 @@ int blk_revalidate_disk_zones(struct gendisk *disk) q->nr_zones = args.nr_zones; swap(q->seq_zones_wlock, args.seq_zones_wlock); swap(q->conv_zones_bitmap, args.conv_zones_bitmap); + if (update_driver_data) + update_driver_data(disk); ret = 0; } else { pr_warn("%s: failed to revalidate zones\n", disk->disk_name); diff --git a/drivers/block/null_blk_zoned.c b/drivers/block/null_blk_zoned.c index 9e4bcdad1a80..46641df2e58e 100644 --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk_zoned.c @@ -73,7 +73,7 @@ int null_register_zoned_dev(struct nullb *nullb) struct request_queue *q = nullb->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); q->nr_zones = blkdev_nr_zones(nullb->disk); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d6e6ce3dc656..fd405dac8eb0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -357,7 +357,8 @@ unsigned int blkdev_nr_zones(struct gendisk *disk); extern int blkdev_zone_mgmt(struct block_device *bdev, enum req_opf op, sector_t sectors, sector_t nr_sectors, 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, unsigned int cmd, unsigned long arg);