From 07002e995638b83a6987180f43722a0eb39d4932 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 12 May 2007 16:23:15 -0400 Subject: fix the dynamic allocation and probe in loop.c Signed-off-by: Al Viro Acked-by: Ken Chen Signed-off-by: Linus Torvalds --- drivers/block/loop.c | 52 ++++++++++++---------------------------------------- 1 file changed, 12 insertions(+), 40 deletions(-) (limited to 'drivers/block/loop.c') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 18cdd8c..e2fc4b6 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1317,18 +1317,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a } #endif -static struct loop_device *loop_find_dev(int number) -{ - struct loop_device *lo; - - list_for_each_entry(lo, &loop_devices, lo_list) { - if (lo->lo_number == number) - return lo; - } - return NULL; -} - -static struct loop_device *loop_init_one(int i); static int lo_open(struct inode *inode, struct file *file) { struct loop_device *lo = inode->i_bdev->bd_disk->private_data; @@ -1337,11 +1325,6 @@ static int lo_open(struct inode *inode, struct file *file) lo->lo_refcnt++; mutex_unlock(&lo->lo_ctl_mutex); - mutex_lock(&loop_devices_mutex); - if (!loop_find_dev(lo->lo_number + 1)) - loop_init_one(lo->lo_number + 1); - mutex_unlock(&loop_devices_mutex); - return 0; } @@ -1448,7 +1431,7 @@ out_free_queue: out_free_dev: kfree(lo); out: - return ERR_PTR(-ENOMEM); + return NULL; } static void loop_del_one(struct loop_device *lo) @@ -1460,36 +1443,30 @@ static void loop_del_one(struct loop_device *lo) kfree(lo); } +static int loop_lock(dev_t dev, void *data) +{ + mutex_lock(&loop_devices_mutex); + return 0; +} + static struct kobject *loop_probe(dev_t dev, int *part, void *data) { - unsigned int number = dev & MINORMASK; - struct loop_device *lo; + struct loop_device *lo = loop_init_one(dev & MINORMASK); + struct kobject *kobj; - mutex_lock(&loop_devices_mutex); - lo = loop_find_dev(number); - if (lo == NULL) - lo = loop_init_one(number); + kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM); mutex_unlock(&loop_devices_mutex); *part = 0; - if (IS_ERR(lo)) - return (void *)lo; - else - return &lo->lo_disk->kobj; + return kobj; } static int __init loop_init(void) { - struct loop_device *lo; - if (register_blkdev(LOOP_MAJOR, "loop")) return -EIO; blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, - THIS_MODULE, loop_probe, NULL, NULL); - - lo = loop_init_one(0); - if (IS_ERR(lo)) - goto out; + THIS_MODULE, loop_probe, loop_lock, NULL); if (max_loop) { printk(KERN_INFO "loop: the max_loop option is obsolete " @@ -1498,11 +1475,6 @@ static int __init loop_init(void) } printk(KERN_INFO "loop: module loaded\n"); return 0; - -out: - unregister_blkdev(LOOP_MAJOR, "loop"); - printk(KERN_ERR "loop: ran out of memory\n"); - return -ENOMEM; } static void __exit loop_exit(void) -- cgit v1.1