]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
block: Move bdi_unregister() to del_gendisk()
authorJan Kara <jack@suse.cz>
Wed, 8 Feb 2017 07:05:56 +0000 (08:05 +0100)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Thu, 27 Apr 2017 13:04:16 +0000 (10:04 -0300)
BugLink: http://bugs.launchpad.net/bugs/1659111
Commit 6cd18e711dd8 "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 6cd18e711dd8 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 <lekshmicpillai@in.ibm.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Tested-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
(back ported from commit 165a5e22fafb127ecb5914e12e8c32a1f0d3f820)

Conflicts:
block/blk-core.c

Signed-off-by: Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Seth Forshee <seth.forshee@canonical.com>
Acked-by: Brad Figg <brad.figg@canonical.com>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
block/blk-core.c
block/genhd.c

index 434fa050a5509bb37abad2f52f1e9ea3d33dc64a..16767baf776da9cdb2cc0b2f7fcfeffc9879527a 100644 (file)
@@ -579,8 +579,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);
-
        /* @q is and will stay empty, shutdown and put */
        blk_put_queue(q);
 }
index 510a57a5254be312055479bb62e0be992541c150..6a6c7f544100c6f933a3edb4bf32d52d6e83657d 100644 (file)
@@ -658,6 +658,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);