diff options
author | Ken Chen <kenchen@google.com> | 2007-05-08 03:28:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:07 -0400 |
commit | 73285082745045bcd64333c1fbaa88f8490f2626 (patch) | |
tree | bb45362b563332ff1e712b5f2b3b16a47b019691 | |
parent | 4f911d64e04a44c47985be30f978fb3c2efcee0c (diff) |
remove artificial software max_loop limit
Remove artificial maximum 256 loop device that can be created due to a
legacy device number limit. Searching through lkml archive, there are
several instances where users complained about the artificial limit that
the loop driver impose. There is no reason to have such limit.
This patch rid the limit entirely and make loop device and associated block
queue instantiation on demand. With on-demand instantiation, it also gives
the benefit of not wasting memory if these devices are not in use (compare
to current implementation that always create 8 loop devices), a net
improvement in both areas. This version is both tested with creation of
large number of loop devices and is compatible with existing losetup/mount
user land tools.
There are a number of people who worked on this and provided valuable
suggestions, in no particular order, by:
Jens Axboe
Jan Engelhardt
Christoph Hellwig
Thomas M
Signed-off-by: Ken Chen <kenchen@google.com>
Cc: Jan Engelhardt <jengelh@linux01.gwdg.de>
Cc: Christoph Hellwig <hch@lst.de>
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 | 184 | ||||
-rw-r--r-- | include/linux/loop.h | 2 |
2 files changed, 112 insertions, 74 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 0d4ccd4a0957..af6d7274a7cc 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -77,9 +77,8 @@ | |||
77 | 77 | ||
78 | #include <asm/uaccess.h> | 78 | #include <asm/uaccess.h> |
79 | 79 | ||
80 | static int max_loop = 8; | 80 | static LIST_HEAD(loop_devices); |
81 | static struct loop_device *loop_dev; | 81 | static DEFINE_MUTEX(loop_devices_mutex); |
82 | static struct gendisk **disks; | ||
83 | 82 | ||
84 | /* | 83 | /* |
85 | * Transfer functions | 84 | * Transfer functions |
@@ -183,7 +182,7 @@ figure_loop_size(struct loop_device *lo) | |||
183 | if (unlikely((loff_t)x != size)) | 182 | if (unlikely((loff_t)x != size)) |
184 | return -EFBIG; | 183 | return -EFBIG; |
185 | 184 | ||
186 | set_capacity(disks[lo->lo_number], x); | 185 | set_capacity(lo->lo_disk, x); |
187 | return 0; | 186 | return 0; |
188 | } | 187 | } |
189 | 188 | ||
@@ -812,7 +811,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, | |||
812 | lo->lo_queue->queuedata = lo; | 811 | lo->lo_queue->queuedata = lo; |
813 | lo->lo_queue->unplug_fn = loop_unplug; | 812 | lo->lo_queue->unplug_fn = loop_unplug; |
814 | 813 | ||
815 | set_capacity(disks[lo->lo_number], size); | 814 | set_capacity(lo->lo_disk, size); |
816 | bd_set_size(bdev, size << 9); | 815 | bd_set_size(bdev, size << 9); |
817 | 816 | ||
818 | set_blocksize(bdev, lo_blocksize); | 817 | set_blocksize(bdev, lo_blocksize); |
@@ -832,7 +831,7 @@ out_clr: | |||
832 | lo->lo_device = NULL; | 831 | lo->lo_device = NULL; |
833 | lo->lo_backing_file = NULL; | 832 | lo->lo_backing_file = NULL; |
834 | lo->lo_flags = 0; | 833 | lo->lo_flags = 0; |
835 | set_capacity(disks[lo->lo_number], 0); | 834 | set_capacity(lo->lo_disk, 0); |
836 | invalidate_bdev(bdev); | 835 | invalidate_bdev(bdev); |
837 | bd_set_size(bdev, 0); | 836 | bd_set_size(bdev, 0); |
838 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask); | 837 | mapping_set_gfp_mask(mapping, lo->old_gfp_mask); |
@@ -918,7 +917,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
918 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); | 917 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); |
919 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); | 918 | memset(lo->lo_file_name, 0, LO_NAME_SIZE); |
920 | invalidate_bdev(bdev); | 919 | invalidate_bdev(bdev); |
921 | set_capacity(disks[lo->lo_number], 0); | 920 | set_capacity(lo->lo_disk, 0); |
922 | bd_set_size(bdev, 0); | 921 | bd_set_size(bdev, 0); |
923 | mapping_set_gfp_mask(filp->f_mapping, gfp); | 922 | mapping_set_gfp_mask(filp->f_mapping, gfp); |
924 | lo->lo_state = Lo_unbound; | 923 | lo->lo_state = Lo_unbound; |
@@ -1322,6 +1321,18 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a | |||
1322 | } | 1321 | } |
1323 | #endif | 1322 | #endif |
1324 | 1323 | ||
1324 | static struct loop_device *loop_find_dev(int number) | ||
1325 | { | ||
1326 | struct loop_device *lo; | ||
1327 | |||
1328 | list_for_each_entry(lo, &loop_devices, lo_list) { | ||
1329 | if (lo->lo_number == number) | ||
1330 | return lo; | ||
1331 | } | ||
1332 | return NULL; | ||
1333 | } | ||
1334 | |||
1335 | static struct loop_device *loop_init_one(int i); | ||
1325 | static int lo_open(struct inode *inode, struct file *file) | 1336 | static int lo_open(struct inode *inode, struct file *file) |
1326 | { | 1337 | { |
1327 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; | 1338 | struct loop_device *lo = inode->i_bdev->bd_disk->private_data; |
@@ -1330,6 +1341,11 @@ static int lo_open(struct inode *inode, struct file *file) | |||
1330 | lo->lo_refcnt++; | 1341 | lo->lo_refcnt++; |
1331 | mutex_unlock(&lo->lo_ctl_mutex); | 1342 | mutex_unlock(&lo->lo_ctl_mutex); |
1332 | 1343 | ||
1344 | mutex_lock(&loop_devices_mutex); | ||
1345 | if (!loop_find_dev(lo->lo_number + 1)) | ||
1346 | loop_init_one(lo->lo_number + 1); | ||
1347 | mutex_unlock(&loop_devices_mutex); | ||
1348 | |||
1333 | return 0; | 1349 | return 0; |
1334 | } | 1350 | } |
1335 | 1351 | ||
@@ -1357,8 +1373,9 @@ static struct block_device_operations lo_fops = { | |||
1357 | /* | 1373 | /* |
1358 | * And now the modules code and kernel interface. | 1374 | * And now the modules code and kernel interface. |
1359 | */ | 1375 | */ |
1376 | static int max_loop; | ||
1360 | module_param(max_loop, int, 0); | 1377 | module_param(max_loop, int, 0); |
1361 | MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)"); | 1378 | MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand"); |
1362 | MODULE_LICENSE("GPL"); | 1379 | MODULE_LICENSE("GPL"); |
1363 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); | 1380 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); |
1364 | 1381 | ||
@@ -1383,7 +1400,7 @@ int loop_unregister_transfer(int number) | |||
1383 | 1400 | ||
1384 | xfer_funcs[n] = NULL; | 1401 | xfer_funcs[n] = NULL; |
1385 | 1402 | ||
1386 | for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { | 1403 | list_for_each_entry(lo, &loop_devices, lo_list) { |
1387 | mutex_lock(&lo->lo_ctl_mutex); | 1404 | mutex_lock(&lo->lo_ctl_mutex); |
1388 | 1405 | ||
1389 | if (lo->lo_encryption == xfer) | 1406 | if (lo->lo_encryption == xfer) |
@@ -1398,91 +1415,110 @@ int loop_unregister_transfer(int number) | |||
1398 | EXPORT_SYMBOL(loop_register_transfer); | 1415 | EXPORT_SYMBOL(loop_register_transfer); |
1399 | EXPORT_SYMBOL(loop_unregister_transfer); | 1416 | EXPORT_SYMBOL(loop_unregister_transfer); |
1400 | 1417 | ||
1401 | static int __init loop_init(void) | 1418 | static struct loop_device *loop_init_one(int i) |
1419 | { | ||
1420 | struct loop_device *lo; | ||
1421 | struct gendisk *disk; | ||
1422 | |||
1423 | lo = kzalloc(sizeof(*lo), GFP_KERNEL); | ||
1424 | if (!lo) | ||
1425 | goto out; | ||
1426 | |||
1427 | lo->lo_queue = blk_alloc_queue(GFP_KERNEL); | ||
1428 | if (!lo->lo_queue) | ||
1429 | goto out_free_dev; | ||
1430 | |||
1431 | disk = lo->lo_disk = alloc_disk(1); | ||
1432 | if (!disk) | ||
1433 | goto out_free_queue; | ||
1434 | |||
1435 | mutex_init(&lo->lo_ctl_mutex); | ||
1436 | lo->lo_number = i; | ||
1437 | lo->lo_thread = NULL; | ||
1438 | init_waitqueue_head(&lo->lo_event); | ||
1439 | spin_lock_init(&lo->lo_lock); | ||
1440 | disk->major = LOOP_MAJOR; | ||
1441 | disk->first_minor = i; | ||
1442 | disk->fops = &lo_fops; | ||
1443 | disk->private_data = lo; | ||
1444 | disk->queue = lo->lo_queue; | ||
1445 | sprintf(disk->disk_name, "loop%d", i); | ||
1446 | add_disk(disk); | ||
1447 | list_add_tail(&lo->lo_list, &loop_devices); | ||
1448 | return lo; | ||
1449 | |||
1450 | out_free_queue: | ||
1451 | blk_cleanup_queue(lo->lo_queue); | ||
1452 | out_free_dev: | ||
1453 | kfree(lo); | ||
1454 | out: | ||
1455 | return ERR_PTR(-ENOMEM); | ||
1456 | } | ||
1457 | |||
1458 | static void loop_del_one(struct loop_device *lo) | ||
1402 | { | 1459 | { |
1403 | int i; | 1460 | del_gendisk(lo->lo_disk); |
1461 | blk_cleanup_queue(lo->lo_queue); | ||
1462 | put_disk(lo->lo_disk); | ||
1463 | list_del(&lo->lo_list); | ||
1464 | kfree(lo); | ||
1465 | } | ||
1404 | 1466 | ||
1405 | if (max_loop < 1 || max_loop > 256) { | 1467 | static struct kobject *loop_probe(dev_t dev, int *part, void *data) |
1406 | printk(KERN_WARNING "loop: invalid max_loop (must be between" | 1468 | { |
1407 | " 1 and 256), using default (8)\n"); | 1469 | unsigned int number = dev & MINORMASK; |
1408 | max_loop = 8; | 1470 | struct loop_device *lo; |
1409 | } | 1471 | |
1472 | mutex_lock(&loop_devices_mutex); | ||
1473 | lo = loop_find_dev(number); | ||
1474 | if (lo == NULL) | ||
1475 | lo = loop_init_one(number); | ||
1476 | mutex_unlock(&loop_devices_mutex); | ||
1477 | |||
1478 | *part = 0; | ||
1479 | if (IS_ERR(lo)) | ||
1480 | return (void *)lo; | ||
1481 | else | ||
1482 | return &lo->lo_disk->kobj; | ||
1483 | } | ||
1484 | |||
1485 | static int __init loop_init(void) | ||
1486 | { | ||
1487 | struct loop_device *lo; | ||
1410 | 1488 | ||
1411 | if (register_blkdev(LOOP_MAJOR, "loop")) | 1489 | if (register_blkdev(LOOP_MAJOR, "loop")) |
1412 | return -EIO; | 1490 | return -EIO; |
1491 | blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, | ||
1492 | THIS_MODULE, loop_probe, NULL, NULL); | ||
1413 | 1493 | ||
1414 | loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL); | 1494 | lo = loop_init_one(0); |
1415 | if (!loop_dev) | 1495 | if (IS_ERR(lo)) |
1416 | goto out_mem1; | 1496 | goto out; |
1417 | memset(loop_dev, 0, max_loop * sizeof(struct loop_device)); | ||
1418 | 1497 | ||
1419 | disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL); | 1498 | if (max_loop) { |
1420 | if (!disks) | 1499 | printk(KERN_INFO "loop: the max_loop option is obsolete " |
1421 | goto out_mem2; | 1500 | "and will be removed in March 2008\n"); |
1422 | 1501 | ||
1423 | for (i = 0; i < max_loop; i++) { | ||
1424 | disks[i] = alloc_disk(1); | ||
1425 | if (!disks[i]) | ||
1426 | goto out_mem3; | ||
1427 | } | 1502 | } |
1428 | 1503 | printk(KERN_INFO "loop: module loaded\n"); | |
1429 | for (i = 0; i < max_loop; i++) { | ||
1430 | struct loop_device *lo = &loop_dev[i]; | ||
1431 | struct gendisk *disk = disks[i]; | ||
1432 | |||
1433 | memset(lo, 0, sizeof(*lo)); | ||
1434 | lo->lo_queue = blk_alloc_queue(GFP_KERNEL); | ||
1435 | if (!lo->lo_queue) | ||
1436 | goto out_mem4; | ||
1437 | mutex_init(&lo->lo_ctl_mutex); | ||
1438 | lo->lo_number = i; | ||
1439 | lo->lo_thread = NULL; | ||
1440 | init_waitqueue_head(&lo->lo_event); | ||
1441 | spin_lock_init(&lo->lo_lock); | ||
1442 | disk->major = LOOP_MAJOR; | ||
1443 | disk->first_minor = i; | ||
1444 | disk->fops = &lo_fops; | ||
1445 | sprintf(disk->disk_name, "loop%d", i); | ||
1446 | disk->private_data = lo; | ||
1447 | disk->queue = lo->lo_queue; | ||
1448 | } | ||
1449 | |||
1450 | /* We cannot fail after we call this, so another loop!*/ | ||
1451 | for (i = 0; i < max_loop; i++) | ||
1452 | add_disk(disks[i]); | ||
1453 | printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop); | ||
1454 | return 0; | 1504 | return 0; |
1455 | 1505 | ||
1456 | out_mem4: | 1506 | out: |
1457 | while (i--) | ||
1458 | blk_cleanup_queue(loop_dev[i].lo_queue); | ||
1459 | i = max_loop; | ||
1460 | out_mem3: | ||
1461 | while (i--) | ||
1462 | put_disk(disks[i]); | ||
1463 | kfree(disks); | ||
1464 | out_mem2: | ||
1465 | kfree(loop_dev); | ||
1466 | out_mem1: | ||
1467 | unregister_blkdev(LOOP_MAJOR, "loop"); | 1507 | unregister_blkdev(LOOP_MAJOR, "loop"); |
1468 | printk(KERN_ERR "loop: ran out of memory\n"); | 1508 | printk(KERN_ERR "loop: ran out of memory\n"); |
1469 | return -ENOMEM; | 1509 | return -ENOMEM; |
1470 | } | 1510 | } |
1471 | 1511 | ||
1472 | static void loop_exit(void) | 1512 | static void __exit loop_exit(void) |
1473 | { | 1513 | { |
1474 | int i; | 1514 | struct loop_device *lo, *next; |
1475 | 1515 | ||
1476 | for (i = 0; i < max_loop; i++) { | 1516 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) |
1477 | del_gendisk(disks[i]); | 1517 | loop_del_one(lo); |
1478 | blk_cleanup_queue(loop_dev[i].lo_queue); | 1518 | |
1479 | put_disk(disks[i]); | 1519 | blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS); |
1480 | } | ||
1481 | if (unregister_blkdev(LOOP_MAJOR, "loop")) | 1520 | if (unregister_blkdev(LOOP_MAJOR, "loop")) |
1482 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); | 1521 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
1483 | |||
1484 | kfree(disks); | ||
1485 | kfree(loop_dev); | ||
1486 | } | 1522 | } |
1487 | 1523 | ||
1488 | module_init(loop_init); | 1524 | module_init(loop_init); |
diff --git a/include/linux/loop.h b/include/linux/loop.h index 191a595055f0..0b99b31f017b 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h | |||
@@ -64,6 +64,8 @@ struct loop_device { | |||
64 | wait_queue_head_t lo_event; | 64 | wait_queue_head_t lo_event; |
65 | 65 | ||
66 | request_queue_t *lo_queue; | 66 | request_queue_t *lo_queue; |
67 | struct gendisk *lo_disk; | ||
68 | struct list_head lo_list; | ||
67 | }; | 69 | }; |
68 | 70 | ||
69 | #endif /* __KERNEL__ */ | 71 | #endif /* __KERNEL__ */ |