LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH][RESEND][v3] Modify loop device to be able to manage partitions of the disk image
@ 2008-03-18 12:19 Laurent Vivier
  2008-03-18 20:54 ` Andrew Morton
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Laurent Vivier @ 2008-03-18 12:19 UTC (permalink / raw)
  To: axboe; +Cc: linux-kernel, akpm, Laurent Vivier

v3 is an updated version of v2, replacing a "%d" by a "%lu".

This patch allows to use loop device with partitionned disk image.

Original behavior of loop is not modified.

A new parameter is introduced to define how many partition we want to be
able to manage per loop device. This parameter is "loop_max_part".

For instance, to manage 63 partitions / loop device, we will do:
# modprobe loop loop_max_part=63
# ls -l /dev/loop?
brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7

And to attach a raw partitionned disk image, the original losetup is used:

# losetup -f etch.img
EXT3 FS on loop0p1, internal journal
EXT3-fs: mounted filesystem with ordered data mode.
loop: module loaded
 loop0: p1 p2 < p5 >
# ls -l /dev/loop?*
brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
brw-rw---- 1 root disk 7,   1 2008-03-05 14:57 /dev/loop0p1
brw-rw---- 1 root disk 7,   2 2008-03-05 14:57 /dev/loop0p2
brw-rw---- 1 root disk 7,   5 2008-03-05 14:57 /dev/loop0p5
brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
# mount /dev/loop0p1 /mnt
kjournald starting.  Commit interval 5 seconds
EXT3 FS on loop0p1, internal journal
EXT3-fs: mounted filesystem with ordered data mode.
# ls /mnt
bench  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

Of course, the same behavior can be done using kpartx on a loop device,
but modifying loop avoids to stack several layers of block device (loop +
device mapper), this is a very light modification (40% of modifications
are to manage the new parameter).

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
 Documentation/kernel-parameters.txt |    4 +++
 drivers/block/loop.c                |   39 ++++++++++++++++++++++++++++++----
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 9a5b665..7f2fd52 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1075,6 +1075,10 @@ and is between 256 and 4096 characters. It is defined in the file
 			be mounted
 			Format: <1-256>
 
+	loop_max_part=	[LOOP] Maximum number of partitions per loopback device.
+			Should be greater than 0, the maximum value depends
+			on max_loop.
+
 	maxcpus=	[SMP] Maximum number of processors that	an SMP kernel
 			should make use of.  maxcpus=n : n >= 0 limits the
 			kernel to using 'n' processors.  n=0 is a special case,
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 91ebb00..16b2aa6 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -82,6 +82,9 @@
 static LIST_HEAD(loop_devices);
 static DEFINE_MUTEX(loop_devices_mutex);
 
+static int loop_max_part;
+static int part_shift;
+
 /*
  * Transfer functions
  */
@@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
 		goto out_putf;
 
 	fput(old_file);
+	if (loop_max_part > 0)
+		ioctl_by_bdev(bdev, BLKRRPART, 0);
 	return 0;
 
  out_putf:
@@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
 	}
 	lo->lo_state = Lo_bound;
 	wake_up_process(lo->lo_thread);
+	if (loop_max_part > 0)
+		ioctl_by_bdev(bdev, BLKRRPART, 0);
 	return 0;
 
 out_clr:
@@ -1360,6 +1367,8 @@ 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");
+module_param(loop_max_part, int, 0);
+MODULE_PARM_DESC(loop_max_part, "Maximum number of partitions per loop device");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
@@ -1412,7 +1421,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;
 
@@ -1422,7 +1431,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;
@@ -1502,7 +1511,12 @@ static int __init loop_init(void)
 	 *     themselves and have kernel automatically instantiate actual
 	 *     device on-demand.
 	 */
-	if (max_loop > 1UL << MINORBITS)
+
+	part_shift = 0;
+	if (loop_max_part > 0)
+		part_shift = fls(loop_max_part);
+
+	if (max_loop > 1UL << (MINORBITS - part_shift))
 		return -EINVAL;
 
 	if (max_loop) {
@@ -1510,7 +1524,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"))
@@ -1549,7 +1563,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);
@@ -1569,4 +1583,19 @@ static int __init max_loop_setup(char *str)
 }
 
 __setup("max_loop=", max_loop_setup);
+
+static int __init max_part_setup(char *str)
+{
+	loop_max_part = simple_strtol(str, NULL, 0);
+	if (loop_max_part > (1UL << (MINORBITS - 1))) {
+		/* we must keep at least one bit for loop device number */
+		printk(KERN_ERR
+			"loop: loop_max_part cannot be greater than %lu\n",
+			1UL << (MINORBITS - 1));
+		return 0;
+	}
+	return 1;
+}
+
+__setup("loop_max_part=", max_part_setup);
 #endif
-- 
1.5.2.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH][RESEND][v3] Modify loop device to be able to manage partitions of the disk image
  2008-03-18 12:19 [PATCH][RESEND][v3] Modify loop device to be able to manage partitions of the disk image Laurent Vivier
@ 2008-03-18 20:54 ` Andrew Morton
  2008-03-19 12:36 ` [PATCH][v4] " Laurent Vivier
  2008-03-19 20:24 ` [PATCH][RESEND][v3] " Bill Davidsen
  2 siblings, 0 replies; 14+ messages in thread
From: Andrew Morton @ 2008-03-18 20:54 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: axboe, linux-kernel, Laurent.Vivier

On Tue, 18 Mar 2008 13:19:20 +0100
Laurent Vivier <Laurent.Vivier@bull.net> wrote:

> v3 is an updated version of v2, replacing a "%d" by a "%lu".
> 
> This patch allows to use loop device with partitionned disk image.
> 
> Original behavior of loop is not modified.
> 
> A new parameter is introduced to define how many partition we want to be
> able to manage per loop device. This parameter is "loop_max_part".
> 
> For instance, to manage 63 partitions / loop device, we will do:
> # modprobe loop loop_max_part=63
> # ls -l /dev/loop?
> brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> 
> And to attach a raw partitionned disk image, the original losetup is used:
> 
> # losetup -f etch.img
> EXT3 FS on loop0p1, internal journal
> EXT3-fs: mounted filesystem with ordered data mode.
> loop: module loaded
>  loop0: p1 p2 < p5 >
> # ls -l /dev/loop?*
> brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> brw-rw---- 1 root disk 7,   1 2008-03-05 14:57 /dev/loop0p1
> brw-rw---- 1 root disk 7,   2 2008-03-05 14:57 /dev/loop0p2
> brw-rw---- 1 root disk 7,   5 2008-03-05 14:57 /dev/loop0p5
> brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> # mount /dev/loop0p1 /mnt
> kjournald starting.  Commit interval 5 seconds
> EXT3 FS on loop0p1, internal journal
> EXT3-fs: mounted filesystem with ordered data mode.
> # ls /mnt
> bench  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
> 
> Of course, the same behavior can be done using kpartx on a loop device,
> but modifying loop avoids to stack several layers of block device (loop +
> device mapper), this is a very light modification (40% of modifications
> are to manage the new parameter).
> 
> ...
>
> index 9a5b665..7f2fd52 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -1075,6 +1075,10 @@ and is between 256 and 4096 characters. It is defined in the file
>  			be mounted
>  			Format: <1-256>
>  
> +	loop_max_part=	[LOOP] Maximum number of partitions per loopback device.
> +			Should be greater than 0, the maximum value depends
> +			on max_loop.
> +

This shouldn't be needed.

> @@ -1360,6 +1367,8 @@ 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");
> +module_param(loop_max_part, int, 0);
> +MODULE_PARM_DESC(loop_max_part, "Maximum number of partitions per loop device");

Because this module_param() gives us the loop.loop_max_part=N kernel boot
parameter.

Given which, I think we could rename it to just "max_part":

	modprobe loop max_part=4

	kernel vmlinuz-... loop.max_part=4

?

>  __setup("max_loop=", max_loop_setup);

That could go away in the same way, but we have a back-compat problem.

> +
> +static int __init max_part_setup(char *str)
> +{
> +	loop_max_part = simple_strtol(str, NULL, 0);
> +	if (loop_max_part > (1UL << (MINORBITS - 1))) {
> +		/* we must keep at least one bit for loop device number */
> +		printk(KERN_ERR
> +			"loop: loop_max_part cannot be greater than %lu\n",
> +			1UL << (MINORBITS - 1));
> +		return 0;
> +	}
> +	return 1;
> +}
> +
> +__setup("loop_max_part=", max_part_setup);


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH][v4]  Modify loop device to be able to manage partitions of the disk image
  2008-03-18 12:19 [PATCH][RESEND][v3] Modify loop device to be able to manage partitions of the disk image Laurent Vivier
  2008-03-18 20:54 ` Andrew Morton
@ 2008-03-19 12:36 ` Laurent Vivier
  2008-03-19 20:11   ` Randy Dunlap
  2008-03-19 20:24 ` [PATCH][RESEND][v3] " Bill Davidsen
  2 siblings, 1 reply; 14+ messages in thread
From: Laurent Vivier @ 2008-03-19 12:36 UTC (permalink / raw)
  To: akpm; +Cc: jens.axboe, linux-kernel, Laurent Vivier

This patch allows to use loop device with partitionned disk image.

Original behavior of loop is not modified.

A new parameter is introduced to define how many partition we want to be
able to manage per loop device. This parameter is "max_part".

For instance, to manage 63 partitions / loop device, we will do:
# modprobe loop max_part=63
# ls -l /dev/loop?*
brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7

And to attach a raw partitionned disk image, the original losetup is used:

# losetup -f etch.img
# ls -l /dev/loop?*
brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
brw-rw---- 1 root disk 7,   1 2008-03-05 14:57 /dev/loop0p1
brw-rw---- 1 root disk 7,   2 2008-03-05 14:57 /dev/loop0p2
brw-rw---- 1 root disk 7,   5 2008-03-05 14:57 /dev/loop0p5
brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
# mount /dev/loop0p1 /mnt
# ls /mnt
bench  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

Of course, the same behavior can be done using kpartx on a loop device,
but modifying loop avoids to stack several layers of block device (loop +
device mapper), this is a very light modification (40% of modifications
are to manage the new parameter).

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
 drivers/block/loop.c |   26 +++++++++++++++++++++-----
 1 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 91ebb00..f7f1635 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -82,6 +82,9 @@
 static LIST_HEAD(loop_devices);
 static DEFINE_MUTEX(loop_devices_mutex);
 
+static int max_part;
+static int part_shift;
+
 /*
  * Transfer functions
  */
@@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
 		goto out_putf;
 
 	fput(old_file);
+	if (max_part > 0)
+		ioctl_by_bdev(bdev, BLKRRPART, 0);
 	return 0;
 
  out_putf:
@@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
 	}
 	lo->lo_state = Lo_bound;
 	wake_up_process(lo->lo_thread);
+	if (max_part > 0)
+		ioctl_by_bdev(bdev, BLKRRPART, 0);
 	return 0;
 
 out_clr:
@@ -919,6 +926,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
 	fput(filp);
 	/* This is safe: open() is still holding a reference. */
 	module_put(THIS_MODULE);
+	if (max_part > 0)
+		ioctl_by_bdev(bdev, BLKRRPART, 0);
 	return 0;
 }
 
@@ -1360,6 +1369,8 @@ 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");
+module_param(max_part, int, 0);
+MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
@@ -1412,7 +1423,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;
 
@@ -1422,7 +1433,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;
@@ -1502,7 +1513,12 @@ static int __init loop_init(void)
 	 *     themselves and have kernel automatically instantiate actual
 	 *     device on-demand.
 	 */
-	if (max_loop > 1UL << MINORBITS)
+
+	part_shift = 0;
+	if (max_part > 0)
+		part_shift = fls(max_part);
+
+	if (max_loop > 1UL << (MINORBITS - part_shift))
 		return -EINVAL;
 
 	if (max_loop) {
@@ -1510,7 +1526,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"))
@@ -1549,7 +1565,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);
-- 
1.5.2.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH][v4]  Modify loop device to be able to manage partitions of the disk image
  2008-03-19 12:36 ` [PATCH][v4] " Laurent Vivier
@ 2008-03-19 20:11   ` Randy Dunlap
  2008-03-19 20:24     ` Laurent Vivier
  0 siblings, 1 reply; 14+ messages in thread
From: Randy Dunlap @ 2008-03-19 20:11 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: akpm, jens.axboe, linux-kernel

On Wed, 19 Mar 2008 13:36:07 +0100 Laurent Vivier wrote:

> This patch allows to use loop device with partitionned disk image.
> 
> Original behavior of loop is not modified.
> 
> A new parameter is introduced to define how many partition we want to be
> able to manage per loop device. This parameter is "max_part".

What happened to the update to Documentation/kernel-parameters.txt
that was in v3?


> For instance, to manage 63 partitions / loop device, we will do:
> # modprobe loop max_part=63
> # ls -l /dev/loop?*
> brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> 
> And to attach a raw partitionned disk image, the original losetup is used:
> 
> # losetup -f etch.img
> # ls -l /dev/loop?*
> brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> brw-rw---- 1 root disk 7,   1 2008-03-05 14:57 /dev/loop0p1
> brw-rw---- 1 root disk 7,   2 2008-03-05 14:57 /dev/loop0p2
> brw-rw---- 1 root disk 7,   5 2008-03-05 14:57 /dev/loop0p5
> brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> # mount /dev/loop0p1 /mnt
> # ls /mnt
> bench  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
> 
> Of course, the same behavior can be done using kpartx on a loop device,
> but modifying loop avoids to stack several layers of block device (loop +
> device mapper), this is a very light modification (40% of modifications
> are to manage the new parameter).
> 
> Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
> ---
>  drivers/block/loop.c |   26 +++++++++++++++++++++-----
>  1 files changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> index 91ebb00..f7f1635 100644
> --- a/drivers/block/loop.c
> +++ b/drivers/block/loop.c
> @@ -82,6 +82,9 @@
>  static LIST_HEAD(loop_devices);
>  static DEFINE_MUTEX(loop_devices_mutex);
>  
> +static int max_part;
> +static int part_shift;
> +
>  /*
>   * Transfer functions
>   */
> @@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
>  		goto out_putf;
>  
>  	fput(old_file);
> +	if (max_part > 0)
> +		ioctl_by_bdev(bdev, BLKRRPART, 0);
>  	return 0;
>  
>   out_putf:
> @@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
>  	}
>  	lo->lo_state = Lo_bound;
>  	wake_up_process(lo->lo_thread);
> +	if (max_part > 0)
> +		ioctl_by_bdev(bdev, BLKRRPART, 0);
>  	return 0;
>  
>  out_clr:
> @@ -919,6 +926,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
>  	fput(filp);
>  	/* This is safe: open() is still holding a reference. */
>  	module_put(THIS_MODULE);
> +	if (max_part > 0)
> +		ioctl_by_bdev(bdev, BLKRRPART, 0);
>  	return 0;
>  }
>  
> @@ -1360,6 +1369,8 @@ 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");
> +module_param(max_part, int, 0);
> +MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");
>  MODULE_LICENSE("GPL");
>  MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
>  
> @@ -1412,7 +1423,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;
>  
> @@ -1422,7 +1433,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;
> @@ -1502,7 +1513,12 @@ static int __init loop_init(void)
>  	 *     themselves and have kernel automatically instantiate actual
>  	 *     device on-demand.
>  	 */
> -	if (max_loop > 1UL << MINORBITS)
> +
> +	part_shift = 0;
> +	if (max_part > 0)
> +		part_shift = fls(max_part);
> +
> +	if (max_loop > 1UL << (MINORBITS - part_shift))
>  		return -EINVAL;
>  
>  	if (max_loop) {
> @@ -1510,7 +1526,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"))
> @@ -1549,7 +1565,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);
> -- 


---
~Randy

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][RESEND][v3] Modify loop device to be able to manage partitions of the disk image
  2008-03-18 12:19 [PATCH][RESEND][v3] Modify loop device to be able to manage partitions of the disk image Laurent Vivier
  2008-03-18 20:54 ` Andrew Morton
  2008-03-19 12:36 ` [PATCH][v4] " Laurent Vivier
@ 2008-03-19 20:24 ` Bill Davidsen
  2008-03-19 20:32   ` Laurent Vivier
  2 siblings, 1 reply; 14+ messages in thread
From: Bill Davidsen @ 2008-03-19 20:24 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: axboe, linux-kernel, akpm

Laurent Vivier wrote:
> v3 is an updated version of v2, replacing a "%d" by a "%lu".
> 
> This patch allows to use loop device with partitionned disk image.
> 
How does this compare in overhead to using nbd?

> Original behavior of loop is not modified.
> 
> A new parameter is introduced to define how many partition we want to be
> able to manage per loop device. This parameter is "loop_max_part".
> 
> For instance, to manage 63 partitions / loop device, we will do:
> # modprobe loop loop_max_part=63
> # ls -l /dev/loop?
> brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> 
> And to attach a raw partitionned disk image, the original losetup is used:
> 
> # losetup -f etch.img
> EXT3 FS on loop0p1, internal journal
> EXT3-fs: mounted filesystem with ordered data mode.
> loop: module loaded
>  loop0: p1 p2 < p5 >
> # ls -l /dev/loop?*
> brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> brw-rw---- 1 root disk 7,   1 2008-03-05 14:57 /dev/loop0p1
> brw-rw---- 1 root disk 7,   2 2008-03-05 14:57 /dev/loop0p2
> brw-rw---- 1 root disk 7,   5 2008-03-05 14:57 /dev/loop0p5
> brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> # mount /dev/loop0p1 /mnt
> kjournald starting.  Commit interval 5 seconds
> EXT3 FS on loop0p1, internal journal
> EXT3-fs: mounted filesystem with ordered data mode.
> # ls /mnt
> bench  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
> 
> Of course, the same behavior can be done using kpartx on a loop device,
> but modifying loop avoids to stack several layers of block device (loop +
> device mapper), this is a very light modification (40% of modifications
> are to manage the new parameter).
> 
> Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
> ---
>  Documentation/kernel-parameters.txt |    4 +++
>  drivers/block/loop.c                |   39 ++++++++++++++++++++++++++++++----
>  2 files changed, 38 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 9a5b665..7f2fd52 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -1075,6 +1075,10 @@ and is between 256 and 4096 characters. It is defined in the file
>  			be mounted
>  			Format: <1-256>
>  
> +	loop_max_part=	[LOOP] Maximum number of partitions per loopback device.
> +			Should be greater than 0, the maximum value depends
> +			on max_loop.
> +
>  	maxcpus=	[SMP] Maximum number of processors that	an SMP kernel
>  			should make use of.  maxcpus=n : n >= 0 limits the
>  			kernel to using 'n' processors.  n=0 is a special case,
> diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> index 91ebb00..16b2aa6 100644
> --- a/drivers/block/loop.c
> +++ b/drivers/block/loop.c
> @@ -82,6 +82,9 @@
>  static LIST_HEAD(loop_devices);
>  static DEFINE_MUTEX(loop_devices_mutex);
>  
> +static int loop_max_part;
> +static int part_shift;
> +
>  /*
>   * Transfer functions
>   */
> @@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
>  		goto out_putf;
>  
>  	fput(old_file);
> +	if (loop_max_part > 0)
> +		ioctl_by_bdev(bdev, BLKRRPART, 0);
>  	return 0;
>  
>   out_putf:
> @@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
>  	}
>  	lo->lo_state = Lo_bound;
>  	wake_up_process(lo->lo_thread);
> +	if (loop_max_part > 0)
> +		ioctl_by_bdev(bdev, BLKRRPART, 0);
>  	return 0;
>  
>  out_clr:
> @@ -1360,6 +1367,8 @@ 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");
> +module_param(loop_max_part, int, 0);
> +MODULE_PARM_DESC(loop_max_part, "Maximum number of partitions per loop device");
>  MODULE_LICENSE("GPL");
>  MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
>  
> @@ -1412,7 +1421,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;
>  
> @@ -1422,7 +1431,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;
> @@ -1502,7 +1511,12 @@ static int __init loop_init(void)
>  	 *     themselves and have kernel automatically instantiate actual
>  	 *     device on-demand.
>  	 */
> -	if (max_loop > 1UL << MINORBITS)
> +
> +	part_shift = 0;
> +	if (loop_max_part > 0)
> +		part_shift = fls(loop_max_part);
> +
> +	if (max_loop > 1UL << (MINORBITS - part_shift))
>  		return -EINVAL;
>  
>  	if (max_loop) {
> @@ -1510,7 +1524,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"))
> @@ -1549,7 +1563,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);
> @@ -1569,4 +1583,19 @@ static int __init max_loop_setup(char *str)
>  }
>  
>  __setup("max_loop=", max_loop_setup);
> +
> +static int __init max_part_setup(char *str)
> +{
> +	loop_max_part = simple_strtol(str, NULL, 0);
> +	if (loop_max_part > (1UL << (MINORBITS - 1))) {
> +		/* we must keep at least one bit for loop device number */
> +		printk(KERN_ERR
> +			"loop: loop_max_part cannot be greater than %lu\n",
> +			1UL << (MINORBITS - 1));
> +		return 0;
> +	}
> +	return 1;
> +}
> +
> +__setup("loop_max_part=", max_part_setup);
>  #endif


-- 
Bill Davidsen <davidsen@tmr.com>
   "We have more to fear from the bungling of the incompetent than from
the machinations of the wicked."  - from Slashdot

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][v4]  Modify loop device to be able to manage partitions of the disk image
  2008-03-19 20:11   ` Randy Dunlap
@ 2008-03-19 20:24     ` Laurent Vivier
  2008-03-19 21:28       ` Andrew Morton
  0 siblings, 1 reply; 14+ messages in thread
From: Laurent Vivier @ 2008-03-19 20:24 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: akpm, jens.axboe, linux-kernel


Le mercredi 19 mars 2008 à 13:11 -0700, Randy Dunlap a écrit :
> On Wed, 19 Mar 2008 13:36:07 +0100 Laurent Vivier wrote:
> 
> > This patch allows to use loop device with partitionned disk image.
> > 
> > Original behavior of loop is not modified.
> > 
> > A new parameter is introduced to define how many partition we want to be
> > able to manage per loop device. This parameter is "max_part".
> 
> What happened to the update to Documentation/kernel-parameters.txt
> that was in v3?

Well, perhaps I didn't understand the comment of Andrew:

"This shouldn't be needed."

I though it means I should remove it. So, Andrew ???

And to comment the changes between v3 and v4:

- remove modification from kernel-parameters.txt (as you saw)
- rename the parameter to max_part (according Andrew comments)
- add an "ioctl_by_bdev(bdev, BLKRRPART, 0);" on loop_clr_fd()
  (to remove loopXpY from /dev/ on "losetup -d")

Laurent

> 
> > For instance, to manage 63 partitions / loop device, we will do:
> > # modprobe loop max_part=63
> > # ls -l /dev/loop?*
> > brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> > brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> > brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> > brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> > brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> > brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> > brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> > brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> > 
> > And to attach a raw partitionned disk image, the original losetup is used:
> > 
> > # losetup -f etch.img
> > # ls -l /dev/loop?*
> > brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> > brw-rw---- 1 root disk 7,   1 2008-03-05 14:57 /dev/loop0p1
> > brw-rw---- 1 root disk 7,   2 2008-03-05 14:57 /dev/loop0p2
> > brw-rw---- 1 root disk 7,   5 2008-03-05 14:57 /dev/loop0p5
> > brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> > brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> > brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> > brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> > brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> > brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> > brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> > # mount /dev/loop0p1 /mnt
> > # ls /mnt
> > bench  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
> > 
> > Of course, the same behavior can be done using kpartx on a loop device,
> > but modifying loop avoids to stack several layers of block device (loop +
> > device mapper), this is a very light modification (40% of modifications
> > are to manage the new parameter).
> > 
> > Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
> > ---
> >  drivers/block/loop.c |   26 +++++++++++++++++++++-----
> >  1 files changed, 21 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> > index 91ebb00..f7f1635 100644
> > --- a/drivers/block/loop.c
> > +++ b/drivers/block/loop.c
> > @@ -82,6 +82,9 @@
> >  static LIST_HEAD(loop_devices);
> >  static DEFINE_MUTEX(loop_devices_mutex);
> >  
> > +static int max_part;
> > +static int part_shift;
> > +
> >  /*
> >   * Transfer functions
> >   */
> > @@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
> >  		goto out_putf;
> >  
> >  	fput(old_file);
> > +	if (max_part > 0)
> > +		ioctl_by_bdev(bdev, BLKRRPART, 0);
> >  	return 0;
> >  
> >   out_putf:
> > @@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
> >  	}
> >  	lo->lo_state = Lo_bound;
> >  	wake_up_process(lo->lo_thread);
> > +	if (max_part > 0)
> > +		ioctl_by_bdev(bdev, BLKRRPART, 0);
> >  	return 0;
> >  
> >  out_clr:
> > @@ -919,6 +926,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
> >  	fput(filp);
> >  	/* This is safe: open() is still holding a reference. */
> >  	module_put(THIS_MODULE);
> > +	if (max_part > 0)
> > +		ioctl_by_bdev(bdev, BLKRRPART, 0);
> >  	return 0;
> >  }
> >  
> > @@ -1360,6 +1369,8 @@ 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");
> > +module_param(max_part, int, 0);
> > +MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");
> >  MODULE_LICENSE("GPL");
> >  MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
> >  
> > @@ -1412,7 +1423,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;
> >  
> > @@ -1422,7 +1433,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;
> > @@ -1502,7 +1513,12 @@ static int __init loop_init(void)
> >  	 *     themselves and have kernel automatically instantiate actual
> >  	 *     device on-demand.
> >  	 */
> > -	if (max_loop > 1UL << MINORBITS)
> > +
> > +	part_shift = 0;
> > +	if (max_part > 0)
> > +		part_shift = fls(max_part);
> > +
> > +	if (max_loop > 1UL << (MINORBITS - part_shift))
> >  		return -EINVAL;
> >  
> >  	if (max_loop) {
> > @@ -1510,7 +1526,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"))
> > @@ -1549,7 +1565,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);
> > -- 
> 
> 
> ---
> ~Randy
> 
-- 
------- Laurent.Vivier@bull.net  -------
  "The best way to predict the future 
      is to invent it." - Alan Kay


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][RESEND][v3] Modify loop device to be able to manage partitions of the disk image
  2008-03-19 20:24 ` [PATCH][RESEND][v3] " Bill Davidsen
@ 2008-03-19 20:32   ` Laurent Vivier
  2008-03-23 23:33     ` Bill Davidsen
  0 siblings, 1 reply; 14+ messages in thread
From: Laurent Vivier @ 2008-03-19 20:32 UTC (permalink / raw)
  To: Bill Davidsen; +Cc: axboe, linux-kernel, akpm


Le mercredi 19 mars 2008 à 16:24 -0400, Bill Davidsen a écrit :
> Laurent Vivier wrote:
> > v3 is an updated version of v2, replacing a "%d" by a "%lu".
> > 
> > This patch allows to use loop device with partitionned disk image.
> > 
> How does this compare in overhead to using nbd?

What do you mean ?

NBD doesn't manage partitions... but I also have a patch to do that.
NBD implies an NBD server and an NBD client in userspace, so loop is
better when disk image is in a raw format.

Laurent

> > Original behavior of loop is not modified.
> > 
> > A new parameter is introduced to define how many partition we want to be
> > able to manage per loop device. This parameter is "loop_max_part".
> > 
> > For instance, to manage 63 partitions / loop device, we will do:
> > # modprobe loop loop_max_part=63
> > # ls -l /dev/loop?
> > brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> > brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> > brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> > brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> > brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> > brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> > brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> > brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> > 
> > And to attach a raw partitionned disk image, the original losetup is used:
> > 
> > # losetup -f etch.img
> > EXT3 FS on loop0p1, internal journal
> > EXT3-fs: mounted filesystem with ordered data mode.
> > loop: module loaded
> >  loop0: p1 p2 < p5 >
> > # ls -l /dev/loop?*
> > brw-rw---- 1 root disk 7,   0 2008-03-05 14:55 /dev/loop0
> > brw-rw---- 1 root disk 7,   1 2008-03-05 14:57 /dev/loop0p1
> > brw-rw---- 1 root disk 7,   2 2008-03-05 14:57 /dev/loop0p2
> > brw-rw---- 1 root disk 7,   5 2008-03-05 14:57 /dev/loop0p5
> > brw-rw---- 1 root disk 7,  64 2008-03-05 14:55 /dev/loop1
> > brw-rw---- 1 root disk 7, 128 2008-03-05 14:55 /dev/loop2
> > brw-rw---- 1 root disk 7, 192 2008-03-05 14:55 /dev/loop3
> > brw-rw---- 1 root disk 7, 256 2008-03-05 14:55 /dev/loop4
> > brw-rw---- 1 root disk 7, 320 2008-03-05 14:55 /dev/loop5
> > brw-rw---- 1 root disk 7, 384 2008-03-05 14:55 /dev/loop6
> > brw-rw---- 1 root disk 7, 448 2008-03-05 14:55 /dev/loop7
> > # mount /dev/loop0p1 /mnt
> > kjournald starting.  Commit interval 5 seconds
> > EXT3 FS on loop0p1, internal journal
> > EXT3-fs: mounted filesystem with ordered data mode.
> > # ls /mnt
> > bench  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
> > 
> > Of course, the same behavior can be done using kpartx on a loop device,
> > but modifying loop avoids to stack several layers of block device (loop +
> > device mapper), this is a very light modification (40% of modifications
> > are to manage the new parameter).
> > 
> > Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
> > ---
> >  Documentation/kernel-parameters.txt |    4 +++
> >  drivers/block/loop.c                |   39 ++++++++++++++++++++++++++++++----
> >  2 files changed, 38 insertions(+), 5 deletions(-)
> > 
> > diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> > index 9a5b665..7f2fd52 100644
> > --- a/Documentation/kernel-parameters.txt
> > +++ b/Documentation/kernel-parameters.txt
> > @@ -1075,6 +1075,10 @@ and is between 256 and 4096 characters. It is defined in the file
> >  			be mounted
> >  			Format: <1-256>
> >  
> > +	loop_max_part=	[LOOP] Maximum number of partitions per loopback device.
> > +			Should be greater than 0, the maximum value depends
> > +			on max_loop.
> > +
> >  	maxcpus=	[SMP] Maximum number of processors that	an SMP kernel
> >  			should make use of.  maxcpus=n : n >= 0 limits the
> >  			kernel to using 'n' processors.  n=0 is a special case,
> > diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> > index 91ebb00..16b2aa6 100644
> > --- a/drivers/block/loop.c
> > +++ b/drivers/block/loop.c
> > @@ -82,6 +82,9 @@
> >  static LIST_HEAD(loop_devices);
> >  static DEFINE_MUTEX(loop_devices_mutex);
> >  
> > +static int loop_max_part;
> > +static int part_shift;
> > +
> >  /*
> >   * Transfer functions
> >   */
> > @@ -692,6 +695,8 @@ static int loop_change_fd(struct loop_device *lo, struct file *lo_file,
> >  		goto out_putf;
> >  
> >  	fput(old_file);
> > +	if (loop_max_part > 0)
> > +		ioctl_by_bdev(bdev, BLKRRPART, 0);
> >  	return 0;
> >  
> >   out_putf:
> > @@ -819,6 +824,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
> >  	}
> >  	lo->lo_state = Lo_bound;
> >  	wake_up_process(lo->lo_thread);
> > +	if (loop_max_part > 0)
> > +		ioctl_by_bdev(bdev, BLKRRPART, 0);
> >  	return 0;
> >  
> >  out_clr:
> > @@ -1360,6 +1367,8 @@ 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");
> > +module_param(loop_max_part, int, 0);
> > +MODULE_PARM_DESC(loop_max_part, "Maximum number of partitions per loop device");
> >  MODULE_LICENSE("GPL");
> >  MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
> >  
> > @@ -1412,7 +1421,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;
> >  
> > @@ -1422,7 +1431,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;
> > @@ -1502,7 +1511,12 @@ static int __init loop_init(void)
> >  	 *     themselves and have kernel automatically instantiate actual
> >  	 *     device on-demand.
> >  	 */
> > -	if (max_loop > 1UL << MINORBITS)
> > +
> > +	part_shift = 0;
> > +	if (loop_max_part > 0)
> > +		part_shift = fls(loop_max_part);
> > +
> > +	if (max_loop > 1UL << (MINORBITS - part_shift))
> >  		return -EINVAL;
> >  
> >  	if (max_loop) {
> > @@ -1510,7 +1524,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"))
> > @@ -1549,7 +1563,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);
> > @@ -1569,4 +1583,19 @@ static int __init max_loop_setup(char *str)
> >  }
> >  
> >  __setup("max_loop=", max_loop_setup);
> > +
> > +static int __init max_part_setup(char *str)
> > +{
> > +	loop_max_part = simple_strtol(str, NULL, 0);
> > +	if (loop_max_part > (1UL << (MINORBITS - 1))) {
> > +		/* we must keep at least one bit for loop device number */
> > +		printk(KERN_ERR
> > +			"loop: loop_max_part cannot be greater than %lu\n",
> > +			1UL << (MINORBITS - 1));
> > +		return 0;
> > +	}
> > +	return 1;
> > +}
> > +
> > +__setup("loop_max_part=", max_part_setup);
> >  #endif
> 
> 
-- 
------- Laurent.Vivier@bull.net  -------
  "The best way to predict the future 
      is to invent it." - Alan Kay


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][v4]  Modify loop device to be able to manage partitions of the disk image
  2008-03-19 20:24     ` Laurent Vivier
@ 2008-03-19 21:28       ` Andrew Morton
  2008-03-19 21:39         ` Laurent Vivier
                           ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Andrew Morton @ 2008-03-19 21:28 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: randy.dunlap, jens.axboe, linux-kernel

On Wed, 19 Mar 2008 21:24:41 +0100
Laurent Vivier <Laurent.Vivier@bull.net> wrote:

> Le mercredi 19 mars 2008 __ 13:11 -0700, Randy Dunlap a __crit :
> > On Wed, 19 Mar 2008 13:36:07 +0100 Laurent Vivier wrote:
> > 
> > > This patch allows to use loop device with partitionned disk image.
> > > 
> > > Original behavior of loop is not modified.
> > > 
> > > A new parameter is introduced to define how many partition we want to be
> > > able to manage per loop device. This parameter is "max_part".
> > 
> > What happened to the update to Documentation/kernel-parameters.txt
> > that was in v3?
> 
> Well, perhaps I didn't understand the comment of Andrew:
> 
> "This shouldn't be needed."
> 
> I though it means I should remove it. So, Andrew ???

No, given that all module_param() options are available via the boot
command line when the module is linked into vmlinux, we don't document them
separately.

There should be a way of auto-generating all the documentation for all the
module parameters from their MODULE_PARM_DESC's.  And there probably is,
but I'm not sure how this is done (?)

(does `make help', fails to spot it).

You can do `modinfo loop' but that probably doesn't work if
CONFIG_BLK_DEV_LOOP=y?



I assume you tested the "loop.max_part=N" option?


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][v4]  Modify loop device to be able to manage partitions of the disk image
  2008-03-19 21:28       ` Andrew Morton
@ 2008-03-19 21:39         ` Laurent Vivier
  2008-03-19 21:43           ` Andrew Morton
  2008-03-19 23:03         ` Randy Dunlap
  2008-03-20 21:36         ` Bill Davidsen
  2 siblings, 1 reply; 14+ messages in thread
From: Laurent Vivier @ 2008-03-19 21:39 UTC (permalink / raw)
  To: Andrew Morton; +Cc: randy.dunlap, jens.axboe, linux-kernel


Le mercredi 19 mars 2008 à 14:28 -0700, Andrew Morton a écrit :
> On Wed, 19 Mar 2008 21:24:41 +0100
> Laurent Vivier <Laurent.Vivier@bull.net> wrote:
> 
> > Le mercredi 19 mars 2008 __ 13:11 -0700, Randy Dunlap a __crit :
> > > On Wed, 19 Mar 2008 13:36:07 +0100 Laurent Vivier wrote:
> > > 
> > > > This patch allows to use loop device with partitionned disk image.
> > > > 
> > > > Original behavior of loop is not modified.
> > > > 
> > > > A new parameter is introduced to define how many partition we want to be
> > > > able to manage per loop device. This parameter is "max_part".
> > > 
> > > What happened to the update to Documentation/kernel-parameters.txt
> > > that was in v3?
> > 
> > Well, perhaps I didn't understand the comment of Andrew:
> > 
> > "This shouldn't be needed."
> > 
> > I though it means I should remove it. So, Andrew ???
> 
> No, given that all module_param() options are available via the boot
> command line when the module is linked into vmlinux, we don't document them
> separately.

"No" is "To document max_part is not needed"

or

"No" is "you must not remove parameter documentation from your patch" ?

> There should be a way of auto-generating all the documentation for all the
> module parameters from their MODULE_PARM_DESC's.  And there probably is,
> but I'm not sure how this is done (?)
> 
> (does `make help', fails to spot it).
> 
> You can do `modinfo loop' but that probably doesn't work if
> CONFIG_BLK_DEV_LOOP=y?
> 
> 
> 
> I assume you tested the "loop.max_part=N" option?

Yes, I did (with N=63)

Regards,
Laurent
-- 
------------- Laurent.Vivier@bull.net ---------------
"The best way to predict the future is to invent it."
- Alan Kay


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][v4]  Modify loop device to be able to manage partitions of the disk image
  2008-03-19 21:39         ` Laurent Vivier
@ 2008-03-19 21:43           ` Andrew Morton
  0 siblings, 0 replies; 14+ messages in thread
From: Andrew Morton @ 2008-03-19 21:43 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: randy.dunlap, jens.axboe, linux-kernel

On Wed, 19 Mar 2008 22:39:10 +0100
Laurent Vivier <Laurent.Vivier@bull.net> wrote:

> > > > What happened to the update to Documentation/kernel-parameters.txt
> > > > that was in v3?
> > > 
> > > Well, perhaps I didn't understand the comment of Andrew:
> > > 
> > > "This shouldn't be needed."
> > > 
> > > I though it means I should remove it. So, Andrew ???
> > 
> > No, given that all module_param() options are available via the boot
> > command line when the module is linked into vmlinux, we don't document them
> > separately.
> 
> "No" is "To document max_part is not needed"
> 
> or
> 
> "No" is "you must not remove parameter documentation from your patch" ?

The former ;)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][v4]  Modify loop device to be able to manage partitions of the disk image
  2008-03-19 21:28       ` Andrew Morton
  2008-03-19 21:39         ` Laurent Vivier
@ 2008-03-19 23:03         ` Randy Dunlap
  2008-03-20 21:36         ` Bill Davidsen
  2 siblings, 0 replies; 14+ messages in thread
From: Randy Dunlap @ 2008-03-19 23:03 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Laurent Vivier, jens.axboe, linux-kernel

Andrew Morton wrote:
> On Wed, 19 Mar 2008 21:24:41 +0100
> Laurent Vivier <Laurent.Vivier@bull.net> wrote:
> 
>> Le mercredi 19 mars 2008 __ 13:11 -0700, Randy Dunlap a __crit :
>>> On Wed, 19 Mar 2008 13:36:07 +0100 Laurent Vivier wrote:
>>>
>>>> This patch allows to use loop device with partitionned disk image.
>>>>
>>>> Original behavior of loop is not modified.
>>>>
>>>> A new parameter is introduced to define how many partition we want to be
>>>> able to manage per loop device. This parameter is "max_part".
>>> What happened to the update to Documentation/kernel-parameters.txt
>>> that was in v3?
>> Well, perhaps I didn't understand the comment of Andrew:
>>
>> "This shouldn't be needed."
>>
>> I though it means I should remove it. So, Andrew ???

First of all, I didn't see Andrew's message until awhile after yours,
due to some kind of email problems...

> No, given that all module_param() options are available via the boot
> command line when the module is linked into vmlinux, we don't document them
> separately.

Thanks.  That's news to me.  Not that I mind the news.

> There should be a way of auto-generating all the documentation for all the
> module parameters from their MODULE_PARM_DESC's.  And there probably is,
> but I'm not sure how this is done (?)

No, nothing in tree like that.

Would such an auto-generator use source files or compiled modules?
Using the latter means that (a) something like allmodconfig must be done
and (b) it only works for the compiled $ARCH(es), whereas using source code
has neither of those "problems."

I can work on updating
http://www.xenotime.net/linux/scripts/module-params (from Oct-2006).
Comments welcome.


> (does `make help', fails to spot it).
> 
> You can do `modinfo loop' but that probably doesn't work if
> CONFIG_BLK_DEV_LOOP=y?


-- 
~Randy

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][v4]  Modify loop device to be able to manage partitions of the disk image
  2008-03-19 21:28       ` Andrew Morton
  2008-03-19 21:39         ` Laurent Vivier
  2008-03-19 23:03         ` Randy Dunlap
@ 2008-03-20 21:36         ` Bill Davidsen
  2 siblings, 0 replies; 14+ messages in thread
From: Bill Davidsen @ 2008-03-20 21:36 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Laurent Vivier, randy.dunlap, jens.axboe, linux-kernel

Andrew Morton wrote:
> On Wed, 19 Mar 2008 21:24:41 +0100
> Laurent Vivier <Laurent.Vivier@bull.net> wrote:
> 
>> Le mercredi 19 mars 2008 __ 13:11 -0700, Randy Dunlap a __crit :
>>> On Wed, 19 Mar 2008 13:36:07 +0100 Laurent Vivier wrote:
>>>
>>>> This patch allows to use loop device with partitionned disk image.
>>>>
>>>> Original behavior of loop is not modified.
>>>>
>>>> A new parameter is introduced to define how many partition we want to be
>>>> able to manage per loop device. This parameter is "max_part".
>>> What happened to the update to Documentation/kernel-parameters.txt
>>> that was in v3?
>> Well, perhaps I didn't understand the comment of Andrew:
>>
>> "This shouldn't be needed."
>>
>> I though it means I should remove it. So, Andrew ???
> 
> No, given that all module_param() options are available via the boot
> command line when the module is linked into vmlinux, we don't document them
> separately.
> 
I totally don't understand this comment, where is the file with the list 
of canonical module parameters now? I must have missed the discussion of 
why it is changed. And what has the boot command line or linking modules 
to do with the documentation file?

> There should be a way of auto-generating all the documentation for all the
> module parameters from their MODULE_PARM_DESC's.  And there probably is,
> but I'm not sure how this is done (?)
> 
> (does `make help', fails to spot it).


-- 
Bill Davidsen <davidsen@tmr.com>
   "We have more to fear from the bungling of the incompetent than from
the machinations of the wicked."  - from Slashdot

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH][RESEND][v3] Modify loop device to be able to manage  partitions of the disk image
  2008-03-19 20:32   ` Laurent Vivier
@ 2008-03-23 23:33     ` Bill Davidsen
  2008-03-25 10:34       ` [PATCH] Modify Network Block Device (nbd) to be able to manage partitions Laurent Vivier
  0 siblings, 1 reply; 14+ messages in thread
From: Bill Davidsen @ 2008-03-23 23:33 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: axboe, linux-kernel, akpm

Laurent Vivier wrote:
> Le mercredi 19 mars 2008 à 16:24 -0400, Bill Davidsen a écrit :
>> Laurent Vivier wrote:
>>> v3 is an updated version of v2, replacing a "%d" by a "%lu".
>>>
>>> This patch allows to use loop device with partitionned disk image.
>>>
>> How does this compare in overhead to using nbd?
> 
> What do you mean ?
> 
> NBD doesn't manage partitions... but I also have a patch to do that.
> NBD implies an NBD server and an NBD client in userspace, so loop is
> better when disk image is in a raw format.
> 
Actually the usual partitioning tools will create partitions on nbd 
volumes, but without inodes they are not useful. I thought we used to 
have that working, to work on virtual machine "disk" files which were 
partitioned, but that was several years ago and I could be 
misremembering. I did use fdisk on an nbd device before I asked about 
overhead, but I didn't try to use the partitions.

In any case, if you have code to make nbd partitions work in a currently 
useful way, that might be useful for keeping disk images handy for 
mount. The kvm copy on write might let the fresh install image be shared 
and VMs customize as needed.

-- 
Bill Davidsen <davidsen@tmr.com>
   "We have more to fear from the bungling of the incompetent than from
the machinations of the wicked."  - from Slashdot


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH] Modify Network Block Device (nbd) to be able to manage partitions
  2008-03-23 23:33     ` Bill Davidsen
@ 2008-03-25 10:34       ` Laurent Vivier
  0 siblings, 0 replies; 14+ messages in thread
From: Laurent Vivier @ 2008-03-25 10:34 UTC (permalink / raw)
  To: Paul Clements; +Cc: linux-kernel, Bill Davidsen, nbd-general, Laurent Vivier

This patch allows to use partitions with network block devices (NBD).

A new parameter is introduced to define how many partition we want to be
able to manage per network block device. This parameter is "max_part".

For instance, to manage 63 partitions / loop device, we will do:

   [on the server side]
# nbd-server 1234 /dev/sdb
   [on the client side]
# modprobe nbd max_part=63
# ls -l /dev/nbd*
brw-rw---- 1 root disk 43,   0 2008-03-25 11:14 /dev/nbd0
brw-rw---- 1 root disk 43,  64 2008-03-25 11:11 /dev/nbd1
brw-rw---- 1 root disk 43, 640 2008-03-25 11:11 /dev/nbd10
brw-rw---- 1 root disk 43, 704 2008-03-25 11:11 /dev/nbd11
brw-rw---- 1 root disk 43, 768 2008-03-25 11:11 /dev/nbd12
brw-rw---- 1 root disk 43, 832 2008-03-25 11:11 /dev/nbd13
brw-rw---- 1 root disk 43, 896 2008-03-25 11:11 /dev/nbd14
brw-rw---- 1 root disk 43, 960 2008-03-25 11:11 /dev/nbd15
brw-rw---- 1 root disk 43, 128 2008-03-25 11:11 /dev/nbd2
brw-rw---- 1 root disk 43, 192 2008-03-25 11:11 /dev/nbd3
brw-rw---- 1 root disk 43, 256 2008-03-25 11:11 /dev/nbd4
brw-rw---- 1 root disk 43, 320 2008-03-25 11:11 /dev/nbd5
brw-rw---- 1 root disk 43, 384 2008-03-25 11:11 /dev/nbd6
brw-rw---- 1 root disk 43, 448 2008-03-25 11:11 /dev/nbd7
brw-rw---- 1 root disk 43, 512 2008-03-25 11:11 /dev/nbd8
brw-rw---- 1 root disk 43, 576 2008-03-25 11:11 /dev/nbd9
# nbd-client localhost 1234 /dev/nbd0
Negotiation: ..size = 80418240KB
bs=1024, sz=80418240

-------NOTE, RFC: partition table is not automatically read.
The driver sets bdev->bd_invalidated to 1 to force the read of the partition
table of the device, but this is done only on an open of the device.
So we have to do a "touch /dev/nbdX" or something like that.
It can't be done from the nbd-client or nbd driver because at this
level we can't ask to read the partition table and to serve the request
at the same time (-> deadlock)

If someone has a better idea, I'm open to any suggestion.
-------NOTE, RFC

# fdisk -l /dev/nbd0

Disk /dev/nbd0: 82.3 GB, 82348277760 bytes
255 heads, 63 sectors/track, 10011 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

     Device Boot      Start         End      Blocks   Id  System
/dev/nbd0p1   *           1        9965    80043831   83  Linux
/dev/nbd0p2            9966       10011      369495    5  Extended
/dev/nbd0p5            9966       10011      369463+  82  Linux swap / Solaris

# ls -l /dev/nbd0*
brw-rw---- 1 root disk 43,   0 2008-03-25 11:16 /dev/nbd0
brw-rw---- 1 root disk 43,   1 2008-03-25 11:16 /dev/nbd0p1
brw-rw---- 1 root disk 43,   2 2008-03-25 11:16 /dev/nbd0p2
brw-rw---- 1 root disk 43,   5 2008-03-25 11:16 /dev/nbd0p5
# mount /dev/nbd0p1 /mnt
# ls /mnt
bin    dev   initrd      lost+found  opt   sbin     sys  var
boot   etc   initrd.img  media       proc  selinux  tmp  vmlinuz
cdrom  home  lib         mnt         root  srv      usr
# umount /mnt
# nbd-client -d /dev/nbd0
# ls -l /dev/nbd0*
brw-rw---- 1 root disk 43, 0 2008-03-25 11:16 /dev/nbd0
-------NOTE
On "nbd-client -d", we can do an iocl(BLKRRPART) to update partition table:
as the size of the device is 0, we don't have to serve the partition manager
request (-> no deadlock).
-------NOTE

Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
 drivers/block/nbd.c |   25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index b53fdb0..36070d5 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -55,6 +55,7 @@ static unsigned int debugflags;
 
 static unsigned int nbds_max = 16;
 static struct nbd_device *nbd_dev;
+static int max_part;
 
 /*
  * Use just one lock (or at most 1 per NIC). Two arguments for this:
@@ -565,10 +566,13 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
 		error = -EINVAL;
 		file = fget(arg);
 		if (file) {
+			struct block_device *bdev = inode->i_bdev;
 			inode = file->f_path.dentry->d_inode;
 			if (S_ISSOCK(inode->i_mode)) {
 				lo->file = file;
 				lo->sock = SOCKET_I(inode);
+				if (max_part > 0)
+					bdev->bd_invalidated = 1;
 				error = 0;
 			} else {
 				fput(file);
@@ -613,6 +617,8 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
 		lo->bytesize = 0;
 		inode->i_bdev->bd_inode->i_size = 0;
 		set_capacity(lo->disk, 0);
+		if (max_part > 0)
+			ioctl_by_bdev(inode->i_bdev, BLKRRPART, 0);
 		return lo->harderror;
 	case NBD_CLEAR_QUE:
 		/*
@@ -646,6 +652,7 @@ static int __init nbd_init(void)
 {
 	int err = -ENOMEM;
 	int i;
+	int part_shift;
 
 	BUILD_BUG_ON(sizeof(struct nbd_request) != 28);
 
@@ -653,8 +660,17 @@ static int __init nbd_init(void)
 	if (!nbd_dev)
 		return -ENOMEM;
 
+	if (max_part < 0) {
+		printk(KERN_CRIT "nbd: max_part must be >= 0\n");
+		return -EINVAL;
+	}
+
+	part_shift = 0;
+	if (max_part > 0)
+		part_shift = fls(max_part);
+
 	for (i = 0; i < nbds_max; i++) {
-		struct gendisk *disk = alloc_disk(1);
+		struct gendisk *disk = alloc_disk(1 << part_shift);
 		elevator_t *old_e;
 		if (!disk)
 			goto out;
@@ -696,10 +712,11 @@ static int __init nbd_init(void)
 		nbd_dev[i].blksize = 1024;
 		nbd_dev[i].bytesize = 0;
 		disk->major = NBD_MAJOR;
-		disk->first_minor = i;
+		disk->first_minor = i << part_shift;
 		disk->fops = &nbd_fops;
 		disk->private_data = &nbd_dev[i];
-		disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
+		if (max_part == 0)
+			disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
 		sprintf(disk->disk_name, "nbd%d", i);
 		set_capacity(disk, 0);
 		add_disk(disk);
@@ -738,6 +755,8 @@ MODULE_LICENSE("GPL");
 
 module_param(nbds_max, int, 0444);
 MODULE_PARM_DESC(nbds_max, "How many network block devices to initialize.");
+module_param(max_part, int, 0444);
+MODULE_PARM_DESC(max_part, "How many partitions by device.");
 #ifndef NDEBUG
 module_param(debugflags, int, 0644);
 MODULE_PARM_DESC(debugflags, "flags for controlling debug output");
-- 
1.5.2.4


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2008-03-25 10:32 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-18 12:19 [PATCH][RESEND][v3] Modify loop device to be able to manage partitions of the disk image Laurent Vivier
2008-03-18 20:54 ` Andrew Morton
2008-03-19 12:36 ` [PATCH][v4] " Laurent Vivier
2008-03-19 20:11   ` Randy Dunlap
2008-03-19 20:24     ` Laurent Vivier
2008-03-19 21:28       ` Andrew Morton
2008-03-19 21:39         ` Laurent Vivier
2008-03-19 21:43           ` Andrew Morton
2008-03-19 23:03         ` Randy Dunlap
2008-03-20 21:36         ` Bill Davidsen
2008-03-19 20:24 ` [PATCH][RESEND][v3] " Bill Davidsen
2008-03-19 20:32   ` Laurent Vivier
2008-03-23 23:33     ` Bill Davidsen
2008-03-25 10:34       ` [PATCH] Modify Network Block Device (nbd) to be able to manage partitions Laurent Vivier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).