]> git.baikalelectronics.ru Git - kernel.git/commitdiff
block: fix surprise removal for drivers calling blk_set_queue_dying
authorChristoph Hellwig <hch@lst.de>
Thu, 17 Feb 2022 07:52:31 +0000 (08:52 +0100)
committerJens Axboe <axboe@kernel.dk>
Thu, 17 Feb 2022 14:54:03 +0000 (07:54 -0700)
Various block drivers call blk_set_queue_dying to mark a disk as dead due
to surprise removal events, but since commit b44b1c0ab7ff that doesn't
work given that the GD_DEAD flag needs to be set to stop I/O.

Replace the driver calls to blk_set_queue_dying with a new (and properly
documented) blk_mark_disk_dead API, and fold blk_set_queue_dying into the
only remaining caller.

Fixes: b44b1c0ab7ff ("block: drain file system I/O on del_gendisk")
Reported-by: Markus Blöchl <markus.bloechl@ipetronik.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Link: https://lore.kernel.org/r/20220217075231.1140-1-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-core.c
block/genhd.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/rbd.c
drivers/block/xen-blkfront.c
drivers/md/dm.c
drivers/nvme/host/core.c
drivers/nvme/host/multipath.c
include/linux/blkdev.h

index d93e3bb9a769b46a29f6c1b4abbc15441341dd01..1039515c99d6aba244bda3fc9b132c00d2191d09 100644 (file)
@@ -284,13 +284,6 @@ void blk_queue_start_drain(struct request_queue *q)
        wake_up_all(&q->mq_freeze_wq);
 }
 
-void blk_set_queue_dying(struct request_queue *q)
-{
-       blk_queue_flag_set(QUEUE_FLAG_DYING, q);
-       blk_queue_start_drain(q);
-}
-EXPORT_SYMBOL_GPL(blk_set_queue_dying);
-
 /**
  * blk_cleanup_queue - shutdown a request queue
  * @q: request queue to shutdown
@@ -308,7 +301,8 @@ void blk_cleanup_queue(struct request_queue *q)
        WARN_ON_ONCE(blk_queue_registered(q));
 
        /* mark @q DYING, no new request or merges will be allowed afterwards */
-       blk_set_queue_dying(q);
+       blk_queue_flag_set(QUEUE_FLAG_DYING, q);
+       blk_queue_start_drain(q);
 
        blk_queue_flag_set(QUEUE_FLAG_NOMERGES, q);
        blk_queue_flag_set(QUEUE_FLAG_NOXMERGES, q);
index 626c8406f21a6a5b5def739ea87a8678e9732303..9eca1f7d35c9712e24db5978531708b52b5e1047 100644 (file)
@@ -548,6 +548,20 @@ out_free_ext_minor:
 }
 EXPORT_SYMBOL(device_add_disk);
 
+/**
+ * blk_mark_disk_dead - mark a disk as dead
+ * @disk: disk to mark as dead
+ *
+ * Mark as disk as dead (e.g. surprise removed) and don't accept any new I/O
+ * to this disk.
+ */
+void blk_mark_disk_dead(struct gendisk *disk)
+{
+       set_bit(GD_DEAD, &disk->state);
+       blk_queue_start_drain(disk->queue);
+}
+EXPORT_SYMBOL_GPL(blk_mark_disk_dead);
+
 /**
  * del_gendisk - remove the gendisk
  * @disk: the struct gendisk to remove
index e6005c2323281d7a3793f148e5decd2276dbe6cc..2b588b62cbbb27f0b905aec3cf26dc7623261162 100644 (file)
@@ -4112,7 +4112,7 @@ static void mtip_pci_remove(struct pci_dev *pdev)
                        "Completion workers still active!\n");
        }
 
-       blk_set_queue_dying(dd->queue);
+       blk_mark_disk_dead(dd->disk);
        set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
 
        /* Clean up the block layer. */
index 4203cdab8abfdd191568583e83d554b44e971dc9..b844432bad20b4b07b7fdc89424ee0095428ec28 100644 (file)
@@ -7185,7 +7185,7 @@ static ssize_t do_rbd_remove(struct bus_type *bus,
                 * IO to complete/fail.
                 */
                blk_mq_freeze_queue(rbd_dev->disk->queue);
-               blk_set_queue_dying(rbd_dev->disk->queue);
+               blk_mark_disk_dead(rbd_dev->disk);
        }
 
        del_gendisk(rbd_dev->disk);
index ccd0dd0c6b83c5d4e04784baf353924c3d39de15..ca71a0585333fbbe1e553ddb9c37a0d8b6ec3072 100644 (file)
@@ -2126,7 +2126,7 @@ static void blkfront_closing(struct blkfront_info *info)
 
        /* No more blkif_request(). */
        blk_mq_stop_hw_queues(info->rq);
-       blk_set_queue_dying(info->rq);
+       blk_mark_disk_dead(info->gd);
        set_capacity(info->gd, 0);
 
        for_each_rinfo(info, rinfo, i) {
index dcbd6d201619d0fd62931af3de1e073648852d1f..997ace47bbd54498172de36da890a11fa3672feb 100644 (file)
@@ -2077,7 +2077,7 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
        set_bit(DMF_FREEING, &md->flags);
        spin_unlock(&_minor_lock);
 
-       blk_set_queue_dying(md->queue);
+       blk_mark_disk_dead(md->disk);
 
        /*
         * Take suspend_lock so that presuspend and postsuspend methods
index 79005ea1a33e380b83ecd2e599619032e44f2f33..469f23186159c2c619e082a538b08b39f552af49 100644 (file)
@@ -4574,7 +4574,7 @@ static void nvme_set_queue_dying(struct nvme_ns *ns)
        if (test_and_set_bit(NVME_NS_DEAD, &ns->flags))
                return;
 
-       blk_set_queue_dying(ns->queue);
+       blk_mark_disk_dead(ns->disk);
        nvme_start_ns_queue(ns);
 
        set_capacity_and_notify(ns->disk, 0);
index f8bf6606eb2fca1a7f97912cff07a98850a66562..ff775235534cf86633eee8047302ab9eebff5025 100644 (file)
@@ -848,7 +848,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
 {
        if (!head->disk)
                return;
-       blk_set_queue_dying(head->disk->queue);
+       blk_mark_disk_dead(head->disk);
        /* make sure all pending bios are cleaned up */
        kblockd_schedule_work(&head->requeue_work);
        flush_work(&head->requeue_work);
index f35aea98bc3510b6e2fd32fa9ece687c567ba15d..16b47035e4b0629d9f3bfe144a5ac67b39193e38 100644 (file)
@@ -748,7 +748,8 @@ extern bool blk_queue_can_use_dma_map_merging(struct request_queue *q,
 
 bool __must_check blk_get_queue(struct request_queue *);
 extern void blk_put_queue(struct request_queue *);
-extern void blk_set_queue_dying(struct request_queue *);
+
+void blk_mark_disk_dead(struct gendisk *disk);
 
 #ifdef CONFIG_BLOCK
 /*