diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d58d68f3c7cd..3045bcb9f7ed 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -2079,6 +2079,7 @@ static const struct blk_mq_ops loop_mq_ops = { .complete = lo_complete_rq, }; +/* Must be called with loop_ctl_mutex held. */ static int loop_add(struct loop_device **l, int i) { struct loop_device *lo; @@ -2186,6 +2187,7 @@ static int loop_add(struct loop_device **l, int i) return err; } +/* Must not be called with loop_ctl_mutex or lo->lo_mutex held. */ static void loop_remove(struct loop_device *lo) { del_gendisk(lo->lo_disk); @@ -2288,8 +2290,9 @@ static long loop_control_ioctl(struct file *file, unsigned int cmd, lo->lo_disk->private_data = NULL; mutex_unlock(&lo->lo_mutex); idr_remove(&loop_index_idr, lo->lo_number); + mutex_unlock(&loop_ctl_mutex); loop_remove(lo); - break; + return 0; case LOOP_CTL_GET_FREE: ret = loop_lookup(&lo, -1); if (ret >= 0) @@ -2397,16 +2400,12 @@ static int loop_exit_cb(int id, void *ptr, void *data) static void __exit loop_exit(void) { - mutex_lock(&loop_ctl_mutex); - idr_for_each(&loop_index_idr, &loop_exit_cb, NULL); idr_destroy(&loop_index_idr); unregister_blkdev(LOOP_MAJOR, "loop"); misc_deregister(&loop_misc); - - mutex_unlock(&loop_ctl_mutex); } module_init(loop_init);