From: Christoph Hellwig hch@lst.de
mainline inclusion from mainline-v5.14-rc1 commit f525464a8000f092c20b00eead3eaa9d849c599e category: bugfix bugzilla: 188733
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
----------------------------------------
Add two new APIs to allocate and free a gendisk including the request_queue for use with BIO based drivers. This is to avoid boilerplate code in drivers.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Hannes Reinecke hare@suse.de Reviewed-by: Ulf Hansson ulf.hansson@linaro.org Link: https://lore.kernel.org/r/20210521055116.1053587-6-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk conflicts: block/genhd.c include/linux/genhd.h Signed-off-by: Zhong Jinghua zhongjinghua@huawei.com Signed-off-by: Li Nan linan122@huawei.com --- include/linux/genhd.h | 22 ++++++++++++++++++++++ block/genhd.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+)
diff --git a/include/linux/genhd.h b/include/linux/genhd.h index b0b9c4fa6311..dd58608f0ce7 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -401,6 +401,28 @@ extern void blk_delete_region(dev_t devt, unsigned long range,
#define alloc_disk(minors) alloc_disk_node(minors, NUMA_NO_NODE)
+/** + * blk_alloc_disk - allocate a gendisk structure + * @node_id: numa node to allocate on + * + * Allocate and pre-initialize a gendisk structure for use with BIO based + * drivers. + * + * Context: can sleep + */ +#define blk_alloc_disk(node_id) \ +({ \ + struct gendisk *__disk = __blk_alloc_disk(node_id); \ + static struct lock_class_key __key; \ + \ + if (__disk) \ + lockdep_init_map(&__disk->lockdep_map, \ + "(bio completion)", &__key, 0); \ + __disk; \ +}) +struct gendisk *__blk_alloc_disk(int node); +void blk_cleanup_disk(struct gendisk *disk); + int register_blkdev(unsigned int major, const char *name); void unregister_blkdev(unsigned int major, const char *name);
diff --git a/block/genhd.c b/block/genhd.c index e5df4d63ecd2..87f622899d70 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1927,6 +1927,25 @@ struct gendisk *__alloc_disk_node(int minors, int node_id) } EXPORT_SYMBOL(__alloc_disk_node);
+struct gendisk *__blk_alloc_disk(int node) +{ + struct request_queue *q; + struct gendisk *disk; + + q = blk_alloc_queue(node); + if (!q) + return NULL; + + disk = __alloc_disk_node(0, node); + if (!disk) { + blk_cleanup_queue(q); + return NULL; + } + disk->queue = q; + return disk; +} +EXPORT_SYMBOL(__blk_alloc_disk); + /** * get_disk_and_module - increments the gendisk and gendisk fops module refcount * @disk: the struct gendisk to increment the refcount for @@ -1973,6 +1992,22 @@ void put_disk(struct gendisk *disk) } EXPORT_SYMBOL(put_disk);
+/** + * blk_cleanup_disk - shutdown a gendisk allocated by blk_alloc_disk + * @disk: gendisk to shutdown + * + * Mark the queue hanging off @disk DYING, drain all pending requests, then mark + * the queue DEAD, destroy and put it and the gendisk structure. + * + * Context: can sleep + */ +void blk_cleanup_disk(struct gendisk *disk) +{ + blk_cleanup_queue(disk->queue); + put_disk(disk); +} +EXPORT_SYMBOL(blk_cleanup_disk); + /** * put_disk_and_module - decrements the module and gendisk refcount * @disk: the struct gendisk to decrement the refcount for