LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* max_loop limit
@ 2007-03-22  7:57 Tomas M
  2007-03-22 11:00 ` markus reichelt
  0 siblings, 1 reply; 30+ messages in thread
From: Tomas M @ 2007-03-22  7:57 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1356 bytes --]

Hello,

this is my first code submitted to kernel, I hope you won't hate it.

This 4-lines-change patch adds support for nearly two-times more loop
devices. Explanation follows:

The maximum amount of loop devices has been 255 for many years, while
there is a lot of space for more. The maximum depends on max memory
available from kmalloc(), which is usually 128KB, but can be increased
in some cases.

It would be better to support thousands of loop devices of course, but
the change could be more complicated (perhaps replace kmalloc by
vmalloc). This four lines change is just simple and sufficient, without
any need for kmalloc replacement.

I only removed the test if (max_loop > 255), so now we support much more
loop devices then before, without ANY OTHER CHANGE to the code.

Information: The maximum max_loop is 455 if kmalloc can allocate 128KB,
so the amount is nearly doubled without any significant change to kernel
code. The maximum could be even bigger I guess, it probably depends on:
NR_CPUS, MAX_NUMNODES, CONFIG_MMU and CONFIG_LARGE_ALLOCS.

If kmalloc can't allocate enough RAM, loop is simply unloaded.


Thank you for your consideration.

I hope you will like it and you will include it in kernel.
Or, if not, maybe this patch will start some debate regarding
the current insufficient limit of 255 loop devices.


Tomas M
slax.org



[-- Attachment #2: loop.c.diff --]
[-- Type: text/x-patch, Size: 1861 bytes --]

--- linux/drivers/block/loop_old.c	2007-02-04 18:44:54.000000000 +0000
+++ linux/drivers/block/loop.c	2007-03-22 08:31:55.000000000 +0000
@@ -44,6 +44,16 @@
  * backing filesystem.
  * Anton Altaparmakov, 16 Feb 2005
  *
+ * The maximum amount of loop devices has been 255 for many years, while there
+ * is a lot of space for more. The maximum depends on max memory available 
+ * from kmalloc, which is usually 128KB, but can be even more.
+ * I removed the test if (max_loop > 255), so now we support much more loop 
+ * devices then before; it probably depends on:
+ *    NR_CPUS, MAX_NUMNODES, CONFIG_MMU and CONFIG_LARGE_ALLOCS.
+ * Information: The maximum max_loop is 455 if kmalloc handles only 128KB.
+ * If kmalloc can't allocate enough RAM, loop is simply unloaded.
+ * Author: Tomas Matejicek, www.slax.org, 21 Mar 2007
+ *
  * Still To Fix:
  * - Advisory locking is ignored here.
  * - Should use an own CAP_* category instead of CAP_SYS_ADMIN
@@ -1358,7 +1368,7 @@
  * And now the modules code and kernel interface.
  */
 module_param(max_loop, int, 0);
-MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)");
+MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-455 on i386)");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
@@ -1402,9 +1412,9 @@
 {
 	int	i;
 
-	if (max_loop < 1 || max_loop > 256) {
-		printk(KERN_WARNING "loop: invalid max_loop (must be between"
-				    " 1 and 256), using default (8)\n");
+	if (max_loop < 1) {
+		printk(KERN_WARNING "loop: invalid max_loop (must be at least 1"
+				    ", using default (8)\n");
 		max_loop = 8;
 	}
 
@@ -1465,7 +1475,7 @@
 	kfree(loop_dev);
 out_mem1:
 	unregister_blkdev(LOOP_MAJOR, "loop");
-	printk(KERN_ERR "loop: ran out of memory\n");
+	printk(KERN_ERR "loop: ran out of memory for max_loop=%d\n", max_loop);
 	return -ENOMEM;
 }
 

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

* Re: max_loop limit
  2007-03-22  7:57 max_loop limit Tomas M
@ 2007-03-22 11:00 ` markus reichelt
  2007-03-22 11:37   ` Tomas M
  0 siblings, 1 reply; 30+ messages in thread
From: markus reichelt @ 2007-03-22 11:00 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 334 bytes --]

* Tomas M <tomas@slax.org> wrote:

> I hope you will like it and you will include it in kernel.
> Or, if not, maybe this patch will start some debate regarding
> the current insufficient limit of 255 loop devices.

255 loop devices are insufficient? What kind of scenario do you have
in mind?


-- 
left blank, right bald

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

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

* Re: max_loop limit
  2007-03-22 11:00 ` markus reichelt
@ 2007-03-22 11:37   ` Tomas M
  2007-03-22 13:42     ` Eric Dumazet
  2007-03-29 14:16     ` max_loop limit Bill Davidsen
  0 siblings, 2 replies; 30+ messages in thread
From: Tomas M @ 2007-03-22 11:37 UTC (permalink / raw)
  To: linux-kernel

> 255 loop devices are insufficient? What kind of scenario do you have
> in mind?
> 
> 

Thank you very much for replying.

In 1981, Bill Gates said that 64KB of memory is enough for everybody.
And you know how much RAM do you have right now. :)

Every limit is bad. The limit of 255 loop devices has been introduced 
years ago, in the times when minor device number has been limited by 
255. Nowadays, there is no such limitation.

There are many possible/reasonable uses for more than 255 loop devices. 
For example CD/ISO server. My project, Slax Linux live, is based on 
modular approach where many parts of the root filesystem are stored 
separately in compressed read-only loop files, and are mounted and 
unioned to a single root by using union fs (aufs).

The question is not "Why do we need more than 255 loops?".
The question should be "Why do we need the hardcoded 255-limit in kernel 
while there is no reason for it at all?"

My patch simply removes the hardcoded limitation.


Tomas M
slax.org


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

* Re: max_loop limit
  2007-03-22 11:37   ` Tomas M
@ 2007-03-22 13:42     ` Eric Dumazet
  2007-03-22 13:42       ` Jens Axboe
                         ` (2 more replies)
  2007-03-29 14:16     ` max_loop limit Bill Davidsen
  1 sibling, 3 replies; 30+ messages in thread
From: Eric Dumazet @ 2007-03-22 13:42 UTC (permalink / raw)
  To: Tomas M; +Cc: linux-kernel

On Thu, 22 Mar 2007 12:37:54 +0100
Tomas M <tomas@slax.org> wrote:

> The question is not "Why do we need more than 255 loops?".
> The question should be "Why do we need the hardcoded 255-limit in kernel 
> while there is no reason for it at all?"
> 
> My patch simply removes the hardcoded limitation.

Hello Tomas, welcome !

Well, its an attempt to remove a hardcoded limit, but as you said in the Changelog, it really depends on kmalloc() being able to allocate a large continous memory zone. Alas it might fail.
The golden rule is to avoid all allocations larger than PAGE_SIZE :)

On x86_64, sizeof(struct loop_device) is 368, so the 'new limit' would be 356 instead of 256...

You might want a more radical patch : 

Instead of using :

static struct loop_device *loop_dev;
loop_dev = kmalloc(max_loop * sizeof(struct loop_device));

Switch to :

static struct loop_device **loop_dev;
loop_dev = kmalloc(max_loop * sizeof(void *));
if (!loop_dev) rollback...
for (i = 0 ; i < max_loop ; i++) {
	loop_dev[i] = kmalloc(sizeof(struct loop_device));
	if (!loop_dev[i]) rollback...
}

This time, you would be limited to 16384 loop devices on x86_64, 32768 on i386 :)

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

* Re: max_loop limit
  2007-03-22 13:42     ` Eric Dumazet
@ 2007-03-22 13:42       ` Jens Axboe
  2007-03-22 13:52         ` Eric Dumazet
  2007-03-22 14:33         ` max_loop limit Al Viro
  2007-03-22 14:25       ` Tomas M
  2007-03-23  1:34       ` Jan Engelhardt
  2 siblings, 2 replies; 30+ messages in thread
From: Jens Axboe @ 2007-03-22 13:42 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Tomas M, linux-kernel

On Thu, Mar 22 2007, Eric Dumazet wrote:
> On Thu, 22 Mar 2007 12:37:54 +0100
> Tomas M <tomas@slax.org> wrote:
> 
> > The question is not "Why do we need more than 255 loops?".
> > The question should be "Why do we need the hardcoded 255-limit in kernel 
> > while there is no reason for it at all?"
> > 
> > My patch simply removes the hardcoded limitation.
> 
> Hello Tomas, welcome !
> 
> Well, its an attempt to remove a hardcoded limit, but as you said in the Changelog, it really depends on kmalloc() being able to allocate a large continous memory zone. Alas it might fail.
> The golden rule is to avoid all allocations larger than PAGE_SIZE :)
> 
> On x86_64, sizeof(struct loop_device) is 368, so the 'new limit' would be 356 instead of 256...
> 
> You might want a more radical patch : 
> 
> Instead of using :
> 
> static struct loop_device *loop_dev;
> loop_dev = kmalloc(max_loop * sizeof(struct loop_device));
> 
> Switch to :
> 
> static struct loop_device **loop_dev;
> loop_dev = kmalloc(max_loop * sizeof(void *));
> if (!loop_dev) rollback...
> for (i = 0 ; i < max_loop ; i++) {
> 	loop_dev[i] = kmalloc(sizeof(struct loop_device));
> 	if (!loop_dev[i]) rollback...
> }
> 
> This time, you would be limited to 16384 loop devices on x86_64, 32768 on i386 :)

But this still wastes memory, why not just allocate each loop device
dynamically when it is set up? The current approach is crap, it is just
wasting memory for loop devices, queues, etc.

-- 
Jens Axboe


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

* Re: max_loop limit
  2007-03-22 13:42       ` Jens Axboe
@ 2007-03-22 13:52         ` Eric Dumazet
  2007-03-22 13:54           ` Jens Axboe
  2007-03-22 14:33         ` max_loop limit Al Viro
  1 sibling, 1 reply; 30+ messages in thread
From: Eric Dumazet @ 2007-03-22 13:52 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Tomas M, linux-kernel

On Thu, 22 Mar 2007 14:42:31 +0100
Jens Axboe <jens.axboe@oracle.com> wrote:


> > This time, you would be limited to 16384 loop devices on x86_64, 32768 on i386 :)
> 
> But this still wastes memory, why not just allocate each loop device
> dynamically when it is set up? The current approach is crap, it is just
> wasting memory for loop devices, queues, etc.
> 

Sure, but it's the first Tomas patch :)

Apparently the 'current crap' didnt caugth someone else attention.

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

* Re: max_loop limit
  2007-03-22 13:52         ` Eric Dumazet
@ 2007-03-22 13:54           ` Jens Axboe
  2007-03-22 14:11             ` William Lee Irwin III
       [not found]             ` <20070322151826.c1421851.dada1@cosmosbay.com>
  0 siblings, 2 replies; 30+ messages in thread
From: Jens Axboe @ 2007-03-22 13:54 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Tomas M, linux-kernel

On Thu, Mar 22 2007, Eric Dumazet wrote:
> On Thu, 22 Mar 2007 14:42:31 +0100
> Jens Axboe <jens.axboe@oracle.com> wrote:
> 
> 
> > > This time, you would be limited to 16384 loop devices on x86_64, 32768 on i386 :)
> > 
> > But this still wastes memory, why not just allocate each loop device
> > dynamically when it is set up? The current approach is crap, it is just
> > wasting memory for loop devices, queues, etc.
> > 
> 
> Sure, but it's the first Tomas patch :)

The more the reason to guide him in the direction of a right solution,
instead of extending the current bad one!

> Apparently the 'current crap' didnt caugth someone else attention.

I guess most people don't care, 8 is enough for them and the wasted
memory isn't too much to care about - 8 devices and only one used, is
wasting at least ~14kb on my machine here.

-- 
Jens Axboe


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

* Re: max_loop limit
  2007-03-22 13:54           ` Jens Axboe
@ 2007-03-22 14:11             ` William Lee Irwin III
  2007-03-22 15:22               ` Arjan van de Ven
  2007-03-22 16:09               ` Pádraig Brady
       [not found]             ` <20070322151826.c1421851.dada1@cosmosbay.com>
  1 sibling, 2 replies; 30+ messages in thread
From: William Lee Irwin III @ 2007-03-22 14:11 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Eric Dumazet, Tomas M, linux-kernel

On Thu, Mar 22 2007, Eric Dumazet wrote:
>> Sure, but it's the first Tomas patch :)

On Thu, Mar 22, 2007 at 02:54:57PM +0100, Jens Axboe wrote:
> The more the reason to guide him in the direction of a right solution,
> instead of extending the current bad one!

On Thu, Mar 22 2007, Eric Dumazet wrote:
>> Apparently the 'current crap' didnt caugth someone else attention.

On Thu, Mar 22, 2007 at 02:54:57PM +0100, Jens Axboe wrote:
> I guess most people don't care, 8 is enough for them and the wasted
> memory isn't too much to care about - 8 devices and only one used, is
> wasting at least ~14kb on my machine here.

Any chance we can get some kind of devices set up for partitions of
loop devices if we're going to redo loopdev setup? That's been a thorn
in my side for some time.


-- wli

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

* Re: max_loop limit
  2007-03-22 13:42     ` Eric Dumazet
  2007-03-22 13:42       ` Jens Axboe
@ 2007-03-22 14:25       ` Tomas M
  2007-03-23  1:34       ` Jan Engelhardt
  2 siblings, 0 replies; 30+ messages in thread
From: Tomas M @ 2007-03-22 14:25 UTC (permalink / raw)
  To: linux-kernel

> You might want a more radical patch : 

I agree that my patch is not the perfect solution for max_loop problem.
But it nearly doubles max_loop for me (using 386 arch) and moreover it 
is a FIX for incorrect implementation in kernel IMHO. So I can see 
REASON to include it in Kernel. Do I cry at the correct tomb? :)

> 
> Instead of using :
> ::
> Switch to :
> ::

I'm not any professional kernel hacker, so I don't understand the 
mysteries regarding ** (pointers to pointers?). Is there anyone who 
could provide CLEAN patch for loop.c, which would raise the max_loop 
limit to (at least) 1024 and which would be ACCEPTED to mainline kernel 
any soon?

I'm offering MONEY for this task.
Let's say $256 ;-)
I hope I didn't offend anyone by this offer.



Tomas M
slax.org

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

* Re: max_loop limit
  2007-03-22 13:42       ` Jens Axboe
  2007-03-22 13:52         ` Eric Dumazet
@ 2007-03-22 14:33         ` Al Viro
  2007-03-22 19:51           ` Olivier Galibert
  1 sibling, 1 reply; 30+ messages in thread
From: Al Viro @ 2007-03-22 14:33 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Eric Dumazet, Tomas M, linux-kernel

On Thu, Mar 22, 2007 at 02:42:31PM +0100, Jens Axboe wrote:
> But this still wastes memory, why not just allocate each loop device
> dynamically when it is set up? The current approach is crap, it is just
> wasting memory for loop devices, queues, etc.

Correction: current ABI is crap.  To set the thing up you need to open
it and issue an ioctl.  Which is a bloody bad idea, for obvious reasons...

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

* Re: max_loop limit
  2007-03-22 14:11             ` William Lee Irwin III
@ 2007-03-22 15:22               ` Arjan van de Ven
  2007-03-22 16:09               ` Pádraig Brady
  1 sibling, 0 replies; 30+ messages in thread
From: Arjan van de Ven @ 2007-03-22 15:22 UTC (permalink / raw)
  To: William Lee Irwin III; +Cc: Jens Axboe, Eric Dumazet, Tomas M, linux-kernel

On Thu, 2007-03-22 at 07:11 -0700, William Lee Irwin III wrote:
> On Thu, Mar 22 2007, Eric Dumazet wrote:
> >> Sure, but it's the first Tomas patch :)
> 
> On Thu, Mar 22, 2007 at 02:54:57PM +0100, Jens Axboe wrote:
> > The more the reason to guide him in the direction of a right solution,
> > instead of extending the current bad one!
> 
> On Thu, Mar 22 2007, Eric Dumazet wrote:
> >> Apparently the 'current crap' didnt caugth someone else attention.
> 
> On Thu, Mar 22, 2007 at 02:54:57PM +0100, Jens Axboe wrote:
> > I guess most people don't care, 8 is enough for them and the wasted
> > memory isn't too much to care about - 8 devices and only one used, is
> > wasting at least ~14kb on my machine here.
> 
> Any chance we can get some kind of devices set up for partitions of
> loop devices if we're going to redo loopdev setup? That's been a thorn
> in my side for some time.

you can already do that with devmapper and partx combo...



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

* Re: max_loop limit - paid job offer
       [not found]                 ` <20070322153603.1f5d442d.dada1@cosmosbay.com>
@ 2007-03-22 15:31                   ` Tomas M
  0 siblings, 0 replies; 30+ messages in thread
From: Tomas M @ 2007-03-22 15:31 UTC (permalink / raw)
  To: linux-kernel

> Really, I dont think Tomas has the skill or time to follow a typical
> lkml discussion.
> 

Well I have the skills to follow LKML discussion, but I don't have the 
skills to provide *perfect* patch for loop.c

So I'm offering a financial reward for the *perfect* loop.c patch.
It should support *A LOT OF* loop devices without any need to specify 
any max_loop at all.

I offered $256 in my previous email, I don't know if this is enough for 
this job, so I'm open to all your suggestions. Is there anyone interested?

If you hate these offers on LKML then let me know please, I'm just used 
to pay for others' time, I hope it doesn't offend you.

Thank you for your consideration.

Tomas M
slax.org

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

* Re: max_loop limit
  2007-03-22 14:11             ` William Lee Irwin III
  2007-03-22 15:22               ` Arjan van de Ven
@ 2007-03-22 16:09               ` Pádraig Brady
  2007-03-28 23:34                 ` Karel Zak
  1 sibling, 1 reply; 30+ messages in thread
From: Pádraig Brady @ 2007-03-22 16:09 UTC (permalink / raw)
  To: William Lee Irwin III; +Cc: Jens Axboe, Eric Dumazet, Tomas M, linux-kernel

William Lee Irwin III wrote:
> Any chance we can get some kind of devices set up for partitions of
> loop devices if we're going to redo loopdev setup? That's been a thorn
> in my side for some time.

This script might be of use:
http://www.pixelbeat.org/scripts/lomount.sh

cheers,
Pádraig.

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

* Re: max_loop limit
  2007-03-22 14:33         ` max_loop limit Al Viro
@ 2007-03-22 19:51           ` Olivier Galibert
  0 siblings, 0 replies; 30+ messages in thread
From: Olivier Galibert @ 2007-03-22 19:51 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel

On Thu, Mar 22, 2007 at 02:33:14PM +0000, Al Viro wrote:
> Correction: current ABI is crap.  To set the thing up you need to open
> it and issue an ioctl.  Which is a bloody bad idea, for obvious reasons...

Agreed.  What would be a right way?  Global device ala ptmx/tun/tap?
New syscall?  Something else?

  OG.

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

* Re: max_loop limit
  2007-03-22 13:42     ` Eric Dumazet
  2007-03-22 13:42       ` Jens Axboe
  2007-03-22 14:25       ` Tomas M
@ 2007-03-23  1:34       ` Jan Engelhardt
  2007-03-23 23:26         ` [PATCH] " Jan Engelhardt
  2 siblings, 1 reply; 30+ messages in thread
From: Jan Engelhardt @ 2007-03-23  1:34 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Tomas M, linux-kernel


On Mar 22 2007 14:42, Eric Dumazet wrote:
>Instead of using :
>
>static struct loop_device *loop_dev;
>loop_dev = kmalloc(max_loop * sizeof(struct loop_device));
>
>Switch to :
>
>static struct loop_device **loop_dev;
>loop_dev = kmalloc(max_loop * sizeof(void *));
>if (!loop_dev) rollback...
>for (i = 0 ; i < max_loop ; i++) {
>	loop_dev[i] = kmalloc(sizeof(struct loop_device));
>	if (!loop_dev[i]) rollback...
>}
>
>This time, you would be limited to 16384 loop devices on x86_64, 32768 on i386
>:)

Oh noes. Please use a linked list (kmalloc cope = perfect) if you really need
loads of loopdevs. Sorta

 struct loopdev {
    struct list_head lh;
    int lo_number;
 };

to keep the /dev/loop%d number consistent across loopdev removal.
Maybe it's better to even use an rbtree (linked list does not scale to it).


Jan
-- 

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

* [PATCH] max_loop limit
  2007-03-23  1:34       ` Jan Engelhardt
@ 2007-03-23 23:26         ` Jan Engelhardt
  2007-03-25  0:17           ` Ken Chen
                             ` (3 more replies)
  0 siblings, 4 replies; 30+ messages in thread
From: Jan Engelhardt @ 2007-03-23 23:26 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Tomas M, Linux Kernel Mailing List

Hi,


here's one. Allocates all the fluff dynamically. It does not create any
dev nodes by itself, so you need to do it (à la mdadm), but you'll get all
1048576 available minors.

Sadly, it locks up the foreground process (losetup that would be), and I
have not yet figured out why. And the mpt regression elsewhere is
hindering me in finding out faster.

Signed-off-by: Jan Engelhardt <jengelh@gmx.de>

Index: linux-2.6.21-rc4/drivers/block/loop.c
===================================================================
--- linux-2.6.21-rc4.orig/drivers/block/loop.c
+++ linux-2.6.21-rc4/drivers/block/loop.c
@@ -77,9 +77,8 @@
 
 #include <asm/uaccess.h>
 
-static int max_loop = 8;
-static struct loop_device *loop_dev;
-static struct gendisk **disks;
+static LIST_HEAD(loop_devices);
+static DEFINE_SPINLOCK(loop_devices_lock);
 
 /*
  * Transfer functions
@@ -183,7 +182,7 @@ figure_loop_size(struct loop_device *lo)
 	if (unlikely((loff_t)x != size))
 		return -EFBIG;
 
-	set_capacity(disks[lo->lo_number], x);
+	set_capacity(lo->lo_disk, x);
 	return 0;					
 }
 
@@ -812,7 +811,7 @@ static int loop_set_fd(struct loop_devic
 	lo->lo_queue->queuedata = lo;
 	lo->lo_queue->unplug_fn = loop_unplug;
 
-	set_capacity(disks[lo->lo_number], size);
+	set_capacity(lo->lo_disk, size);
 	bd_set_size(bdev, size << 9);
 
 	set_blocksize(bdev, lo_blocksize);
@@ -832,7 +831,7 @@ out_clr:
 	lo->lo_device = NULL;
 	lo->lo_backing_file = NULL;
 	lo->lo_flags = 0;
-	set_capacity(disks[lo->lo_number], 0);
+	set_capacity(lo->lo_disk, 0);
 	invalidate_bdev(bdev, 0);
 	bd_set_size(bdev, 0);
 	mapping_set_gfp_mask(mapping, lo->old_gfp_mask);
@@ -918,7 +917,7 @@ static int loop_clr_fd(struct loop_devic
 	memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
 	memset(lo->lo_file_name, 0, LO_NAME_SIZE);
 	invalidate_bdev(bdev, 0);
-	set_capacity(disks[lo->lo_number], 0);
+	set_capacity(lo->lo_disk, 0);
 	bd_set_size(bdev, 0);
 	mapping_set_gfp_mask(filp->f_mapping, gfp);
 	lo->lo_state = Lo_unbound;
@@ -1357,8 +1356,6 @@ static struct block_device_operations lo
 /*
  * And now the modules code and kernel interface.
  */
-module_param(max_loop, int, 0);
-MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
@@ -1383,7 +1380,7 @@ int loop_unregister_transfer(int number)
 
 	xfer_funcs[n] = NULL;
 
-	for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
+	list_for_each_entry(lo, &loop_devices, lo_list) {
 		mutex_lock(&lo->lo_ctl_mutex);
 
 		if (lo->lo_encryption == xfer)
@@ -1398,102 +1395,102 @@ int loop_unregister_transfer(int number)
 EXPORT_SYMBOL(loop_register_transfer);
 EXPORT_SYMBOL(loop_unregister_transfer);
 
-static int __init loop_init(void)
+static struct loop_device *loop_find_dev(unsigned int number)
+{
+	struct loop_device *lo;
+	list_for_each_entry(lo, &loop_devices, lo_list)
+		if (lo->lo_number == number)
+			return lo;
+	return NULL;
+}
+
+static struct loop_device *loop_init_one(unsigned int number)
 {
-	int	i;
+	struct loop_device *lo;
+	struct gendisk *disk;
+
+	lo = kzalloc(sizeof(struct loop_device), GFP_KERNEL);
+	if (lo == NULL)
+		goto out;
+
+	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
+	if (lo->lo_queue == NULL)
+		goto out_free_dev;
+
+	disk = lo->lo_disk = alloc_disk(1);
+	if (disk == NULL)
+		goto out_free_queue;
+
+	mutex_init(&lo->lo_ctl_mutex);
+	lo->lo_number      = number;
+	lo->lo_thread      = NULL;
+	init_waitqueue_head(&lo->lo_event);
+	spin_lock_init(&lo->lo_lock);
+	disk->major        = LOOP_MAJOR;
+	disk->first_minor  = number;
+	disk->fops         = &lo_fops;
+	disk->private_data = lo;
+	disk->queue        = lo->lo_queue;
+	sprintf(disk->disk_name, "loop%u", number);
+	add_disk(lo->lo_disk);
+
+	spin_lock(&loop_devices_lock);
+	list_add_tail(&lo->lo_list, &loop_devices);
+	spin_unlock(&loop_devices_lock);
+	return lo;
+
+ out_free_queue:
+	blk_cleanup_queue(lo->lo_queue);
+ out_free_dev:
+	kfree(lo);
+ out:
+	return ERR_PTR(-ENOMEM);
+}
+
+static void loop_del_one(struct loop_device *lo)
+{
+	del_gendisk(lo->lo_disk);
+	blk_cleanup_queue(lo->lo_queue);
+	put_disk(lo->lo_disk);
+	list_del(&lo->lo_list);
+	kfree(lo);
+	return;
+}
+
+static struct kobject *loop_probe(dev_t dev, int *part, void *data)
+{
+	unsigned int number = dev & MINORMASK;
+	struct loop_device *lo;
 
-	if (max_loop < 1 || max_loop > 256) {
-		printk(KERN_WARNING "loop: invalid max_loop (must be between"
-				    " 1 and 256), using default (8)\n");
-		max_loop = 8;
+	if ((lo = loop_find_dev(number)) == NULL) {
+		lo = loop_init_one(number);
+		if (IS_ERR(lo))
+			return (void *)lo;
 	}
 
+	return &lo->lo_disk->kobj;
+}
+
+static int __init loop_init(void)
+{
 	if (register_blkdev(LOOP_MAJOR, "loop"))
 		return -EIO;
-
-	loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
-	if (!loop_dev)
-		goto out_mem1;
-	memset(loop_dev, 0, max_loop * sizeof(struct loop_device));
-
-	disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL);
-	if (!disks)
-		goto out_mem2;
-
-	for (i = 0; i < max_loop; i++) {
-		disks[i] = alloc_disk(1);
-		if (!disks[i])
-			goto out_mem3;
-	}
-
-	for (i = 0; i < max_loop; i++) {
-		struct loop_device *lo = &loop_dev[i];
-		struct gendisk *disk = disks[i];
-
-		memset(lo, 0, sizeof(*lo));
-		lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
-		if (!lo->lo_queue)
-			goto out_mem4;
-		mutex_init(&lo->lo_ctl_mutex);
-		lo->lo_number = i;
-		lo->lo_thread = NULL;
-		init_waitqueue_head(&lo->lo_event);
-		spin_lock_init(&lo->lo_lock);
-		disk->major = LOOP_MAJOR;
-		disk->first_minor = i;
-		disk->fops = &lo_fops;
-		sprintf(disk->disk_name, "loop%d", i);
-		disk->private_data = lo;
-		disk->queue = lo->lo_queue;
-	}
-
-	/* We cannot fail after we call this, so another loop!*/
-	for (i = 0; i < max_loop; i++)
-		add_disk(disks[i]);
-	printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
+	blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
+	                    THIS_MODULE, loop_probe, NULL, NULL);
 	return 0;
+}
 
-out_mem4:
-	while (i--)
-		blk_cleanup_queue(loop_dev[i].lo_queue);
-	i = max_loop;
-out_mem3:
-	while (i--)
-		put_disk(disks[i]);
-	kfree(disks);
-out_mem2:
-	kfree(loop_dev);
-out_mem1:
-	unregister_blkdev(LOOP_MAJOR, "loop");
-	printk(KERN_ERR "loop: ran out of memory\n");
-	return -ENOMEM;
-}
-
-static void loop_exit(void)
-{
-	int i;
-
-	for (i = 0; i < max_loop; i++) {
-		del_gendisk(disks[i]);
-		blk_cleanup_queue(loop_dev[i].lo_queue);
-		put_disk(disks[i]);
-	}
+static void __exit loop_exit(void)
+{
+	struct loop_device *lo, *next;
+
+	list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
+		loop_del_one(lo);
+
+	blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS);
 	if (unregister_blkdev(LOOP_MAJOR, "loop"))
 		printk(KERN_WARNING "loop: cannot unregister blkdev\n");
-
-	kfree(disks);
-	kfree(loop_dev);
 }
 
 module_init(loop_init);
 module_exit(loop_exit);
-
-#ifndef MODULE
-static int __init max_loop_setup(char *str)
-{
-	max_loop = simple_strtol(str, NULL, 0);
-	return 1;
-}
-
-__setup("max_loop=", max_loop_setup);
-#endif
Index: linux-2.6.21-rc4/include/linux/loop.h
===================================================================
--- linux-2.6.21-rc4.orig/include/linux/loop.h
+++ linux-2.6.21-rc4/include/linux/loop.h
@@ -16,6 +16,7 @@
 #ifdef __KERNEL__
 #include <linux/bio.h>
 #include <linux/blkdev.h>
+#include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 
@@ -29,7 +30,8 @@ enum {
 struct loop_func_table;
 
 struct loop_device {
-	int		lo_number;
+	struct list_head lo_list;
+	unsigned int	lo_number;
 	int		lo_refcnt;
 	loff_t		lo_offset;
 	loff_t		lo_sizelimit;
@@ -50,6 +52,7 @@ struct loop_device {
 
 	struct file *	lo_backing_file;
 	struct block_device *lo_device;
+	struct gendisk *lo_disk;
 	unsigned	lo_blocksize;
 	void		*key_data; 
 
#<EOF>


Jan
-- 

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

* Re: [PATCH] max_loop limit
  2007-03-23 23:26         ` [PATCH] " Jan Engelhardt
@ 2007-03-25  0:17           ` Ken Chen
  2007-03-25  0:29           ` Ken Chen
                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 30+ messages in thread
From: Ken Chen @ 2007-03-25  0:17 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Eric Dumazet, Tomas M, Linux Kernel Mailing List

On 3/23/07, Jan Engelhardt <jengelh@linux01.gwdg.de> wrote:
> Sadly, it locks up the foreground process (losetup that would be), and I
> have not yet figured out why. And the mpt regression elsewhere is
> hindering me in finding out faster.

You need to tell the block layer that each loop device is a whole
block device, not a partition within another device. Otherwise, I
think it will cause a recursive mutex lock in block_dev.c:do_open().

This patch should fix the problem.

Signed-off-by: Ken Chen <kenchen@google.com>

--- ./drivers/block/loop.c.orig	2007-03-24 17:05:51.000000000 -0700
+++ ./drivers/block/loop.c	2007-03-24 17:06:06.000000000 -0700
@@ -1464,6 +1464,7 @@

 	if ((lo = loop_find_dev(number)) == NULL) {
 		lo = loop_init_one(number);
+		*part = 0;
 		if (IS_ERR(lo))
 			return (void *)lo;
 	}

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

* Re: [PATCH] max_loop limit
  2007-03-23 23:26         ` [PATCH] " Jan Engelhardt
  2007-03-25  0:17           ` Ken Chen
@ 2007-03-25  0:29           ` Ken Chen
  2007-03-25  8:40           ` Tomas M
  2007-03-29  3:54           ` Kyle Moffett
  3 siblings, 0 replies; 30+ messages in thread
From: Ken Chen @ 2007-03-25  0:29 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Eric Dumazet, Tomas M, Linux Kernel Mailing List

On 3/23/07, Jan Engelhardt <jengelh@linux01.gwdg.de> wrote:
> @@ -1383,7 +1380,7 @@ int loop_unregister_transfer(int number)
>
>         xfer_funcs[n] = NULL;
>
> -       for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
> +       list_for_each_entry(lo, &loop_devices, lo_list) {
>                 mutex_lock(&lo->lo_ctl_mutex);

Don't you need to use loop_devices_lock to protect the linked list here?


> +static struct loop_device *loop_find_dev(unsigned int number)
> +{
> +       struct loop_device *lo;
> +       list_for_each_entry(lo, &loop_devices, lo_list)
> +               if (lo->lo_number == number)
> +                       return lo;
> +       return NULL;

Here too with spin lock??

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

* Re: [PATCH] max_loop limit
  2007-03-23 23:26         ` [PATCH] " Jan Engelhardt
  2007-03-25  0:17           ` Ken Chen
  2007-03-25  0:29           ` Ken Chen
@ 2007-03-25  8:40           ` Tomas M
  2007-03-28 23:41             ` Karel Zak
  2007-03-29  3:54           ` Kyle Moffett
  3 siblings, 1 reply; 30+ messages in thread
From: Tomas M @ 2007-03-25  8:40 UTC (permalink / raw)
  To: linux-kernel

> here's one. Allocates all the fluff dynamically. It does not create any
> dev nodes by itself, so you need to do it (à la mdadm)

I'm afraid that this would break a lot of things, for example mount -o 
loop will not work anymore unless you create /dev/loop* manually first, 
am I correct? In this case, this is unusable for many as it is not 
backward compatible with old loop.c, am I correct?


Tomas M
slax.org


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

* Re: max_loop limit
  2007-03-22 16:09               ` Pádraig Brady
@ 2007-03-28 23:34                 ` Karel Zak
  0 siblings, 0 replies; 30+ messages in thread
From: Karel Zak @ 2007-03-28 23:34 UTC (permalink / raw)
  To: Pádraig Brady
  Cc: William Lee Irwin III, Jens Axboe, Eric Dumazet, Tomas M, linux-kernel

On Thu, Mar 22, 2007 at 04:09:13PM +0000, Pádraig Brady wrote:
> William Lee Irwin III wrote:
> > Any chance we can get some kind of devices set up for partitions of
> > loop devices if we're going to redo loopdev setup? That's been a thorn
> > in my side for some time.
> 
> This script might be of use:
> http://www.pixelbeat.org/scripts/lomount.sh

 Ah, lomount... very popular name ;-) Xen guys have lomount too.
 
 Unfortunately, these solution are useless with LVM volumes. The
 kpartx is more usable:

 http://fedoraproject.org/wiki/FedoraXenQuickstartFC6?highlight=%28Xen%29#head-9c5408e750e8184aece3efe822be0ef6dd1871cd

    Karel

-- 
 Karel Zak  <kzak@redhat.com>

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

* Re: [PATCH] max_loop limit
  2007-03-25  8:40           ` Tomas M
@ 2007-03-28 23:41             ` Karel Zak
  0 siblings, 0 replies; 30+ messages in thread
From: Karel Zak @ 2007-03-28 23:41 UTC (permalink / raw)
  To: Tomas M; +Cc: linux-kernel

On Sun, Mar 25, 2007 at 10:40:10AM +0200, Tomas M wrote:
> >here's one. Allocates all the fluff dynamically. It does not create any
> >dev nodes by itself, so you need to do it (à la mdadm)
> 
> I'm afraid that this would break a lot of things, for example mount -o 
> loop will not work anymore unless you create /dev/loop* manually first, 

 Yes, "losetup" and "mount -o loop" call stat( /dev/loopN ) when look
 for an (un)used loop device.

> am I correct? In this case, this is unusable for many as it is not 
> backward compatible with old loop.c, am I correct?

 udev ?

        Karel

-- 
 Karel Zak  <kzak@redhat.com>

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

* Re: [PATCH] max_loop limit
  2007-03-23 23:26         ` [PATCH] " Jan Engelhardt
                             ` (2 preceding siblings ...)
  2007-03-25  8:40           ` Tomas M
@ 2007-03-29  3:54           ` Kyle Moffett
  2007-03-29  4:16             ` [PATCH] max_loop limit, t2 Jan Engelhardt
  3 siblings, 1 reply; 30+ messages in thread
From: Kyle Moffett @ 2007-03-29  3:54 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Eric Dumazet, Tomas M, Linux Kernel Mailing List

On Mar 23, 2007, at 19:26:34, Jan Engelhardt wrote:
> here's one. Allocates all the fluff dynamically. It does not create  
> any dev nodes by itself, so you need to do it (à la mdadm), but  
> you'll get all 1048576 available minors.
>
> +static LIST_HEAD(loop_devices);

Maybe an rbtree would work better here?  Maximum number of nodes  
traversed to get to the bottom of the tree given 2^(20) loop devices  
is 19 as opposed to the 2^(20) for a linked list.  Also, to preserve  
compatibility with existing userspace loop tools you should probably  
always allocate one extra loop device.  Keep a "highest used loopdev"  
number and create the one after that so that udev will autocreate a  
dev node for it.

Cheers,
Kyle Moffett


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

* Re: [PATCH] max_loop limit, t2
  2007-03-29  3:54           ` Kyle Moffett
@ 2007-03-29  4:16             ` Jan Engelhardt
  2007-03-29  8:38               ` [PATCH] max_loop limit, loop.c final working version Tomas M
  0 siblings, 1 reply; 30+ messages in thread
From: Jan Engelhardt @ 2007-03-29  4:16 UTC (permalink / raw)
  To: Kyle Moffett; +Cc: Eric Dumazet, Tomas M, Linux Kernel Mailing List



On Mar 25 2007 10:40, Tomas M wrote:
>On ??, Jan Engelhardt wrote:
>
>> here's one. Allocates all the fluff dynamically. It does not
>> create any dev nodes by itself, so you need to do it (à la mdadm)
>
> I'm afraid that this would break a lot of things, for example mount
> -o loop will not work anymore unless you create /dev/loop* manually
> first, am I correct? In this case, this is unusable for many as it
> is not backward compatible with old loop.c, am I correct?

So here's another try. Use the max_auto_loop= module parameter to
define how many device nodes should be created (defaults to 8, like
original loop.c) in advance. (More specifically, how many disks you
want uevents have generated.) This is because creating all 1048576
possible loop disks in /dev (tmpfs!!) would be really overkill and
seldom good for memory usage.


On Mar 28 2007 23:54, Kyle Moffett wrote:

> Maybe an rbtree would work better here?  Maximum number of nodes
> traversed to get to the bottom of the tree given 2^(20) loop
> devices is 19 as opposed to the 2^(20) for a linked list.  Also, to
> preserve compatibility with existing userspace loop tools you
> should probably always allocate one extra loop device. Keep a
> "highest used loopdev" number and create the one after that so that
> udev will autocreate a dev node for it.

Yeah I already have a ... hack that creates /dev/loop[0-7] but it
segfaults ^_^ Perhaps someone knows why. The oops trace I get has
kobject_uevent() in it, but I don't think I missed something in the
_init function wrt. uevent generation, did I?

Signed-off-by: Jan Engelhardt <jengelh@gmx.de>

Name: dynamic-loop-jengelh2.diff

Index: linux-2.6.21-rc5/drivers/block/Makefile
===================================================================
--- linux-2.6.21-rc5.orig/drivers/block/Makefile
+++ linux-2.6.21-rc5/drivers/block/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_VIODASD)		+= viodasd.o
 obj-$(CONFIG_BLK_DEV_SX8)	+= sx8.o
 obj-$(CONFIG_BLK_DEV_UB)	+= ub.o
 
+CFLAGS_loop.o += -O0
Index: linux-2.6.21-rc5/drivers/block/loop.c
===================================================================
--- linux-2.6.21-rc5.orig/drivers/block/loop.c
+++ linux-2.6.21-rc5/drivers/block/loop.c
@@ -77,9 +77,9 @@
 
 #include <asm/uaccess.h>
 
-static int max_loop = 8;
-static struct loop_device *loop_dev;
-static struct gendisk **disks;
+static unsigned int max_auto_loop = 8;
+static LIST_HEAD(loop_devices);
+static DEFINE_SPINLOCK(loop_devices_lock);
 
 /*
  * Transfer functions
@@ -183,7 +183,7 @@ figure_loop_size(struct loop_device *lo)
 	if (unlikely((loff_t)x != size))
 		return -EFBIG;
 
-	set_capacity(disks[lo->lo_number], x);
+	set_capacity(lo->lo_disk, x);
 	return 0;					
 }
 
@@ -812,7 +812,7 @@ static int loop_set_fd(struct loop_devic
 	lo->lo_queue->queuedata = lo;
 	lo->lo_queue->unplug_fn = loop_unplug;
 
-	set_capacity(disks[lo->lo_number], size);
+	set_capacity(lo->lo_disk, size);
 	bd_set_size(bdev, size << 9);
 
 	set_blocksize(bdev, lo_blocksize);
@@ -832,7 +832,7 @@ out_clr:
 	lo->lo_device = NULL;
 	lo->lo_backing_file = NULL;
 	lo->lo_flags = 0;
-	set_capacity(disks[lo->lo_number], 0);
+	set_capacity(lo->lo_disk, 0);
 	invalidate_bdev(bdev, 0);
 	bd_set_size(bdev, 0);
 	mapping_set_gfp_mask(mapping, lo->old_gfp_mask);
@@ -918,7 +918,7 @@ static int loop_clr_fd(struct loop_devic
 	memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
 	memset(lo->lo_file_name, 0, LO_NAME_SIZE);
 	invalidate_bdev(bdev, 0);
-	set_capacity(disks[lo->lo_number], 0);
+	set_capacity(lo->lo_disk, 0);
 	bd_set_size(bdev, 0);
 	mapping_set_gfp_mask(filp->f_mapping, gfp);
 	lo->lo_state = Lo_unbound;
@@ -1357,8 +1357,9 @@ static struct block_device_operations lo
 /*
  * And now the modules code and kernel interface.
  */
-module_param(max_loop, int, 0);
-MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)");
+module_param(max_auto_loop, uint, S_IRUGO);
+MODULE_PARM_DESC(max_auto_loop, "Maximum number of auto-generated loop device "
+	"nodes (0-1048576)");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
@@ -1383,7 +1384,7 @@ int loop_unregister_transfer(int number)
 
 	xfer_funcs[n] = NULL;
 
-	for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
+	list_for_each_entry(lo, &loop_devices, lo_list) {
 		mutex_lock(&lo->lo_ctl_mutex);
 
 		if (lo->lo_encryption == xfer)
@@ -1398,102 +1399,120 @@ int loop_unregister_transfer(int number)
 EXPORT_SYMBOL(loop_register_transfer);
 EXPORT_SYMBOL(loop_unregister_transfer);
 
-static int __init loop_init(void)
+static struct loop_device *loop_find_dev(unsigned int number)
+{
+	struct loop_device *lo;
+	list_for_each_entry(lo, &loop_devices, lo_list)
+		if (lo->lo_number == number)
+			return lo;
+	return NULL;
+}
+
+static struct loop_device *loop_init_one(unsigned int number)
 {
-	int	i;
+	struct loop_device *lo;
+	struct gendisk *disk;
+
+	lo = kzalloc(sizeof(struct loop_device), GFP_KERNEL);
+	if (lo == NULL)
+		goto out;
 
-	if (max_loop < 1 || max_loop > 256) {
-		printk(KERN_WARNING "loop: invalid max_loop (must be between"
-				    " 1 and 256), using default (8)\n");
-		max_loop = 8;
+	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
+	if (lo->lo_queue == NULL)
+		goto out_free_dev;
+
+	disk = lo->lo_disk = alloc_disk(1);
+	if (disk == NULL)
+		goto out_free_queue;
+
+	mutex_init(&lo->lo_ctl_mutex);
+	lo->lo_number      = number;
+	lo->lo_thread      = NULL;
+	init_waitqueue_head(&lo->lo_event);
+	spin_lock_init(&lo->lo_lock);
+	disk->major        = LOOP_MAJOR;
+	disk->first_minor  = number;
+	disk->fops         = &lo_fops;
+	disk->private_data = lo;
+	disk->queue        = lo->lo_queue;
+	sprintf(disk->disk_name, "loop%u", number);
+	add_disk(lo->lo_disk);
+
+	spin_lock(&loop_devices_lock);
+	list_add_tail(&lo->lo_list, &loop_devices);
+	spin_unlock(&loop_devices_lock);
+	return lo;
+
+ out_free_queue:
+	blk_cleanup_queue(lo->lo_queue);
+ out_free_dev:
+	kfree(lo);
+ out:
+	return ERR_PTR(-ENOMEM);
+}
+
+static void loop_del_one(struct loop_device *lo)
+{
+	del_gendisk(lo->lo_disk);
+	blk_cleanup_queue(lo->lo_queue);
+	put_disk(lo->lo_disk);
+	list_del(&lo->lo_list);
+	kfree(lo);
+	return;
+}
+
+static struct kobject *loop_probe(dev_t dev, int *part, void *data)
+{
+	unsigned int number = dev & MINORMASK;
+	struct loop_device *lo;
+
+	if ((lo = loop_find_dev(number)) == NULL) {
+		lo = loop_init_one(number);
+		if (IS_ERR(lo))
+			return (void *)lo;
+		*part = 0;
 	}
 
+	return &lo->lo_disk->kobj;
+}
+
+static int __init loop_init(void)
+{
+	struct kobject kobj;
+	int i;
+
 	if (register_blkdev(LOOP_MAJOR, "loop"))
 		return -EIO;
+	blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
+	                    THIS_MODULE, loop_probe, NULL, NULL);
 
-	loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
-	if (!loop_dev)
-		goto out_mem1;
-	memset(loop_dev, 0, max_loop * sizeof(struct loop_device));
-
-	disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL);
-	if (!disks)
-		goto out_mem2;
-
-	for (i = 0; i < max_loop; i++) {
-		disks[i] = alloc_disk(1);
-		if (!disks[i])
-			goto out_mem3;
-	}
-
-	for (i = 0; i < max_loop; i++) {
-		struct loop_device *lo = &loop_dev[i];
-		struct gendisk *disk = disks[i];
-
-		memset(lo, 0, sizeof(*lo));
-		lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
-		if (!lo->lo_queue)
-			goto out_mem4;
-		mutex_init(&lo->lo_ctl_mutex);
-		lo->lo_number = i;
-		lo->lo_thread = NULL;
-		init_waitqueue_head(&lo->lo_event);
-		spin_lock_init(&lo->lo_lock);
-		disk->major = LOOP_MAJOR;
-		disk->first_minor = i;
-		disk->fops = &lo_fops;
-		sprintf(disk->disk_name, "loop%d", i);
-		disk->private_data = lo;
-		disk->queue = lo->lo_queue;
-	}
-
-	/* We cannot fail after we call this, so another loop!*/
-	for (i = 0; i < max_loop; i++)
-		add_disk(disks[i]);
-	printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
-	return 0;
+	/* Trigger uevents so that /dev nodes get created by udev */
+	for (i = 0; i < max_auto_loop; ++i) {
+		kobject_init(&kobj);
+		if (kobject_set_name(&kobj, "loop%u", i) != 0)
+			/*
+			 * Most likely the Out Of Memory case. Do not try to
+			 * create more objects.
+			 */
+			break;
+		kobject_uevent(&kobj, KOBJ_ADD);
+		kobject_put(&kobj);
+	}
 
-out_mem4:
-	while (i--)
-		blk_cleanup_queue(loop_dev[i].lo_queue);
-	i = max_loop;
-out_mem3:
-	while (i--)
-		put_disk(disks[i]);
-	kfree(disks);
-out_mem2:
-	kfree(loop_dev);
-out_mem1:
-	unregister_blkdev(LOOP_MAJOR, "loop");
-	printk(KERN_ERR "loop: ran out of memory\n");
-	return -ENOMEM;
+	return 0;
 }
 
-static void loop_exit(void)
+static void __exit loop_exit(void)
 {
-	int i;
+	struct loop_device *lo, *next;
 
-	for (i = 0; i < max_loop; i++) {
-		del_gendisk(disks[i]);
-		blk_cleanup_queue(loop_dev[i].lo_queue);
-		put_disk(disks[i]);
-	}
+	list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
+		loop_del_one(lo);
+
+	blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS);
 	if (unregister_blkdev(LOOP_MAJOR, "loop"))
 		printk(KERN_WARNING "loop: cannot unregister blkdev\n");
-
-	kfree(disks);
-	kfree(loop_dev);
 }
 
 module_init(loop_init);
 module_exit(loop_exit);
-
-#ifndef MODULE
-static int __init max_loop_setup(char *str)
-{
-	max_loop = simple_strtol(str, NULL, 0);
-	return 1;
-}
-
-__setup("max_loop=", max_loop_setup);
-#endif
Index: linux-2.6.21-rc5/include/linux/loop.h
===================================================================
--- linux-2.6.21-rc5.orig/include/linux/loop.h
+++ linux-2.6.21-rc5/include/linux/loop.h
@@ -16,6 +16,7 @@
 #ifdef __KERNEL__
 #include <linux/bio.h>
 #include <linux/blkdev.h>
+#include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 
@@ -29,7 +30,8 @@ enum {
 struct loop_func_table;
 
 struct loop_device {
-	int		lo_number;
+	struct list_head lo_list;
+	unsigned int	lo_number;
 	int		lo_refcnt;
 	loff_t		lo_offset;
 	loff_t		lo_sizelimit;
@@ -50,6 +52,7 @@ struct loop_device {
 
 	struct file *	lo_backing_file;
 	struct block_device *lo_device;
+	struct gendisk *lo_disk;
 	unsigned	lo_blocksize;
 	void		*key_data; 
 
#<EOF>


Jan
-- 

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

* Re: [PATCH] max_loop limit, loop.c final working version
  2007-03-29  4:16             ` [PATCH] max_loop limit, t2 Jan Engelhardt
@ 2007-03-29  8:38               ` Tomas M
  0 siblings, 0 replies; 30+ messages in thread
From: Tomas M @ 2007-03-29  8:38 UTC (permalink / raw)
  To: Jan Engelhardt, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 714 bytes --]

This is a diff from Ken Chen, who sent it to me a week ago and received 
the claimed prize $256. I think it's partially based on Jan's code, 
while if fixes the bug Jan mentioned (as far as I know).

It does the following:
- allocate loop dynamically on the fly
- allocate one more (spare) loop each time,
   so losetup and mount tools can work correctly
- doesn't need any module parameters

Unfortunately 'mount' and 'losetup' binaries are hardcoded to stop 
searching for free loop device after the minor num 255, so one have to 
use a workaround in order to use more loops with 'mount':

$ losetup /dev/loop1000 file
$ mount /dev/loop1000 /mntpnt

I hope these binaries will be fixed soon.


Tomas M
slax.org


[-- Attachment #2: loop.c.diff --]
[-- Type: text/x-patch, Size: 7610 bytes --]

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 6b5b642..7db2c38 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -77,9 +77,8 @@ #include <linux/kthread.h>
 
 #include <asm/uaccess.h>
 
-static int max_loop = 8;
-static struct loop_device *loop_dev;
-static struct gendisk **disks;
+static LIST_HEAD(loop_devices);
+static DEFINE_SPINLOCK(loop_devices_lock);
 
 /*
  * Transfer functions
@@ -183,7 +182,7 @@ figure_loop_size(struct loop_device *lo)
 	if (unlikely((loff_t)x != size))
 		return -EFBIG;
 
-	set_capacity(disks[lo->lo_number], x);
+	set_capacity(lo->lo_disk, x);
 	return 0;					
 }
 
@@ -812,7 +811,7 @@ static int loop_set_fd(struct loop_devic
 	lo->lo_queue->queuedata = lo;
 	lo->lo_queue->unplug_fn = loop_unplug;
 
-	set_capacity(disks[lo->lo_number], size);
+	set_capacity(lo->lo_disk, size);
 	bd_set_size(bdev, size << 9);
 
 	set_blocksize(bdev, lo_blocksize);
@@ -832,7 +831,7 @@ out_clr:
 	lo->lo_device = NULL;
 	lo->lo_backing_file = NULL;
 	lo->lo_flags = 0;
-	set_capacity(disks[lo->lo_number], 0);
+	set_capacity(lo->lo_disk, 0);
 	invalidate_bdev(bdev, 0);
 	bd_set_size(bdev, 0);
 	mapping_set_gfp_mask(mapping, lo->old_gfp_mask);
@@ -918,7 +917,7 @@ static int loop_clr_fd(struct loop_devic
 	memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
 	memset(lo->lo_file_name, 0, LO_NAME_SIZE);
 	invalidate_bdev(bdev, 0);
-	set_capacity(disks[lo->lo_number], 0);
+	set_capacity(lo->lo_disk, 0);
 	bd_set_size(bdev, 0);
 	mapping_set_gfp_mask(filp->f_mapping, gfp);
 	lo->lo_state = Lo_unbound;
@@ -1322,6 +1321,23 @@ static long lo_compat_ioctl(struct file 
 }
 #endif
 
+static struct loop_device *loop_find_dev(int number)
+{
+	struct loop_device *lo;
+	int found = 0;
+		  
+	spin_lock(&loop_devices_lock);
+	list_for_each_entry(lo, &loop_devices, lo_list) {
+		if (lo->lo_number == number) {
+			found = 1;
+			break;
+		}
+	}
+	spin_unlock(&loop_devices_lock);
+	return found ? lo : NULL;
+}
+
+static struct loop_device *loop_init_one(int i);
 static int lo_open(struct inode *inode, struct file *file)
 {
 	struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -1330,6 +1346,9 @@ static int lo_open(struct inode *inode, 
 	lo->lo_refcnt++;
 	mutex_unlock(&lo->lo_ctl_mutex);
 
+	if (!loop_find_dev(lo->lo_number + 1))
+		loop_init_one(lo->lo_number + 1);
+
 	return 0;
 }
 
@@ -1357,8 +1376,6 @@ #endif
 /*
  * And now the modules code and kernel interface.
  */
-module_param(max_loop, int, 0);
-MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
@@ -1383,7 +1400,7 @@ int loop_unregister_transfer(int number)
 
 	xfer_funcs[n] = NULL;
 
-	for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
+	list_for_each_entry(lo, &loop_devices, lo_list) {
 		mutex_lock(&lo->lo_ctl_mutex);
 
 		if (lo->lo_encryption == xfer)
@@ -1398,102 +1415,104 @@ int loop_unregister_transfer(int number)
 EXPORT_SYMBOL(loop_register_transfer);
 EXPORT_SYMBOL(loop_unregister_transfer);
 
-static int __init loop_init(void)
+static struct loop_device *loop_init_one(int i)
 {
-	int	i;
+	struct loop_device *lo;
+	struct gendisk *disk;
 
-	if (max_loop < 1 || max_loop > 256) {
-		printk(KERN_WARNING "loop: invalid max_loop (must be between"
-				    " 1 and 256), using default (8)\n");
-		max_loop = 8;
-	}
+	lo = kzalloc(sizeof(*lo), GFP_KERNEL);
+	if (!lo)
+		goto out;
 
-	if (register_blkdev(LOOP_MAJOR, "loop"))
-		return -EIO;
+	lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
+	if (!lo->lo_queue)
+		goto out_free_dev;
+
+	disk = lo->lo_disk = alloc_disk(1);
+	if (!disk)
+		goto out_free_queue;
+
+	mutex_init(&lo->lo_ctl_mutex);
+	lo->lo_number		= i;
+	lo->lo_thread		= NULL;
+	init_waitqueue_head(&lo->lo_event);
+	spin_lock_init(&lo->lo_lock);
+	disk->major		= LOOP_MAJOR;
+	disk->first_minor	= i;
+	disk->fops		= &lo_fops;
+	disk->private_data	= lo;
+	disk->queue		= lo->lo_queue;
+	sprintf(disk->disk_name, "loop%d", i);
+	add_disk(disk);
+	spin_lock(&loop_devices_lock);
+	list_add_tail(&lo->lo_list, &loop_devices);
+	spin_unlock(&loop_devices_lock);
+	return lo;
+
+out_free_queue:
+	blk_cleanup_queue(lo->lo_queue);
+out_free_dev:
+	kfree(lo);
+out:
+	return ERR_PTR(-ENOMEM);
+}
 
-	loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
-	if (!loop_dev)
-		goto out_mem1;
-	memset(loop_dev, 0, max_loop * sizeof(struct loop_device));
+static void loop_del_one(struct loop_device *lo)
+{
+	del_gendisk(lo->lo_disk);
+	blk_cleanup_queue(lo->lo_queue);
+	put_disk(lo->lo_disk);
+	list_del(&lo->lo_list);
+	kfree(lo);
+}
 
-	disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL);
-	if (!disks)
-		goto out_mem2;
+static struct kobject *loop_probe(dev_t dev, int *part, void *data)
+{
+	unsigned int number = dev & MINORMASK;
+	struct loop_device *lo;
 
-	for (i = 0; i < max_loop; i++) {
-		disks[i] = alloc_disk(1);
-		if (!disks[i])
-			goto out_mem3;
+	if ((lo = loop_find_dev(number)) == NULL) {
+		lo = loop_init_one(number);
+		*part = 0;
+		if (IS_ERR(lo))
+			return (void *)lo;
 	}
+	return &lo->lo_disk->kobj;
+}
 
-	for (i = 0; i < max_loop; i++) {
-		struct loop_device *lo = &loop_dev[i];
-		struct gendisk *disk = disks[i];
-
-		memset(lo, 0, sizeof(*lo));
-		lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
-		if (!lo->lo_queue)
-			goto out_mem4;
-		mutex_init(&lo->lo_ctl_mutex);
-		lo->lo_number = i;
-		lo->lo_thread = NULL;
-		init_waitqueue_head(&lo->lo_event);
-		spin_lock_init(&lo->lo_lock);
-		disk->major = LOOP_MAJOR;
-		disk->first_minor = i;
-		disk->fops = &lo_fops;
-		sprintf(disk->disk_name, "loop%d", i);
-		disk->private_data = lo;
-		disk->queue = lo->lo_queue;
-	}
+static int __init loop_init(void)
+{
+	struct loop_device *lo;
+
+	if (register_blkdev(LOOP_MAJOR, "loop"))
+		return -EIO;
+	blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
+				  THIS_MODULE, loop_probe, NULL, NULL);
 
-	/* We cannot fail after we call this, so another loop!*/
-	for (i = 0; i < max_loop; i++)
-		add_disk(disks[i]);
-	printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
+	lo = loop_init_one(0);
+	if (IS_ERR(lo))
+		goto out_free;
+
+	printk(KERN_INFO "loop: loaded");
 	return 0;
 
-out_mem4:
-	while (i--)
-		blk_cleanup_queue(loop_dev[i].lo_queue);
-	i = max_loop;
-out_mem3:
-	while (i--)
-		put_disk(disks[i]);
-	kfree(disks);
-out_mem2:
-	kfree(loop_dev);
-out_mem1:
+out_free:
 	unregister_blkdev(LOOP_MAJOR, "loop");
 	printk(KERN_ERR "loop: ran out of memory\n");
 	return -ENOMEM;
 }
 
-static void loop_exit(void)
+static void __exit loop_exit(void)
 {
-	int i;
+	struct loop_device *lo, *next;
 
-	for (i = 0; i < max_loop; i++) {
-		del_gendisk(disks[i]);
-		blk_cleanup_queue(loop_dev[i].lo_queue);
-		put_disk(disks[i]);
-	}
+	list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
+		loop_del_one(lo);
+
+	blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS);
 	if (unregister_blkdev(LOOP_MAJOR, "loop"))
 		printk(KERN_WARNING "loop: cannot unregister blkdev\n");
-
-	kfree(disks);
-	kfree(loop_dev);
 }
 
 module_init(loop_init);
 module_exit(loop_exit);
-
-#ifndef MODULE
-static int __init max_loop_setup(char *str)
-{
-	max_loop = simple_strtol(str, NULL, 0);
-	return 1;
-}
-
-__setup("max_loop=", max_loop_setup);
-#endif
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 191a595..0b99b31 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -64,6 +64,8 @@ struct loop_device {
 	wait_queue_head_t	lo_event;
 
 	request_queue_t		*lo_queue;
+	struct gendisk		*lo_disk;
+	struct list_head	lo_list;
 };
 
 #endif /* __KERNEL__ */

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

* Re: max_loop limit
  2007-03-22 11:37   ` Tomas M
  2007-03-22 13:42     ` Eric Dumazet
@ 2007-03-29 14:16     ` Bill Davidsen
  1 sibling, 0 replies; 30+ messages in thread
From: Bill Davidsen @ 2007-03-29 14:16 UTC (permalink / raw)
  To: Tomas M; +Cc: linux-kernel

Tomas M wrote:
>> 255 loop devices are insufficient? What kind of scenario do you have
>> in mind?
>>
>>
> 
> Thank you very much for replying.
> 
> In 1981, Bill Gates said that 64KB of memory is enough for everybody.
> And you know how much RAM do you have right now. :)
> 
Actually, I believe the number was 640k, the quote included the phrase 
"should be," the available memory on the IBM PC. And this was after IBM 
decided to put the video adapter in memory at 640k, Intel decided to 
provide only 1MB of address space on the 8086, and was in the context of 
mainframes of the day, some of which could only address 1MB.

And having run clients with three users on an XT with just that 640kB 
and UNIX, I don't think he was wrong about the memory for that time, 
just the O/S.

BTW: anyone got a copy of PC/IX (SysIII for XT) around? I'd love to run 
that in a VM just for the comparison.

-- 
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] 30+ messages in thread

* Re: max_loop limit
  2007-03-22 23:37 roland
@ 2007-03-29 14:20 ` Bill Davidsen
  0 siblings, 0 replies; 30+ messages in thread
From: Bill Davidsen @ 2007-03-29 14:20 UTC (permalink / raw)
  To: roland; +Cc: linux-kernel

roland wrote:
> partitions on loop or device-mapper devices ?
> 
> you can use kpartx tool for this.
> 
> bryn m. reeves told me, that it's probably poissible to create udev 
> rules that will automatically create partition maps when a new loop 
> device is setup, which is better than adding partitioning logig into 
> dm-loop for example.

It is certainly possible to create a partitionable RAID device from a 
loop device. Should be possible to use nbd as well, but I can't seem to 
get nbd to work on 2.6.21-rc (my working system runs 2.6.17).
> 
> example:
>> kpartx -a /dev/mapper/loop0
>>
>> # ls /dev/mapper/loop0*
>> /dev/mapper/loop0  /dev/mapper/loop0p1  /dev/mapper/loop0p2
>> /dev/mapper/loop0p3
> 
> i have seen a patch for loop.c doing this, though. search the archives 
> for this
> 
> regards
> roland
> 
> 
> 
> 
> 
> On Thu, Mar 22, 2007 at 02:33:14PM +0000, Al Viro wrote:
>> Correction: current ABI is crap.  To set the thing up you need to open
>> it and issue an ioctl.  Which is a bloody bad idea, for obvious 
>> reasons...
> 
> Agreed.  What would be a right way?  Global device ala ptmx/tun/tap?
> New syscall?  Something else?
> 
>  OG.
> -
> ]


-- 
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] 30+ messages in thread

* Re: max_loop limit
  2007-03-22 23:23 devzero
@ 2007-03-23  8:59 ` Tomas M
  0 siblings, 0 replies; 30+ messages in thread
From: Tomas M @ 2007-03-23  8:59 UTC (permalink / raw)
  To: linux-kernel

> wondering that here are 13 postings about loopdevice limitation, but
> nobody giving any comment about dm-loop (
> http://sources.redhat.com/lvm2/wiki/DMLoop ), which is a solution for
> this problem ......

If I understand it correctly, I would need 'dm' in kernel (or module) 
and moreover I would need some userspace utilities/binaries.

 > It can be used as a 1:1 replacement for classic loop and
 > should (?) probably be ready for mainline in the not too far future.

So it is not in Kernel?

With current loop, people would need kernel patch and *no* userspace 
utilities.
With dm-loop, people would need kernel patch *and* userspace utilities.
So, from my point of view, it would be better to fix/enhance Linux's loop.


Tomas M
slax.org

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

* Re: max_loop limit
@ 2007-03-22 23:37 roland
  2007-03-29 14:20 ` Bill Davidsen
  0 siblings, 1 reply; 30+ messages in thread
From: roland @ 2007-03-22 23:37 UTC (permalink / raw)
  To: linux-kernel

partitions on loop or device-mapper devices ?

you can use kpartx tool for this.

bryn m. reeves told me, that it's probably poissible to create udev rules 
that will automatically create partition maps when a new loop device is 
setup, which is better than adding partitioning logig into dm-loop for 
example.

example:
>kpartx -a /dev/mapper/loop0
>
># ls /dev/mapper/loop0*
>/dev/mapper/loop0  /dev/mapper/loop0p1  /dev/mapper/loop0p2
>/dev/mapper/loop0p3

i have seen a patch for loop.c doing this, though. search the archives for 
this

regards
roland





On Thu, Mar 22, 2007 at 02:33:14PM +0000, Al Viro wrote:
> Correction: current ABI is crap.  To set the thing up you need to open
> it and issue an ioctl.  Which is a bloody bad idea, for obvious reasons...

Agreed.  What would be a right way?  Global device ala ptmx/tun/tap?
New syscall?  Something else?

  OG.
-
] 


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

* Re: max_loop limit
@ 2007-03-22 23:23 devzero
  2007-03-23  8:59 ` Tomas M
  0 siblings, 1 reply; 30+ messages in thread
From: devzero @ 2007-03-22 23:23 UTC (permalink / raw)
  To: linux-kernel

wondering that here are 13 postings about loopdevice limitation, but nobody giving any comment about dm-loop ( http://sources.redhat.com/lvm2/wiki/DMLoop ), which is a solution for this problem ......

tomas, you should spend that money to bryn! ;)

regards
roland


> -----Ursprüngliche Nachricht-----
> Von: devzero@web.de
> Gesendet: 22.03.07 14:53:19
> An: linux-kernel@vger.kernel.org
> Betreff: Re: max_loop limit

> oh - i forgot sending this to the list, since this was copy&paste via webmailer.....
> 
> 
> > -----Ursprüngliche Nachricht-----
> > Von: devzero@web.de
> > Gesendet: 22.03.07 14:42:45
> > An: tomas@slax.org
> > CC: breeves@redhat.com
> > Betreff: Re: max_loop limit
> 
> > Hi Tomas, 
> > 
> > you`re completely right.
> > 
> > I have had this problem of loopdev number limitation for years, but i think there is a better solution besides your patch.
> > 
> > Some new module has been created for this and being announced on dm-devel mailinglist : 
> > 
> > dm-loop - the device mapper loopback target.
> > 
> > See http://sources.redhat.com/lvm2/wiki/DMLoop  for further information.
> > 
> > It can be used as a 1:1 replacement for classic loop and should (?) probably be ready for mainline in the not too far future. (i cannot tell, but it works good for me!)
> > 
> > Typically, you need to use dm-setup to setup device-mapper targets, but dm-setup has got support for dm-loop,  so it`s as easy as 1-2-3 to replace "losetup ...." with "dmlosetup" alias for dm-setup.
> > 
> > Feel free to test it and give feedback !
> > 
> > regards
> > Roland
> > 
> > ps:
> > dm-loop-config.patch is being linked wrong in the wiki - this is the right one:  http://sources.redhat.com/lvm2/wiki/DMLoop?action=AttachFile&do=get&target=dm-loop-config.patch
> > 
> > 
> > 
> > > 255 loop devices are insufficient? What kind of scenario do you have
> > > in mind?
> > > 
> > > 
> > 
> > Thank you very much for replying.
> > 
> > In 1981, Bill Gates said that 64KB of memory is enough for everybody.
> > And you know how much RAM do you have right now. :)
> > 
> > Every limit is bad. The limit of 255 loop devices has been introduced 
> > years ago, in the times when minor device number has been limited by 
> > 255. Nowadays, there is no such limitation.
> > 
> > There are many possible/reasonable uses for more than 255 loop devices. 
> > For example CD/ISO server. My project, Slax Linux live, is based on 
> > modular approach where many parts of the root filesystem are stored 
> > separately in compressed read-only loop files, and are mounted and 
> > unioned to a single root by using union fs (aufs).
> > 
> > The question is not "Why do we need more than 255 loops?".
> > The question should be "Why do we need the hardcoded 255-limit in kernel 
> > while there is no reason for it at all?"
> > 
> > My patch simply removes the hardcoded limitation.
> > 
> > 
> > Tomas M
> > slax.org
> 
> 


_______________________________________________________________
SMS schreiben mit WEB.DE FreeMail - einfach, schnell und
kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192


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

* Re: max_loop limit
@ 2007-03-22 13:53 devzero
  0 siblings, 0 replies; 30+ messages in thread
From: devzero @ 2007-03-22 13:53 UTC (permalink / raw)
  To: linux-kernel

oh - i forgot sending this to the list, since this was copy&paste via webmailer.....


> -----Ursprüngliche Nachricht-----
> Von: devzero@web.de
> Gesendet: 22.03.07 14:42:45
> An: tomas@slax.org
> CC: breeves@redhat.com
> Betreff: Re: max_loop limit

> Hi Tomas, 
> 
> you`re completely right.
> 
> I have had this problem of loopdev number limitation for years, but i think there is a better solution besides your patch.
> 
> Some new module has been created for this and being announced on dm-devel mailinglist : 
> 
> dm-loop - the device mapper loopback target.
> 
> See http://sources.redhat.com/lvm2/wiki/DMLoop  for further information.
> 
> It can be used as a 1:1 replacement for classic loop and should (?) probably be ready for mainline in the not too far future. (i cannot tell, but it works good for me!)
> 
> Typically, you need to use dm-setup to setup device-mapper targets, but dm-setup has got support for dm-loop,  so it`s as easy as 1-2-3 to replace "losetup ...." with "dmlosetup" alias for dm-setup.
> 
> Feel free to test it and give feedback !
> 
> regards
> Roland
> 
> ps:
> dm-loop-config.patch is being linked wrong in the wiki - this is the right one:  http://sources.redhat.com/lvm2/wiki/DMLoop?action=AttachFile&do=get&target=dm-loop-config.patch
> 
> 
> 
> > 255 loop devices are insufficient? What kind of scenario do you have
> > in mind?
> > 
> > 
> 
> Thank you very much for replying.
> 
> In 1981, Bill Gates said that 64KB of memory is enough for everybody.
> And you know how much RAM do you have right now. :)
> 
> Every limit is bad. The limit of 255 loop devices has been introduced 
> years ago, in the times when minor device number has been limited by 
> 255. Nowadays, there is no such limitation.
> 
> There are many possible/reasonable uses for more than 255 loop devices. 
> For example CD/ISO server. My project, Slax Linux live, is based on 
> modular approach where many parts of the root filesystem are stored 
> separately in compressed read-only loop files, and are mounted and 
> unioned to a single root by using union fs (aufs).
> 
> The question is not "Why do we need more than 255 loops?".
> The question should be "Why do we need the hardcoded 255-limit in kernel 
> while there is no reason for it at all?"
> 
> My patch simply removes the hardcoded limitation.
> 
> 
> Tomas M
> slax.org


_______________________________________________________________
SMS schreiben mit WEB.DE FreeMail - einfach, schnell und
kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192


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

end of thread, other threads:[~2007-03-29 14:19 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-22  7:57 max_loop limit Tomas M
2007-03-22 11:00 ` markus reichelt
2007-03-22 11:37   ` Tomas M
2007-03-22 13:42     ` Eric Dumazet
2007-03-22 13:42       ` Jens Axboe
2007-03-22 13:52         ` Eric Dumazet
2007-03-22 13:54           ` Jens Axboe
2007-03-22 14:11             ` William Lee Irwin III
2007-03-22 15:22               ` Arjan van de Ven
2007-03-22 16:09               ` Pádraig Brady
2007-03-28 23:34                 ` Karel Zak
     [not found]             ` <20070322151826.c1421851.dada1@cosmosbay.com>
     [not found]               ` <20070322142306.GU19922@kernel.dk>
     [not found]                 ` <20070322153603.1f5d442d.dada1@cosmosbay.com>
2007-03-22 15:31                   ` max_loop limit - paid job offer Tomas M
2007-03-22 14:33         ` max_loop limit Al Viro
2007-03-22 19:51           ` Olivier Galibert
2007-03-22 14:25       ` Tomas M
2007-03-23  1:34       ` Jan Engelhardt
2007-03-23 23:26         ` [PATCH] " Jan Engelhardt
2007-03-25  0:17           ` Ken Chen
2007-03-25  0:29           ` Ken Chen
2007-03-25  8:40           ` Tomas M
2007-03-28 23:41             ` Karel Zak
2007-03-29  3:54           ` Kyle Moffett
2007-03-29  4:16             ` [PATCH] max_loop limit, t2 Jan Engelhardt
2007-03-29  8:38               ` [PATCH] max_loop limit, loop.c final working version Tomas M
2007-03-29 14:16     ` max_loop limit Bill Davidsen
2007-03-22 13:53 devzero
2007-03-22 23:23 devzero
2007-03-23  8:59 ` Tomas M
2007-03-22 23:37 roland
2007-03-29 14:20 ` Bill Davidsen

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).