diff options
author | Ken Chen <kenchen@google.com> | 2007-06-08 16:46:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-08 20:23:32 -0400 |
commit | a47653fc2643cf61bcabba8c9ff5c45517c089ba (patch) | |
tree | b29e9c4d4bebae15c7678c6da73fd1687d6e8d37 | |
parent | c287ef1ff9296ddf707af6f9d355e1c3ffc243dd (diff) |
loop: preallocate eight loop devices
The kernel on-demand loop device instantiation breaks several user space
tools as the tools are not ready to cope with the "on-demand feature". Fix
it by instantiate default 8 loop devices and also reinstate max_loop module
parameter.
Signed-off-by: Ken Chen <kenchen@google.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/block/loop.c | 100 |
1 files changed, 82 insertions, 18 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 5526eadb6592..0ed5470d2533 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -1354,7 +1354,7 @@ static struct block_device_operations lo_fops = { | |||
1354 | */ | 1354 | */ |
1355 | static int max_loop; | 1355 | static int max_loop; |
1356 | module_param(max_loop, int, 0); | 1356 | module_param(max_loop, int, 0); |
1357 | MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand"); | 1357 | MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); |
1358 | MODULE_LICENSE("GPL"); | 1358 | MODULE_LICENSE("GPL"); |
1359 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); | 1359 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); |
1360 | 1360 | ||
@@ -1394,16 +1394,11 @@ int loop_unregister_transfer(int number) | |||
1394 | EXPORT_SYMBOL(loop_register_transfer); | 1394 | EXPORT_SYMBOL(loop_register_transfer); |
1395 | EXPORT_SYMBOL(loop_unregister_transfer); | 1395 | EXPORT_SYMBOL(loop_unregister_transfer); |
1396 | 1396 | ||
1397 | static struct loop_device *loop_init_one(int i) | 1397 | static struct loop_device *loop_alloc(int i) |
1398 | { | 1398 | { |
1399 | struct loop_device *lo; | 1399 | struct loop_device *lo; |
1400 | struct gendisk *disk; | 1400 | struct gendisk *disk; |
1401 | 1401 | ||
1402 | list_for_each_entry(lo, &loop_devices, lo_list) { | ||
1403 | if (lo->lo_number == i) | ||
1404 | return lo; | ||
1405 | } | ||
1406 | |||
1407 | lo = kzalloc(sizeof(*lo), GFP_KERNEL); | 1402 | lo = kzalloc(sizeof(*lo), GFP_KERNEL); |
1408 | if (!lo) | 1403 | if (!lo) |
1409 | goto out; | 1404 | goto out; |
@@ -1427,8 +1422,6 @@ static struct loop_device *loop_init_one(int i) | |||
1427 | disk->private_data = lo; | 1422 | disk->private_data = lo; |
1428 | disk->queue = lo->lo_queue; | 1423 | disk->queue = lo->lo_queue; |
1429 | sprintf(disk->disk_name, "loop%d", i); | 1424 | sprintf(disk->disk_name, "loop%d", i); |
1430 | add_disk(disk); | ||
1431 | list_add_tail(&lo->lo_list, &loop_devices); | ||
1432 | return lo; | 1425 | return lo; |
1433 | 1426 | ||
1434 | out_free_queue: | 1427 | out_free_queue: |
@@ -1439,15 +1432,37 @@ out: | |||
1439 | return NULL; | 1432 | return NULL; |
1440 | } | 1433 | } |
1441 | 1434 | ||
1442 | static void loop_del_one(struct loop_device *lo) | 1435 | static void loop_free(struct loop_device *lo) |
1443 | { | 1436 | { |
1444 | del_gendisk(lo->lo_disk); | ||
1445 | blk_cleanup_queue(lo->lo_queue); | 1437 | blk_cleanup_queue(lo->lo_queue); |
1446 | put_disk(lo->lo_disk); | 1438 | put_disk(lo->lo_disk); |
1447 | list_del(&lo->lo_list); | 1439 | list_del(&lo->lo_list); |
1448 | kfree(lo); | 1440 | kfree(lo); |
1449 | } | 1441 | } |
1450 | 1442 | ||
1443 | static struct loop_device *loop_init_one(int i) | ||
1444 | { | ||
1445 | struct loop_device *lo; | ||
1446 | |||
1447 | list_for_each_entry(lo, &loop_devices, lo_list) { | ||
1448 | if (lo->lo_number == i) | ||
1449 | return lo; | ||
1450 | } | ||
1451 | |||
1452 | lo = loop_alloc(i); | ||
1453 | if (lo) { | ||
1454 | add_disk(lo->lo_disk); | ||
1455 | list_add_tail(&lo->lo_list, &loop_devices); | ||
1456 | } | ||
1457 | return lo; | ||
1458 | } | ||
1459 | |||
1460 | static void loop_del_one(struct loop_device *lo) | ||
1461 | { | ||
1462 | del_gendisk(lo->lo_disk); | ||
1463 | loop_free(lo); | ||
1464 | } | ||
1465 | |||
1451 | static struct kobject *loop_probe(dev_t dev, int *part, void *data) | 1466 | static struct kobject *loop_probe(dev_t dev, int *part, void *data) |
1452 | { | 1467 | { |
1453 | struct loop_device *lo; | 1468 | struct loop_device *lo; |
@@ -1464,28 +1479,77 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) | |||
1464 | 1479 | ||
1465 | static int __init loop_init(void) | 1480 | static int __init loop_init(void) |
1466 | { | 1481 | { |
1467 | if (register_blkdev(LOOP_MAJOR, "loop")) | 1482 | int i, nr; |
1468 | return -EIO; | 1483 | unsigned long range; |
1469 | blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, | 1484 | struct loop_device *lo, *next; |
1470 | THIS_MODULE, loop_probe, NULL, NULL); | 1485 | |
1486 | /* | ||
1487 | * loop module now has a feature to instantiate underlying device | ||
1488 | * structure on-demand, provided that there is an access dev node. | ||
1489 | * However, this will not work well with user space tool that doesn't | ||
1490 | * know about such "feature". In order to not break any existing | ||
1491 | * tool, we do the following: | ||
1492 | * | ||
1493 | * (1) if max_loop is specified, create that many upfront, and this | ||
1494 | * also becomes a hard limit. | ||
1495 | * (2) if max_loop is not specified, create 8 loop device on module | ||
1496 | * load, user can further extend loop device by create dev node | ||
1497 | * themselves and have kernel automatically instantiate actual | ||
1498 | * device on-demand. | ||
1499 | */ | ||
1500 | if (max_loop > 1UL << MINORBITS) | ||
1501 | return -EINVAL; | ||
1471 | 1502 | ||
1472 | if (max_loop) { | 1503 | if (max_loop) { |
1473 | printk(KERN_INFO "loop: the max_loop option is obsolete " | 1504 | nr = max_loop; |
1474 | "and will be removed in March 2008\n"); | 1505 | range = max_loop; |
1506 | } else { | ||
1507 | nr = 8; | ||
1508 | range = 1UL << MINORBITS; | ||
1509 | } | ||
1510 | |||
1511 | if (register_blkdev(LOOP_MAJOR, "loop")) | ||
1512 | return -EIO; | ||
1475 | 1513 | ||
1514 | for (i = 0; i < nr; i++) { | ||
1515 | lo = loop_alloc(i); | ||
1516 | if (!lo) | ||
1517 | goto Enomem; | ||
1518 | list_add_tail(&lo->lo_list, &loop_devices); | ||
1476 | } | 1519 | } |
1520 | |||
1521 | /* point of no return */ | ||
1522 | |||
1523 | list_for_each_entry(lo, &loop_devices, lo_list) | ||
1524 | add_disk(lo->lo_disk); | ||
1525 | |||
1526 | blk_register_region(MKDEV(LOOP_MAJOR, 0), range, | ||
1527 | THIS_MODULE, loop_probe, NULL, NULL); | ||
1528 | |||
1477 | printk(KERN_INFO "loop: module loaded\n"); | 1529 | printk(KERN_INFO "loop: module loaded\n"); |
1478 | return 0; | 1530 | return 0; |
1531 | |||
1532 | Enomem: | ||
1533 | printk(KERN_INFO "loop: out of memory\n"); | ||
1534 | |||
1535 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) | ||
1536 | loop_free(lo); | ||
1537 | |||
1538 | unregister_blkdev(LOOP_MAJOR, "loop"); | ||
1539 | return -ENOMEM; | ||
1479 | } | 1540 | } |
1480 | 1541 | ||
1481 | static void __exit loop_exit(void) | 1542 | static void __exit loop_exit(void) |
1482 | { | 1543 | { |
1544 | unsigned long range; | ||
1483 | struct loop_device *lo, *next; | 1545 | struct loop_device *lo, *next; |
1484 | 1546 | ||
1547 | range = max_loop ? max_loop : 1UL << MINORBITS; | ||
1548 | |||
1485 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) | 1549 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) |
1486 | loop_del_one(lo); | 1550 | loop_del_one(lo); |
1487 | 1551 | ||
1488 | blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS); | 1552 | blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range); |
1489 | if (unregister_blkdev(LOOP_MAJOR, "loop")) | 1553 | if (unregister_blkdev(LOOP_MAJOR, "loop")) |
1490 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); | 1554 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
1491 | } | 1555 | } |