As it should be useful to be able to mount partition from a disk image, (and as I need a break in my bug hunting) I've modified the loop driver to mount raw disk image.
To not break original loop device, as we have to change minor numbers to manage partitions, a new parameter is added to the module: max_part which define the maximum number of partitions by loop device. By default max_part is equal to 1. The patch has been created against the current KVM kernel source tree (2.6.24-rc6). Example: # insmod drivers/block/loop.ko # ls -ld /dev/loop* drwxr-xr-x 2 root root 60 2008-01-15 18:49 /dev/loop brw-rw---- 1 root disk 7, 0 2008-01-15 19:07 /dev/loop0 brw-rw---- 1 root disk 7, 1 2008-01-15 19:07 /dev/loop1 brw-rw---- 1 root disk 7, 2 2008-01-15 19:07 /dev/loop2 brw-rw---- 1 root disk 7, 3 2008-01-15 19:07 /dev/loop3 brw-rw---- 1 root disk 7, 4 2008-01-15 19:07 /dev/loop4 brw-rw---- 1 root disk 7, 5 2008-01-15 19:07 /dev/loop5 brw-rw---- 1 root disk 7, 6 2008-01-15 19:07 /dev/loop6 brw-rw---- 1 root disk 7, 7 2008-01-15 19:07 /dev/loop7 # rmmod loop # insmod drivers/block/loop.ko max_part=16 # ls -ld /dev/loop* drwxr-xr-x 2 root root 60 2008-01-15 18:49 /dev/loop brw-rw---- 1 root disk 7, 0 2008-01-15 19:08 /dev/loop0 brw-rw---- 1 root disk 7, 16 2008-01-15 19:08 /dev/loop1 brw-rw---- 1 root disk 7, 32 2008-01-15 19:08 /dev/loop2 brw-rw---- 1 root disk 7, 48 2008-01-15 19:08 /dev/loop3 brw-rw---- 1 root disk 7, 64 2008-01-15 19:08 /dev/loop4 brw-rw---- 1 root disk 7, 80 2008-01-15 19:08 /dev/loop5 brw-rw---- 1 root disk 7, 96 2008-01-15 19:08 /dev/loop6 brw-rw---- 1 root disk 7, 112 2008-01-15 19:08 /dev/loop7 # losetup /dev/loop0 etch.img # ls -ld /dev/loop* drwxr-xr-x 2 root root 60 2008-01-15 18:49 /dev/loop brw-rw---- 1 root disk 7, 0 2008-01-15 19:08 /dev/loop0 brw-rw---- 1 root disk 7, 1 2008-01-15 19:09 /dev/loop0p1 brw-rw---- 1 root disk 7, 2 2008-01-15 19:09 /dev/loop0p2 brw-rw---- 1 root disk 7, 5 2008-01-15 19:09 /dev/loop0p5 brw-rw---- 1 root disk 7, 16 2008-01-15 19:08 /dev/loop1 brw-rw---- 1 root disk 7, 32 2008-01-15 19:08 /dev/loop2 brw-rw---- 1 root disk 7, 48 2008-01-15 19:08 /dev/loop3 brw-rw---- 1 root disk 7, 64 2008-01-15 19:08 /dev/loop4 brw-rw---- 1 root disk 7, 80 2008-01-15 19:08 /dev/loop5 brw-rw---- 1 root disk 7, 96 2008-01-15 19:08 /dev/loop6 brw-rw---- 1 root disk 7, 112 2008-01-15 19:08 /dev/loop7 # mount /dev/loop0p1 /mnt # ls /m cdrom home lib mnt root srv usr bin dev initrd lost+found opt sbin sys var boot etc initrd.img media proc selinux tmp vmlinuz # umount /mnt # losetup -d /dev/loop0 # rmmod loop All comments are welcome, perhaps it is stupid idea... Signed-off-by: Laurent Vivier <[EMAIL PROTECTED]> --- drivers/block/loop.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 files changed, 36 insertions(+), 7 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 56e2304..f601633 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -82,6 +82,8 @@ static LIST_HEAD(loop_devices); static DEFINE_MUTEX(loop_devices_mutex); +static int part_shift; + /* * Transfer functions */ @@ -819,6 +821,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, } lo->lo_state = Lo_bound; wake_up_process(lo->lo_thread); + ioctl_by_bdev(bdev, BLKRRPART, 0); return 0; out_clr: @@ -1352,6 +1355,9 @@ static struct block_device_operations lo_fops = { static int max_loop; module_param(max_loop, int, 0); MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); +static int max_part = 1; +module_param(max_part, int, 0); +MODULE_PARM_DESC(max_part, "Maximum number of partition by loop device"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); @@ -1404,7 +1410,7 @@ static struct loop_device *loop_alloc(int i) if (!lo->lo_queue) goto out_free_dev; - disk = lo->lo_disk = alloc_disk(1); + disk = lo->lo_disk = alloc_disk(1 << part_shift); if (!disk) goto out_free_queue; @@ -1414,7 +1420,7 @@ static struct loop_device *loop_alloc(int i) init_waitqueue_head(&lo->lo_event); spin_lock_init(&lo->lo_lock); disk->major = LOOP_MAJOR; - disk->first_minor = i; + disk->first_minor = i << part_shift; disk->fops = &lo_fops; disk->private_data = lo; disk->queue = lo->lo_queue; @@ -1466,7 +1472,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) struct kobject *kobj; mutex_lock(&loop_devices_mutex); - lo = loop_init_one(dev & MINORMASK); + lo = loop_init_one((dev & MINORMASK) & 0x0F); kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM); mutex_unlock(&loop_devices_mutex); @@ -1477,7 +1483,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) static int __init loop_init(void) { int i, nr; - unsigned long range; + unsigned long range, bitfield; struct loop_device *lo, *next; /* @@ -1494,7 +1500,11 @@ static int __init loop_init(void) * themselves and have kernel automatically instantiate actual * device on-demand. */ - if (max_loop > 1UL << MINORBITS) + + bitfield = max_part; + part_shift = find_first_bit(&bitfield, sizeof(bitfield)); + + if (max_loop > 1UL << (MINORBITS - part_shift)) return -EINVAL; if (max_loop) { @@ -1502,7 +1512,7 @@ static int __init loop_init(void) range = max_loop; } else { nr = 8; - range = 1UL << MINORBITS; + range = 1UL << (MINORBITS - part_shift); } if (register_blkdev(LOOP_MAJOR, "loop")) @@ -1541,7 +1551,7 @@ static void __exit loop_exit(void) unsigned long range; struct loop_device *lo, *next; - range = max_loop ? max_loop : 1UL << MINORBITS; + range = max_loop ? max_loop : 1UL << (MINORBITS - part_shift); list_for_each_entry_safe(lo, next, &loop_devices, lo_list) loop_del_one(lo); @@ -1561,4 +1571,23 @@ static int __init max_loop_setup(char *str) } __setup("max_loop=", max_loop_setup); + +static int __init max_part_setup(char *str) +{ + max_part = simple_strtol(str, NULL, 0); + if (max_part < 1) { + /* there is at least one partition */ + printk(KERN_ERR "loop: max_part cannot be lesser than 1\n"); + return 0; + } + if (max_part > MINORBITS - 1) { + /* we must keep at least one bit for loop device number */ + printk(KERN_ERR "loop: max_part cannot be greater than %d\n", + MINORBITS - 1); + return 0; + } + return 1; +} + +__setup("max_part=", max_part_setup); #endif -- 1.5.2.4 ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel