Skip to content

Commit

Permalink
block: Move bdi_unregister() to del_gendisk()
Browse files Browse the repository at this point in the history
Commit 6cd18e7 "block: destroy bdi before blockdev is
unregistered." moved bdi unregistration (at that time through
bdi_destroy()) from blk_release_queue() to blk_cleanup_queue() because
it needs to happen before blk_unregister_region() call in del_gendisk()
for MD. SCSI though will free up the device number from sd_remove()
called through a maze of callbacks from device_del() in
__scsi_remove_device() before blk_cleanup_queue() and thus similar races
as described in 6cd18e7 can happen for SCSI as well as reported by
Omar [1].

Moving bdi_unregister() to del_gendisk() works for MD and fixes the
problem for SCSI since del_gendisk() gets called from sd_remove() before
freeing the device number.

This also makes device_add_disk() (calling bdi_register_owner()) more
symmetric with del_gendisk().

[1] http://marc.info/?l=linux-block&m=148554717109098&w=2

Tested-by: Lekshmi Pillai <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Signed-off-by: Jan Kara <[email protected]>
Tested-by: Omar Sandoval <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
jankara authored and axboe committed Mar 2, 2017
1 parent 113285b commit 165a5e2
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 1 deletion.
1 change: 0 additions & 1 deletion block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,6 @@ void blk_cleanup_queue(struct request_queue *q)
q->queue_lock = &q->__queue_lock;
spin_unlock_irq(lock);

bdi_unregister(q->backing_dev_info);
put_disk_devt(q->disk_devt);

/* @q is and will stay empty, shutdown and put */
Expand Down
5 changes: 5 additions & 0 deletions block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,11 @@ void del_gendisk(struct gendisk *disk)
disk->flags &= ~GENHD_FL_UP;

sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
/*
* Unregister bdi before releasing device numbers (as they can get
* reused and we'd get clashes in sysfs).
*/
bdi_unregister(disk->queue->backing_dev_info);
blk_unregister_queue(disk);
blk_unregister_region(disk_devt(disk), disk->minors);

Expand Down

0 comments on commit 165a5e2

Please sign in to comment.