diff mbox series

[4/7] loop: don't call blk_mq_freeze_queue()/blk_mq_unfreeze_queue() from lo_release()

Message ID 20220129071500.3566-5-penguin-kernel@I-love.SAKURA.ne.jp (mailing list archive)
State New, archived
Headers show
Series [1/7] loop: revert "make autoclear operation asynchronous" | expand

Commit Message

Tetsuo Handa Jan. 29, 2022, 7:14 a.m. UTC
It turned out that there is no need to call blk_mq_freeze_queue() from
lo_release(), for all pending I/O requests are flushed by the block core
layer before "struct block_device_operations"->release() is called.

As a preparation for not holding lo->lo_mutex from lo_open()/lo_release()
paths, remove blk_mq_freeze_queue()/blk_mq_unfreeze_queue() from
lo_release().

Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 drivers/block/loop.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 14b6f862531b..b6435f803061 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1108,7 +1108,8 @@  static void __loop_clr_fd(struct loop_device *lo, bool release)
 		blk_queue_write_cache(lo->lo_queue, false, false);
 
 	/* freeze request queue during the transition */
-	blk_mq_freeze_queue(lo->lo_queue);
+	if (!release)
+		blk_mq_freeze_queue(lo->lo_queue);
 
 	destroy_workqueue(lo->workqueue);
 	spin_lock_irq(&lo->lo_work_lock);
@@ -1139,7 +1140,8 @@  static void __loop_clr_fd(struct loop_device *lo, bool release)
 	/* let user-space know about this change */
 	kobject_uevent(&disk_to_dev(lo->lo_disk)->kobj, KOBJ_CHANGE);
 	mapping_set_gfp_mask(filp->f_mapping, gfp);
-	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);
 
@@ -1728,22 +1730,11 @@  static void lo_release(struct gendisk *disk, fmode_t mode)
 			goto out_unlock;
 		lo->lo_state = Lo_rundown;
 		mutex_unlock(&lo->lo_mutex);
-		/*
-		 * In autoclear mode, stop the loop thread
-		 * and remove configuration after last close.
-		 */
 		__loop_clr_fd(lo, true);
 		mutex_lock(&lo->lo_mutex);
 		lo->lo_state = Lo_unbound;
 		mutex_unlock(&lo->lo_mutex);
 		return;
-	} else if (lo->lo_state == Lo_bound) {
-		/*
-		 * Otherwise keep thread (if running) and config,
-		 * but flush possible ongoing bios in thread.
-		 */
-		blk_mq_freeze_queue(lo->lo_queue);
-		blk_mq_unfreeze_queue(lo->lo_queue);
 	}
 
 out_unlock: