diff mbox series

[7/8] loop: move loop device deletion out of loop_ctl_mutex

Message ID 20210826133810.3700-8-hch@lst.de (mailing list archive)
State New, archived
Headers show
Series [1/8] cryptoloop: fix a sparse annotation | expand

Commit Message

hch@lst.de Aug. 26, 2021, 1:38 p.m. UTC
To avoid complex lock ordering issues always delete loop devices outside
of loop_ctl_mutex.  In loop_control_remove the Lo_deleting state can
be used to prevent further lookups, and given that module unload is
synchronized vs new opens of the control device and thus ioctls there
is no need for locks there at all.

Based on patches from Hillf Danton <hdanton@sina.com> and
Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>.

Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/block/loop.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 6ee4b046bdcc..cb857d5e8313 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -2478,7 +2478,11 @@  static int loop_control_remove(int idx)
 	mutex_unlock(&lo->lo_mutex);
 
 	idr_remove(&loop_index_idr, lo->lo_number);
+	mutex_unlock(&loop_ctl_mutex);
+
 	loop_remove(lo);
+	return 0;
+
 out_unlock_ctrl:
 	mutex_unlock(&loop_ctl_mutex);
 	return ret;
@@ -2609,11 +2613,12 @@  static void __exit loop_exit(void)
 	unregister_blkdev(LOOP_MAJOR, "loop");
 	misc_deregister(&loop_misc);
 
-	mutex_lock(&loop_ctl_mutex);
+	/*
+	 * No need for loop_ctl_mutex given that no new ioctls and thus
+	 * additions and removals can happen in parallel to module unloading.
+	 */
 	idr_for_each_entry(&loop_index_idr, lo, id)
 		loop_remove(lo);
-	mutex_unlock(&loop_ctl_mutex);
-
 	idr_destroy(&loop_index_idr);
 }