Skip to content

Commit

Permalink
block: hold a request_queue reference for the lifetime of struct gendisk
Browse files Browse the repository at this point in the history
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 <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Christoph Hellwig authored and axboe committed Aug 23, 2021
1 parent 4a1fa41 commit 61a35cf
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 13 deletions.
19 changes: 7 additions & 12 deletions block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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 */
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1296,6 +1289,8 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
bdi_put(disk->bdi);
out_free_disk:
kfree(disk);
out_put_queue:
blk_put_queue(q);
return NULL;
}
EXPORT_SYMBOL(__alloc_disk_node);
Expand Down
1 change: 0 additions & 1 deletion include/linux/genhd.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ struct gendisk {
unsigned long state;
#define GD_NEED_PART_SCAN 0
#define GD_READ_ONLY 1
#define GD_QUEUE_REF 2

struct mutex open_mutex; /* open/close mutex */
unsigned open_partitions; /* number of open partitions */
Expand Down

0 comments on commit 61a35cf

Please sign in to comment.