diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2007-05-12 16:23:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-12 19:53:02 -0400 |
commit | 07002e995638b83a6987180f43722a0eb39d4932 (patch) | |
tree | 76d09369163b040acd41c56f7c9acf2c489b40e0 | |
parent | f1d1a842d85acf34dd185027cb2c9b4fd13130ef (diff) |
fix the dynamic allocation and probe in loop.c
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: Ken Chen <kenchen@google.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/block/loop.c | 52 |
1 files changed, 12 insertions, 40 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 18cdd8c77626..e2fc4b6734cf 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 | |||
1317 | } | 1317 | } |
1318 | #endif | 1318 | #endif |
1319 | 1319 | ||
1320 | static struct loop_device *loop_find_dev(int number) | ||
1321 | { | ||
1322 | struct loop_device *lo; | ||
1323 | |||
1324 | list_for_each_entry(lo, &loop_devices, lo_list) { | ||
1325 | if (lo->lo_number == number) | ||
1326 | return lo; | ||
1327 | } | ||
1328 | return NULL; | ||
1329 | } | ||
1330 | |||
1331 | static struct loop_device *loop_init_one(int i); | ||
1332 | static int lo_open(struct inode *inode, struct file *file) | 1320 | static int lo_open(struct inode *inode, struct file *file) |
1333 | { | 1321 | { |
1334 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; | 1322 | 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) | |||
1337 | lo->lo_refcnt++; | 1325 | lo->lo_refcnt++; |
1338 | mutex_unlock(&lo->lo_ctl_mutex); | 1326 | mutex_unlock(&lo->lo_ctl_mutex); |
1339 | 1327 | ||
1340 | mutex_lock(&loop_devices_mutex); | ||
1341 | if (!loop_find_dev(lo->lo_number + 1)) | ||
1342 | loop_init_one(lo->lo_number + 1); | ||
1343 | mutex_unlock(&loop_devices_mutex); | ||
1344 | |||
1345 | return 0; | 1328 | return 0; |
1346 | } | 1329 | } |
1347 | 1330 | ||
@@ -1448,7 +1431,7 @@ out_free_queue: | |||
1448 | out_free_dev: | 1431 | out_free_dev: |
1449 | kfree(lo); | 1432 | kfree(lo); |
1450 | out: | 1433 | out: |
1451 | return ERR_PTR(-ENOMEM); | 1434 | return NULL; |
1452 | } | 1435 | } |
1453 | 1436 | ||
1454 | static void loop_del_one(struct loop_device *lo) | 1437 | static void loop_del_one(struct loop_device *lo) |
@@ -1460,36 +1443,30 @@ static void loop_del_one(struct loop_device *lo) | |||
1460 | kfree(lo); | 1443 | kfree(lo); |
1461 | } | 1444 | } |
1462 | 1445 | ||
1446 | static int loop_lock(dev_t dev, void *data) | ||
1447 | { | ||
1448 | mutex_lock(&loop_devices_mutex); | ||
1449 | return 0; | ||
1450 | } | ||
1451 | |||
1463 | static struct kobject *loop_probe(dev_t dev, int *part, void *data) | 1452 | static struct kobject *loop_probe(dev_t dev, int *part, void *data) |
1464 | { | 1453 | { |
1465 | unsigned int number = dev & MINORMASK; | 1454 | struct loop_device *lo = loop_init_one(dev & MINORMASK); |
1466 | struct loop_device *lo; | 1455 | struct kobject *kobj; |
1467 | 1456 | ||
1468 | mutex_lock(&loop_devices_mutex); | 1457 | kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM); |
1469 | lo = loop_find_dev(number); | ||
1470 | if (lo == NULL) | ||
1471 | lo = loop_init_one(number); | ||
1472 | mutex_unlock(&loop_devices_mutex); | 1458 | mutex_unlock(&loop_devices_mutex); |
1473 | 1459 | ||
1474 | *part = 0; | 1460 | *part = 0; |
1475 | if (IS_ERR(lo)) | 1461 | return kobj; |
1476 | return (void *)lo; | ||
1477 | else | ||
1478 | return &lo->lo_disk->kobj; | ||
1479 | } | 1462 | } |
1480 | 1463 | ||
1481 | static int __init loop_init(void) | 1464 | static int __init loop_init(void) |
1482 | { | 1465 | { |
1483 | struct loop_device *lo; | ||
1484 | |||
1485 | if (register_blkdev(LOOP_MAJOR, "loop")) | 1466 | if (register_blkdev(LOOP_MAJOR, "loop")) |
1486 | return -EIO; | 1467 | return -EIO; |
1487 | blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, | 1468 | blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, |
1488 | THIS_MODULE, loop_probe, NULL, NULL); | 1469 | THIS_MODULE, loop_probe, loop_lock, NULL); |
1489 | |||
1490 | lo = loop_init_one(0); | ||
1491 | if (IS_ERR(lo)) | ||
1492 | goto out; | ||
1493 | 1470 | ||
1494 | if (max_loop) { | 1471 | if (max_loop) { |
1495 | printk(KERN_INFO "loop: the max_loop option is obsolete " | 1472 | printk(KERN_INFO "loop: the max_loop option is obsolete " |
@@ -1498,11 +1475,6 @@ static int __init loop_init(void) | |||
1498 | } | 1475 | } |
1499 | printk(KERN_INFO "loop: module loaded\n"); | 1476 | printk(KERN_INFO "loop: module loaded\n"); |
1500 | return 0; | 1477 | return 0; |
1501 | |||
1502 | out: | ||
1503 | unregister_blkdev(LOOP_MAJOR, "loop"); | ||
1504 | printk(KERN_ERR "loop: ran out of memory\n"); | ||
1505 | return -ENOMEM; | ||
1506 | } | 1478 | } |
1507 | 1479 | ||
1508 | static void __exit loop_exit(void) | 1480 | static void __exit loop_exit(void) |