Import 2.3.25pre1
[davej-history.git] / drivers / block / loop.c
blob45f91b2da2a56eb067b2c47a8577d83af8704fcb
1 /*
2 * linux/drivers/block/loop.c
4 * Written by Theodore Ts'o, 3/29/93
5 *
6 * Copyright 1993 by Theodore Ts'o. Redistribution of this file is
7 * permitted under the GNU Public License.
9 * DES encryption plus some minor changes by Werner Almesberger, 30-MAY-1993
10 * more DES encryption plus IDEA encryption by Nicholas J. Leon, June 20, 1996
12 * Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994
13 * Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996
15 * Fixed do_loop_request() re-entrancy - Vincent.Renardias@waw.com Mar 20, 1997
17 * Handle sparse backing files correctly - Kenn Humborg, Jun 28, 1998
19 * Loadable modules and other fixes by AK, 1998
21 * Make real block number available to downstream transfer functions, enables
22 * CBC (and relatives) mode encryption requiring unique IVs per data block.
23 * Reed H. Petty, rhp@draper.net
25 * Maximum number of loop devices now dynamic via max_loop module parameter.
26 * Still fixed at 8 devices when compiled into the kernel normally.
27 * Russell Kroll <rkroll@exploits.org> 19990701
29 * Still To Fix:
30 * - Advisory locking is ignored here.
31 * - Should use an own CAP_* category instead of CAP_SYS_ADMIN
32 * - Should use the underlying filesystems/devices read function if possible
33 * to support read ahead (and for write)
35 * WARNING/FIXME:
36 * - The block number as IV passing to low level transfer functions is broken:
37 * it passes the underlying device's block number instead of the
38 * offset. This makes it change for a given block when the file is
39 * moved/restored/copied and also doesn't work over NFS.
40 */
42 #include <linux/module.h>
44 #include <linux/sched.h>
45 #include <linux/fs.h>
46 #include <linux/file.h>
47 #include <linux/stat.h>
48 #include <linux/errno.h>
49 #include <linux/major.h>
51 #include <linux/init.h>
53 #include <asm/uaccess.h>
55 #include <linux/loop.h>
57 #define MAJOR_NR LOOP_MAJOR
59 #define DEVICE_NAME "loop"
60 #define DEVICE_REQUEST do_lo_request
61 #define DEVICE_NR(device) (MINOR(device))
62 #define DEVICE_ON(device)
63 #define DEVICE_OFF(device)
64 #define DEVICE_NO_RANDOM
65 #define TIMEOUT_VALUE (6 * HZ)
66 #include <linux/blk.h>
68 #include <linux/malloc.h>
69 static int max_loop = 8;
70 static struct loop_device *loop_dev;
71 static int *loop_sizes;
72 static int *loop_blksizes;
74 #define FALSE 0
75 #define TRUE (!FALSE)
77 /* Forward declaration of function to create missing blocks in the
78 backing file (can happen if the backing file is sparse) */
79 static int create_missing_block(struct loop_device *lo, int block, int blksize);
82 * Transfer functions
84 static int transfer_none(struct loop_device *lo, int cmd, char *raw_buf,
85 char *loop_buf, int size, int real_block)
87 if (cmd == READ)
88 memcpy(loop_buf, raw_buf, size);
89 else
90 memcpy(raw_buf, loop_buf, size);
91 return 0;
94 static int transfer_xor(struct loop_device *lo, int cmd, char *raw_buf,
95 char *loop_buf, int size, int real_block)
97 char *in, *out, *key;
98 int i, keysize;
100 if (cmd == READ) {
101 in = raw_buf;
102 out = loop_buf;
103 } else {
104 in = loop_buf;
105 out = raw_buf;
107 key = lo->lo_encrypt_key;
108 keysize = lo->lo_encrypt_key_size;
109 for (i=0; i < size; i++)
110 *out++ = *in++ ^ key[(i & 511) % keysize];
111 return 0;
114 static int none_status(struct loop_device *lo, struct loop_info *info)
116 return 0;
119 static int xor_status(struct loop_device *lo, struct loop_info *info)
121 if (info->lo_encrypt_key_size <= 0)
122 return -EINVAL;
123 return 0;
126 struct loop_func_table none_funcs = {
127 number: LO_CRYPT_NONE,
128 transfer: transfer_none,
129 init: none_status
132 struct loop_func_table xor_funcs = {
133 number: LO_CRYPT_XOR,
134 transfer: transfer_xor,
135 init: xor_status
138 /* xfer_funcs[0] is special - its release function is never called */
139 struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
140 &none_funcs,
141 &xor_funcs
144 #define MAX_DISK_SIZE 1024*1024*1024
146 static void figure_loop_size(struct loop_device *lo)
148 int size;
150 if (S_ISREG(lo->lo_dentry->d_inode->i_mode))
151 size = (lo->lo_dentry->d_inode->i_size - lo->lo_offset) / BLOCK_SIZE;
152 else {
153 kdev_t lodev = lo->lo_device;
154 if (blk_size[MAJOR(lodev)])
155 size = blk_size[MAJOR(lodev)][MINOR(lodev)] -
156 lo->lo_offset / BLOCK_SIZE;
157 else
158 size = MAX_DISK_SIZE;
161 loop_sizes[lo->lo_number] = size;
164 static void do_lo_request(void)
166 int real_block, block, offset, len, blksize, size;
167 char *dest_addr;
168 struct loop_device *lo;
169 struct buffer_head *bh;
170 struct request *current_request;
171 int block_present;
173 repeat:
174 INIT_REQUEST;
175 current_request=CURRENT;
176 CURRENT=current_request->next;
177 if (MINOR(current_request->rq_dev) >= max_loop)
178 goto error_out;
179 lo = &loop_dev[MINOR(current_request->rq_dev)];
180 if (!lo->lo_dentry || !lo->transfer)
181 goto error_out;
183 blksize = BLOCK_SIZE;
184 if (blksize_size[MAJOR(lo->lo_device)]) {
185 blksize = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
186 if (!blksize)
187 blksize = BLOCK_SIZE;
190 dest_addr = current_request->buffer;
192 if (blksize < 512) {
193 block = current_request->sector * (512/blksize);
194 offset = 0;
195 } else {
196 block = current_request->sector / (blksize >> 9);
197 offset = (current_request->sector % (blksize >> 9)) << 9;
199 block += lo->lo_offset / blksize;
200 offset += lo->lo_offset % blksize;
201 if (offset > blksize) {
202 block++;
203 offset -= blksize;
205 len = current_request->current_nr_sectors << 9;
207 if (current_request->cmd == WRITE) {
208 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
209 goto error_out;
210 } else if (current_request->cmd != READ) {
211 printk(KERN_ERR "unknown loop device command (%d)?!?", current_request->cmd);
212 goto error_out;
214 spin_unlock_irq(&io_request_lock);
215 while (len > 0) {
217 size = blksize - offset;
218 if (size > len)
219 size = len;
221 real_block = block;
222 block_present = TRUE;
224 if (lo->lo_flags & LO_FLAGS_DO_BMAP) {
225 real_block = bmap(lo->lo_dentry->d_inode, block);
226 if (!real_block) {
228 /* The backing file is a sparse file and this block
229 doesn't exist. If reading, return zeros. If
230 writing, force the underlying FS to create
231 the block */
232 if (current_request->cmd == READ) {
233 memset(dest_addr, 0, size);
234 block_present = FALSE;
235 } else {
236 if (!create_missing_block(lo, block, blksize)) {
237 goto error_out_lock;
239 real_block = bmap(lo->lo_dentry->d_inode, block);
245 if (block_present) {
246 bh = getblk(lo->lo_device, real_block, blksize);
247 if (!bh) {
248 printk(KERN_ERR "loop: device %s: getblk(-, %d, %d) returned NULL",
249 kdevname(lo->lo_device),
250 block, blksize);
251 goto error_out_lock;
253 if (!buffer_uptodate(bh) && ((current_request->cmd == READ) ||
254 (offset || (len < blksize)))) {
255 ll_rw_block(READ, 1, &bh);
256 wait_on_buffer(bh);
257 if (!buffer_uptodate(bh)) {
258 brelse(bh);
259 goto error_out_lock;
263 if ((lo->transfer)(lo, current_request->cmd, bh->b_data + offset,
264 dest_addr, size, real_block)) {
265 printk(KERN_ERR "loop: transfer error block %d\n", block);
266 brelse(bh);
267 goto error_out_lock;
270 if (current_request->cmd == WRITE) {
271 mark_buffer_uptodate(bh, 1);
272 mark_buffer_dirty(bh, 1);
274 brelse(bh);
276 dest_addr += size;
277 len -= size;
278 offset = 0;
279 block++;
281 spin_lock_irq(&io_request_lock);
282 current_request->next=CURRENT;
283 CURRENT=current_request;
284 end_request(1);
285 goto repeat;
286 error_out_lock:
287 spin_lock_irq(&io_request_lock);
288 error_out:
289 current_request->next=CURRENT;
290 CURRENT=current_request;
291 end_request(0);
292 goto repeat;
295 static int create_missing_block(struct loop_device *lo, int block, int blksize)
297 struct file *file;
298 loff_t new_offset;
299 char zero_buf[1] = { 0 };
300 ssize_t retval;
301 mm_segment_t old_fs;
302 struct inode *inode;
304 file = lo->lo_backing_file;
305 if (file == NULL) {
306 printk(KERN_WARNING "loop: cannot create block - no backing file\n");
307 return FALSE;
310 if (file->f_op == NULL) {
311 printk(KERN_WARNING "loop: cannot create block - no file ops\n");
312 return FALSE;
315 new_offset = block * blksize;
317 if (file->f_op->llseek != NULL) {
318 file->f_op->llseek(file, new_offset, 0);
319 } else {
320 /* Do what the default llseek() code would have done */
321 file->f_pos = new_offset;
322 file->f_reada = 0;
323 file->f_version = ++event;
326 if (file->f_op->write == NULL) {
327 printk(KERN_WARNING "loop: cannot create block - file not writeable\n");
328 return FALSE;
331 old_fs = get_fs();
332 set_fs(get_ds());
334 inode = file->f_dentry->d_inode;
335 down(&inode->i_sem);
336 retval = file->f_op->write(file, zero_buf, 1, &file->f_pos);
337 up(&inode->i_sem);
339 set_fs(old_fs);
341 if (retval < 0) {
342 printk(KERN_WARNING "loop: cannot create block - FS write failed: code %d\n",
343 retval);
344 return FALSE;
345 } else {
346 return TRUE;
350 static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
352 struct file *file;
353 struct inode *inode;
354 int error;
356 MOD_INC_USE_COUNT;
358 error = -EBUSY;
359 if (lo->lo_dentry)
360 goto out;
362 error = -EBADF;
363 file = fget(arg);
364 if (!file)
365 goto out;
367 error = -EINVAL;
368 inode = file->f_dentry->d_inode;
369 if (!inode) {
370 printk(KERN_ERR "loop_set_fd: NULL inode?!?\n");
371 goto out_putf;
374 if (S_ISBLK(inode->i_mode)) {
375 error = blkdev_open(inode, file);
376 lo->lo_device = inode->i_rdev;
377 lo->lo_flags = 0;
379 /* Backed by a block device - don't need to hold onto
380 a file structure */
381 lo->lo_backing_file = NULL;
382 } else if (S_ISREG(inode->i_mode)) {
383 if (!inode->i_op->get_block) {
384 printk(KERN_ERR "loop: device has no block access/not implemented\n");
385 goto out_putf;
388 /* Backed by a regular file - we need to hold onto
389 a file structure for this file. We'll use it to
390 write to blocks that are not already present in
391 a sparse file. We create a new file structure
392 based on the one passed to us via 'arg'. This is
393 to avoid changing the file structure that the
394 caller is using */
396 lo->lo_device = inode->i_dev;
397 lo->lo_flags = LO_FLAGS_DO_BMAP;
399 error = -ENFILE;
400 lo->lo_backing_file = get_empty_filp();
401 if (lo->lo_backing_file) {
402 lo->lo_backing_file->f_mode = file->f_mode;
403 lo->lo_backing_file->f_pos = file->f_pos;
404 lo->lo_backing_file->f_flags = file->f_flags;
405 lo->lo_backing_file->f_owner = file->f_owner;
406 lo->lo_backing_file->f_dentry = file->f_dentry;
407 lo->lo_backing_file->f_op = file->f_op;
408 lo->lo_backing_file->private_data = file->private_data;
409 file_moveto(lo->lo_backing_file, file);
411 error = get_write_access(inode);
412 if (error) {
413 put_filp(lo->lo_backing_file);
414 lo->lo_backing_file = NULL;
418 if (error)
419 goto out_putf;
421 if (IS_RDONLY (inode) || is_read_only(lo->lo_device)) {
422 lo->lo_flags |= LO_FLAGS_READ_ONLY;
423 set_device_ro(dev, 1);
424 } else {
425 invalidate_inode_pages (inode);
426 set_device_ro(dev, 0);
429 lo->lo_dentry = dget(file->f_dentry);
430 lo->transfer = NULL;
431 lo->ioctl = NULL;
432 figure_loop_size(lo);
434 out_putf:
435 fput(file);
436 out:
437 if (error)
438 MOD_DEC_USE_COUNT;
439 return error;
442 static int loop_release_xfer(struct loop_device *lo)
444 int err = 0;
445 if (lo->lo_encrypt_type) {
446 struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type];
447 if (xfer && xfer->release)
448 err = xfer->release(lo);
449 if (xfer && xfer->unlock)
450 xfer->unlock(lo);
451 lo->lo_encrypt_type = 0;
453 return err;
456 static int loop_init_xfer(struct loop_device *lo, int type,struct loop_info *i)
458 int err = 0;
459 if (type) {
460 struct loop_func_table *xfer = xfer_funcs[type];
461 if (xfer->init)
462 err = xfer->init(lo, i);
463 if (!err) {
464 lo->lo_encrypt_type = type;
465 if (xfer->lock)
466 xfer->lock(lo);
469 return err;
472 static int loop_clr_fd(struct loop_device *lo, kdev_t dev)
474 struct dentry *dentry = lo->lo_dentry;
476 if (!dentry)
477 return -ENXIO;
478 if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */
479 return -EBUSY;
481 if (S_ISBLK(dentry->d_inode->i_mode))
482 blkdev_release (dentry->d_inode);
483 lo->lo_dentry = NULL;
485 if (lo->lo_backing_file != NULL) {
486 fput(lo->lo_backing_file);
487 lo->lo_backing_file = NULL;
488 } else {
489 dput(dentry);
492 loop_release_xfer(lo);
493 lo->transfer = NULL;
494 lo->ioctl = NULL;
495 lo->lo_device = 0;
496 lo->lo_encrypt_type = 0;
497 lo->lo_offset = 0;
498 lo->lo_encrypt_key_size = 0;
499 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
500 memset(lo->lo_name, 0, LO_NAME_SIZE);
501 loop_sizes[lo->lo_number] = 0;
502 invalidate_buffers(dev);
503 MOD_DEC_USE_COUNT;
504 return 0;
507 static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
509 struct loop_info info;
510 int err;
511 unsigned int type;
513 if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
514 !capable(CAP_SYS_ADMIN))
515 return -EPERM;
516 if (!lo->lo_dentry)
517 return -ENXIO;
518 if (copy_from_user(&info, arg, sizeof (struct loop_info)))
519 return -EFAULT;
520 if ((unsigned int) info.lo_encrypt_key_size > LO_KEY_SIZE)
521 return -EINVAL;
522 type = info.lo_encrypt_type;
523 if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
524 return -EINVAL;
525 err = loop_release_xfer(lo);
526 if (!err)
527 err = loop_init_xfer(lo, type, &info);
528 if (err)
529 return err;
531 lo->lo_offset = info.lo_offset;
532 strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE);
534 lo->transfer = xfer_funcs[type]->transfer;
535 lo->ioctl = xfer_funcs[type]->ioctl;
536 lo->lo_encrypt_key_size = info.lo_encrypt_key_size;
537 lo->lo_init[0] = info.lo_init[0];
538 lo->lo_init[1] = info.lo_init[1];
539 if (info.lo_encrypt_key_size) {
540 memcpy(lo->lo_encrypt_key, info.lo_encrypt_key,
541 info.lo_encrypt_key_size);
542 lo->lo_key_owner = current->uid;
544 figure_loop_size(lo);
545 return 0;
548 static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
550 struct loop_info info;
552 if (!lo->lo_dentry)
553 return -ENXIO;
554 if (!arg)
555 return -EINVAL;
556 memset(&info, 0, sizeof(info));
557 info.lo_number = lo->lo_number;
558 info.lo_device = kdev_t_to_nr(lo->lo_dentry->d_inode->i_dev);
559 info.lo_inode = lo->lo_dentry->d_inode->i_ino;
560 info.lo_rdevice = kdev_t_to_nr(lo->lo_device);
561 info.lo_offset = lo->lo_offset;
562 info.lo_flags = lo->lo_flags;
563 strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);
564 info.lo_encrypt_type = lo->lo_encrypt_type;
565 if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
566 info.lo_encrypt_key_size = lo->lo_encrypt_key_size;
567 memcpy(info.lo_encrypt_key, lo->lo_encrypt_key,
568 lo->lo_encrypt_key_size);
570 return copy_to_user(arg, &info, sizeof(info)) ? -EFAULT : 0;
573 static int lo_ioctl(struct inode * inode, struct file * file,
574 unsigned int cmd, unsigned long arg)
576 struct loop_device *lo;
577 int dev;
579 if (!inode)
580 return -EINVAL;
581 if (MAJOR(inode->i_rdev) != MAJOR_NR) {
582 printk(KERN_WARNING "lo_ioctl: pseudo-major != %d\n", MAJOR_NR);
583 return -ENODEV;
585 dev = MINOR(inode->i_rdev);
586 if (dev >= max_loop)
587 return -ENODEV;
588 lo = &loop_dev[dev];
589 switch (cmd) {
590 case LOOP_SET_FD:
591 return loop_set_fd(lo, inode->i_rdev, arg);
592 case LOOP_CLR_FD:
593 return loop_clr_fd(lo, inode->i_rdev);
594 case LOOP_SET_STATUS:
595 return loop_set_status(lo, (struct loop_info *) arg);
596 case LOOP_GET_STATUS:
597 return loop_get_status(lo, (struct loop_info *) arg);
598 case BLKGETSIZE: /* Return device size */
599 if (!lo->lo_dentry)
600 return -ENXIO;
601 if (!arg)
602 return -EINVAL;
603 return put_user(loop_sizes[lo->lo_number] << 1, (long *) arg);
604 default:
605 return lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
607 return 0;
610 static int lo_open(struct inode *inode, struct file *file)
612 struct loop_device *lo;
613 int dev, type;
616 if (!inode)
617 return -EINVAL;
618 if (MAJOR(inode->i_rdev) != MAJOR_NR) {
619 printk(KERN_WARNING "lo_open: pseudo-major != %d\n", MAJOR_NR);
620 return -ENODEV;
622 dev = MINOR(inode->i_rdev);
623 if (dev >= max_loop) {
624 return -ENODEV;
626 lo = &loop_dev[dev];
628 type = lo->lo_encrypt_type;
629 if (type && xfer_funcs[type] && xfer_funcs[type]->lock)
630 xfer_funcs[type]->lock(lo);
631 lo->lo_refcnt++;
632 MOD_INC_USE_COUNT;
633 return 0;
636 static int lo_release(struct inode *inode, struct file *file)
638 struct loop_device *lo;
639 int dev, err;
641 if (!inode)
642 return 0;
643 if (MAJOR(inode->i_rdev) != MAJOR_NR) {
644 printk(KERN_WARNING "lo_release: pseudo-major != %d\n", MAJOR_NR);
645 return 0;
647 dev = MINOR(inode->i_rdev);
648 if (dev >= max_loop)
649 return 0;
650 err = fsync_dev(inode->i_rdev);
651 lo = &loop_dev[dev];
652 if (lo->lo_refcnt <= 0)
653 printk(KERN_ERR "lo_release: refcount(%d) <= 0\n", lo->lo_refcnt);
654 else {
655 int type = lo->lo_encrypt_type;
656 --lo->lo_refcnt;
657 if (xfer_funcs[type] && xfer_funcs[type]->unlock)
658 xfer_funcs[type]->unlock(lo);
659 MOD_DEC_USE_COUNT;
661 return err;
664 static struct file_operations lo_fops = {
665 NULL, /* lseek - default */
666 block_read, /* read - general block-dev read */
667 block_write, /* write - general block-dev write */
668 NULL, /* readdir - bad */
669 NULL, /* poll */
670 lo_ioctl, /* ioctl */
671 NULL, /* mmap */
672 lo_open, /* open */
673 NULL, /* flush */
674 lo_release /* release */
678 * And now the modules code and kernel interface.
680 #ifdef MODULE
681 #define loop_init init_module
682 MODULE_PARM(max_loop, "i");
683 MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-255)");
684 #endif
686 int loop_register_transfer(struct loop_func_table *funcs)
688 if ((unsigned)funcs->number > MAX_LO_CRYPT || xfer_funcs[funcs->number])
689 return -EINVAL;
690 xfer_funcs[funcs->number] = funcs;
691 return 0;
694 int loop_unregister_transfer(int number)
696 struct loop_device *lo;
698 if ((unsigned)number >= MAX_LO_CRYPT)
699 return -EINVAL;
700 for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
701 int type = lo->lo_encrypt_type;
702 if (type == number) {
703 xfer_funcs[type]->release(lo);
704 lo->transfer = NULL;
705 lo->lo_encrypt_type = 0;
708 xfer_funcs[number] = NULL;
709 return 0;
712 EXPORT_SYMBOL(loop_register_transfer);
713 EXPORT_SYMBOL(loop_unregister_transfer);
715 int __init loop_init(void)
717 int i;
719 if (register_blkdev(MAJOR_NR, "loop", &lo_fops)) {
720 printk(KERN_WARNING "Unable to get major number %d for loop device\n",
721 MAJOR_NR);
722 return -EIO;
725 if ((max_loop < 1) || (max_loop > 255)) {
726 printk (KERN_WARNING "loop: max_loop must be between 1 and 255\n");
727 return -EINVAL;
730 #ifndef MODULE
731 printk(KERN_INFO "loop: registered device at major %d\n", MAJOR_NR);
732 #else
733 printk(KERN_INFO "loop: enabling %d loop devices\n", max_loop);
734 #endif
736 loop_dev = kmalloc (max_loop * sizeof(struct loop_device), GFP_KERNEL);
737 if (!loop_dev) {
738 printk (KERN_ERR "loop: Unable to create loop_dev\n");
739 return -ENOMEM;
742 loop_sizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL);
743 if (!loop_sizes) {
744 printk (KERN_ERR "loop: Unable to create loop_sizes\n");
745 kfree (loop_dev);
746 return -ENOMEM;
749 loop_blksizes = kmalloc (max_loop * sizeof(int), GFP_KERNEL);
750 if (!loop_blksizes) {
751 printk (KERN_ERR "loop: Unable to create loop_blksizes\n");
752 kfree (loop_dev);
753 kfree (loop_sizes);
754 return -ENOMEM;
757 blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
758 for (i=0; i < max_loop; i++) {
759 memset(&loop_dev[i], 0, sizeof(struct loop_device));
760 loop_dev[i].lo_number = i;
762 memset(loop_sizes, 0, max_loop * sizeof(int));
763 memset(loop_blksizes, 0, max_loop * sizeof(int));
764 blk_size[MAJOR_NR] = loop_sizes;
765 blksize_size[MAJOR_NR] = loop_blksizes;
767 return 0;
770 #ifdef MODULE
771 void cleanup_module(void)
773 if (unregister_blkdev(MAJOR_NR, "loop") != 0)
774 printk(KERN_WARNING "loop: cannot unregister blkdev\n");
776 kfree (loop_dev);
777 kfree (loop_sizes);
778 kfree (loop_blksizes);
780 #endif