summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2022-03-30 07:29:12 +0200
committerJens Axboe <axboe@kernel.dk>2022-04-18 06:54:09 -0600
commit1fe0b1acb14dd3113b7dc975a118cd7f08af8316 (patch)
treeeba2ed9c53de94888bb004718adc48baf04565fe /drivers/block
parent46dc967445bde5300eee7e567a67796de2217586 (diff)
downloadlinux-1fe0b1acb14dd3113b7dc975a118cd7f08af8316.tar.bz2
loop: only freeze the queue in __loop_clr_fd when needed
->release is only called after all outstanding I/O has completed, so only freeze the queue when clearing the backing file of a live loop device. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Tested-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20220330052917.2566582-11-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/loop.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index d6315b0c413e..d1a4af599359 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1139,8 +1139,13 @@ static void __loop_clr_fd(struct loop_device *lo, bool release)
if (test_bit(QUEUE_FLAG_WC, &lo->lo_queue->queue_flags))
blk_queue_write_cache(lo->lo_queue, false, false);
- /* freeze request queue during the transition */
- blk_mq_freeze_queue(lo->lo_queue);
+ /*
+ * Freeze the request queue when unbinding on a live file descriptor and
+ * thus an open device. When called from ->release we are guaranteed
+ * that there is no I/O in progress already.
+ */
+ if (!release)
+ blk_mq_freeze_queue(lo->lo_queue);
destroy_workqueue(lo->workqueue);
loop_free_idle_workers(lo, true);
@@ -1165,7 +1170,8 @@ static void __loop_clr_fd(struct loop_device *lo, bool release)
mapping_set_gfp_mask(filp->f_mapping, gfp);
/* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE);
- blk_mq_unfreeze_queue(lo->lo_queue);
+ if (!release)
+ blk_mq_unfreeze_queue(lo->lo_queue);
disk_force_media_change(lo->lo_disk, DISK_EVENT_MEDIA_CHANGE);