Skip to content

Commit 7a5428d

Browse files
Christoph Hellwigaxboe
authored andcommitted
block: fix surprise removal for drivers calling blk_set_queue_dying
Various block drivers call blk_set_queue_dying to mark a disk as dead due to surprise removal events, but since commit 8e141f9 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: 8e141f9 ("block: drain file system I/O on del_gendisk") Reported-by: Markus Blöchl <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Sagi Grimberg <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent cc8f7fe commit 7a5428d

File tree

9 files changed

+24
-15
lines changed

9 files changed

+24
-15
lines changed

block/blk-core.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,6 @@ void blk_queue_start_drain(struct request_queue *q)
284284
wake_up_all(&q->mq_freeze_wq);
285285
}
286286

287-
void blk_set_queue_dying(struct request_queue *q)
288-
{
289-
blk_queue_flag_set(QUEUE_FLAG_DYING, q);
290-
blk_queue_start_drain(q);
291-
}
292-
EXPORT_SYMBOL_GPL(blk_set_queue_dying);
293-
294287
/**
295288
* blk_cleanup_queue - shutdown a request queue
296289
* @q: request queue to shutdown
@@ -308,7 +301,8 @@ void blk_cleanup_queue(struct request_queue *q)
308301
WARN_ON_ONCE(blk_queue_registered(q));
309302

310303
/* mark @q DYING, no new request or merges will be allowed afterwards */
311-
blk_set_queue_dying(q);
304+
blk_queue_flag_set(QUEUE_FLAG_DYING, q);
305+
blk_queue_start_drain(q);
312306

313307
blk_queue_flag_set(QUEUE_FLAG_NOMERGES, q);
314308
blk_queue_flag_set(QUEUE_FLAG_NOXMERGES, q);

block/genhd.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,20 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
548548
}
549549
EXPORT_SYMBOL(device_add_disk);
550550

551+
/**
552+
* blk_mark_disk_dead - mark a disk as dead
553+
* @disk: disk to mark as dead
554+
*
555+
* Mark as disk as dead (e.g. surprise removed) and don't accept any new I/O
556+
* to this disk.
557+
*/
558+
void blk_mark_disk_dead(struct gendisk *disk)
559+
{
560+
set_bit(GD_DEAD, &disk->state);
561+
blk_queue_start_drain(disk->queue);
562+
}
563+
EXPORT_SYMBOL_GPL(blk_mark_disk_dead);
564+
551565
/**
552566
* del_gendisk - remove the gendisk
553567
* @disk: the struct gendisk to remove

drivers/block/mtip32xx/mtip32xx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4112,7 +4112,7 @@ static void mtip_pci_remove(struct pci_dev *pdev)
41124112
"Completion workers still active!\n");
41134113
}
41144114

4115-
blk_set_queue_dying(dd->queue);
4115+
blk_mark_disk_dead(dd->disk);
41164116
set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
41174117

41184118
/* Clean up the block layer. */

drivers/block/rbd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7185,7 +7185,7 @@ static ssize_t do_rbd_remove(struct bus_type *bus,
71857185
* IO to complete/fail.
71867186
*/
71877187
blk_mq_freeze_queue(rbd_dev->disk->queue);
7188-
blk_set_queue_dying(rbd_dev->disk->queue);
7188+
blk_mark_disk_dead(rbd_dev->disk);
71897189
}
71907190

71917191
del_gendisk(rbd_dev->disk);

drivers/block/xen-blkfront.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2126,7 +2126,7 @@ static void blkfront_closing(struct blkfront_info *info)
21262126

21272127
/* No more blkif_request(). */
21282128
blk_mq_stop_hw_queues(info->rq);
2129-
blk_set_queue_dying(info->rq);
2129+
blk_mark_disk_dead(info->gd);
21302130
set_capacity(info->gd, 0);
21312131

21322132
for_each_rinfo(info, rinfo, i) {

drivers/md/dm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2077,7 +2077,7 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
20772077
set_bit(DMF_FREEING, &md->flags);
20782078
spin_unlock(&_minor_lock);
20792079

2080-
blk_set_queue_dying(md->queue);
2080+
blk_mark_disk_dead(md->disk);
20812081

20822082
/*
20832083
* Take suspend_lock so that presuspend and postsuspend methods

drivers/nvme/host/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4574,7 +4574,7 @@ static void nvme_set_queue_dying(struct nvme_ns *ns)
45744574
if (test_and_set_bit(NVME_NS_DEAD, &ns->flags))
45754575
return;
45764576

4577-
blk_set_queue_dying(ns->queue);
4577+
blk_mark_disk_dead(ns->disk);
45784578
nvme_start_ns_queue(ns);
45794579

45804580
set_capacity_and_notify(ns->disk, 0);

drivers/nvme/host/multipath.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
848848
{
849849
if (!head->disk)
850850
return;
851-
blk_set_queue_dying(head->disk->queue);
851+
blk_mark_disk_dead(head->disk);
852852
/* make sure all pending bios are cleaned up */
853853
kblockd_schedule_work(&head->requeue_work);
854854
flush_work(&head->requeue_work);

include/linux/blkdev.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,8 @@ extern bool blk_queue_can_use_dma_map_merging(struct request_queue *q,
748748

749749
bool __must_check blk_get_queue(struct request_queue *);
750750
extern void blk_put_queue(struct request_queue *);
751-
extern void blk_set_queue_dying(struct request_queue *);
751+
752+
void blk_mark_disk_dead(struct gendisk *disk);
752753

753754
#ifdef CONFIG_BLOCK
754755
/*

0 commit comments

Comments
 (0)