diff options
author | Christoph Hellwig <hch@lst.de> | 2021-08-16 15:19:09 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2021-08-23 12:54:31 -0600 |
commit | 61a35cfc26334fe1c8e970ca8fafeae2daae257d (patch) | |
tree | 73d024e0f1f89f96495780aaea0c2305b5f3412b /block/genhd.c | |
parent | 4a1fa41d304c7129328d4d5c7f31715b95e23b29 (diff) |
block: hold a request_queue reference for the lifetime of struct gendisk
Acquire the queue ref dropped in disk_release in __blk_alloc_disk so any
allocate gendisk always has a queue reference.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20210816131910.615153-9-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/genhd.c')
-rw-r--r-- | block/genhd.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/block/genhd.c b/block/genhd.c index f18122ee2778..6294517cebe6 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -551,15 +551,6 @@ void device_add_disk(struct device *parent, struct gendisk *disk, register_disk(parent, disk, groups); blk_register_queue(disk); - /* - * Take an extra ref on queue which will be put on disk_release() - * so that it sticks around as long as @disk is there. - */ - if (blk_get_queue(disk->queue)) - set_bit(GD_QUEUE_REF, &disk->state); - else - WARN_ON_ONCE(1); - disk_add_events(disk); blk_integrity_add(disk); } @@ -1087,8 +1078,7 @@ static void disk_release(struct device *dev) disk_release_events(disk); kfree(disk->random); xa_destroy(&disk->part_tbl); - if (test_bit(GD_QUEUE_REF, &disk->state) && disk->queue) - blk_put_queue(disk->queue); + blk_put_queue(disk->queue); iput(disk->part0->bd_inode); /* frees the disk */ } @@ -1259,9 +1249,12 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id, { struct gendisk *disk; + if (!blk_get_queue(q)) + return NULL; + disk = kzalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id); if (!disk) - return NULL; + goto out_put_queue; disk->bdi = bdi_alloc(node_id); if (!disk->bdi) @@ -1296,6 +1289,8 @@ out_free_bdi: bdi_put(disk->bdi); out_free_disk: kfree(disk); +out_put_queue: + blk_put_queue(q); return NULL; } EXPORT_SYMBOL(__alloc_disk_node); |