mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
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 commit8e141f9eb8
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:8e141f9eb8
("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>
This commit is contained in:
parent
cc8f7fe1f5
commit
7a5428dcb7
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user