do cleanup if loop_add fail.
Signed-off-by: weiping zhang <[email protected]>
---
drivers/block/loop.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index bc8e61506968..9bea70a7da16 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1987,6 +1987,14 @@ static struct miscdevice loop_misc = {
MODULE_ALIAS_MISCDEV(LOOP_CTRL_MINOR);
MODULE_ALIAS("devname:loop-control");
+static int loop_exit_cb(int id, void *ptr, void *data)
+{
+ struct loop_device *lo = ptr;
+
+ loop_remove(lo);
+ return 0;
+}
+
static int __init loop_init(void)
{
int i, nr;
@@ -2050,27 +2058,29 @@ static int __init loop_init(void)
/* pre-create number of devices given by config or max_loop */
mutex_lock(&loop_index_mutex);
- for (i = 0; i < nr; i++)
- loop_add(&lo, i);
+ for (i = 0; i < nr; i++) {
+ err = loop_add(&lo, i);
+ if (err < 0) {
+ mutex_unlock(&loop_index_mutex);
+ goto err_blk;
+ }
+ }
mutex_unlock(&loop_index_mutex);
printk(KERN_INFO "loop: module loaded\n");
return 0;
+err_blk:
+ idr_for_each(&loop_index_idr, &loop_exit_cb, NULL);
+ idr_destroy(&loop_index_idr);
+ blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range);
+ unregister_blkdev(LOOP_MAJOR, "loop");
misc_out:
misc_deregister(&loop_misc);
err_out:
return err;
}
-static int loop_exit_cb(int id, void *ptr, void *data)
-{
- struct loop_device *lo = ptr;
-
- loop_remove(lo);
- return 0;
-}
-
static void __exit loop_exit(void)
{
unsigned long range;
--
2.14.2