On Mon, 16 Oct 2000, Alan Cox wrote:
> ENOPATCH

sorry.
here it is.
--- linux-2.2.18pre16/drivers/block/loop.c.orig Mon Oct 16 22:09:17 2000
+++ linux-2.2.18pre16/drivers/block/loop.c      Mon Oct 16 22:14:00 2000
@@ -22,6 +22,8 @@
  * CBC (and relatives) mode encryption requiring unique IVs per data block. 
  * Reed H. Petty, [EMAIL PROTECTED]
  * 
+ * module parameter for max. number of loop devices - Eric Lammerts, Oct 16, 2000
+ *
  * Still To Fix:
  * - Advisory locking is ignored here. 
  * - Should use an own CAP_* category instead of CAP_SYS_ADMIN 
@@ -42,6 +44,7 @@
 #include <linux/file.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
+#include <linux/malloc.h>
 #include <linux/major.h>
 
 #include <linux/init.h>
@@ -61,10 +64,12 @@
 #define TIMEOUT_VALUE (6 * HZ)
 #include <linux/blk.h>
 
-#define MAX_LOOP 8
-static struct loop_device loop_dev[MAX_LOOP];
-static int loop_sizes[MAX_LOOP];
-static int loop_blksizes[MAX_LOOP];
+static int max_loop = 8;
+MODULE_PARM(max_loop, "i");
+
+static struct loop_device *loop_dev;
+static int *loop_sizes;
+static int *loop_blksizes;
 
 #define FALSE 0
 #define TRUE (!FALSE)
@@ -169,7 +174,7 @@
        INIT_REQUEST;
        current_request=CURRENT;
        CURRENT=current_request->next;
-       if (MINOR(current_request->rq_dev) >= MAX_LOOP)
+       if (MINOR(current_request->rq_dev) >= max_loop)
                goto error_out;
        lo = &loop_dev[MINOR(current_request->rq_dev)];
        if (!lo->lo_dentry || !lo->transfer)
@@ -577,7 +582,7 @@
                return -ENODEV;
        }
        dev = MINOR(inode->i_rdev);
-       if (dev >= MAX_LOOP)
+       if (dev >= max_loop)
                return -ENODEV;
        lo = &loop_dev[dev];
        switch (cmd) {
@@ -614,7 +619,7 @@
                return -ENODEV;
        }
        dev = MINOR(inode->i_rdev);
-       if (dev >= MAX_LOOP) {
+       if (dev >= max_loop) {
                return -ENODEV;
        }
        lo = &loop_dev[dev];
@@ -639,7 +644,7 @@
                return 0;
        }
        dev = MINOR(inode->i_rdev);
-       if (dev >= MAX_LOOP)
+       if (dev >= max_loop)
                return 0;
        err = fsync_dev(inode->i_rdev);
        lo = &loop_dev[dev];
@@ -689,7 +694,7 @@
 
        if ((unsigned)number >= MAX_LO_CRYPT)
                return -EINVAL; 
-       for (lo = &loop_dev[0]; lo < &loop_dev[MAX_LOOP]; lo++) { 
+       for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { 
                int type = lo->lo_encrypt_type;
                if (type == number) { 
                        xfer_funcs[type]->release(lo);
@@ -706,34 +711,65 @@
 
 int __init loop_init(void) 
 {
-       int     i;
+       int i, retval;
+
+       if(max_loop < 1 || max_loop > 256) {
+               printk(KERN_ERR "loop: 1 <= max_loop <= 256\n");
+               return -EINVAL;
+       }
+
+       retval = -ENOMEM;
+       loop_dev = kmalloc(sizeof(*loop_dev) * max_loop, GFP_KERNEL);
+       if(loop_dev == NULL) goto out_nomem;
+
+       loop_sizes = kmalloc(sizeof(*loop_sizes) * max_loop, GFP_KERNEL);
+       if(loop_sizes == NULL) goto out_nomem_freedev;
+
+       loop_blksizes = kmalloc(sizeof(*loop_blksizes) * max_loop, GFP_KERNEL);
+       if(loop_blksizes == NULL) goto out_nomem_freesizes;
 
        if (register_blkdev(MAJOR_NR, "loop", &lo_fops)) {
                printk(KERN_WARNING "Unable to get major number %d for loop device\n",
                       MAJOR_NR);
-               return -EIO;
+               retval = -EIO;
+               goto out_nomem_freeblksizes;
        }
 #ifndef MODULE
        printk(KERN_INFO "loop: registered device at major %d\n", MAJOR_NR);
 #endif
 
        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
-       for (i=0; i < MAX_LOOP; i++) {
+       for (i=0; i < max_loop; i++) {
                memset(&loop_dev[i], 0, sizeof(struct loop_device));
                loop_dev[i].lo_number = i;
        }
-       memset(&loop_sizes, 0, sizeof(loop_sizes));
-       memset(&loop_blksizes, 0, sizeof(loop_blksizes));
+       memset(loop_sizes, 0, sizeof(*loop_sizes) * max_loop);
+       memset(loop_blksizes, 0, sizeof(*loop_blksizes) * max_loop);
        blk_size[MAJOR_NR] = loop_sizes;
        blksize_size[MAJOR_NR] = loop_blksizes;
        
        return 0;
+
+out_nomem_freeblksizes:
+       kfree(loop_blksizes);
+out_nomem_freesizes:
+       kfree(loop_sizes);
+out_nomem_freedev:
+       kfree(loop_dev);
+out_nomem:
+       return retval;
 }
 
 #ifdef MODULE
 void cleanup_module(void) 
 {
-       if (unregister_blkdev(MAJOR_NR, "loop") != 0)
+       if (unregister_blkdev(MAJOR_NR, "loop") != 0) {
                printk(KERN_WARNING "loop: cannot unregister blkdev\n");
+               return;
+       }
+
+       kfree(loop_dev);
+       kfree(loop_sizes);
+       kfree(loop_blksizes);
 }
 #endif

Reply via email to