Import 2.3.9pre5
[davej-history.git] / drivers / block / rd.c
blob6c2768b279455adf4f9c7e91d474634cdae1971d
1 /*
2 * ramdisk.c - Multiple RAM disk driver - gzip-loading version - v. 0.8 beta.
3 *
4 * (C) Chad Page, Theodore Ts'o, et. al, 1995.
6 * This RAM disk is designed to have filesystems created on it and mounted
7 * just like a regular floppy disk.
8 *
9 * It also does something suggested by Linus: use the buffer cache as the
10 * RAM disk data. This makes it possible to dynamically allocate the RAM disk
11 * buffer - with some consequences I have to deal with as I write this.
13 * This code is based on the original ramdisk.c, written mostly by
14 * Theodore Ts'o (TYT) in 1991. The code was largely rewritten by
15 * Chad Page to use the buffer cache to store the RAM disk data in
16 * 1995; Theodore then took over the driver again, and cleaned it up
17 * for inclusion in the mainline kernel.
19 * The original CRAMDISK code was written by Richard Lyons, and
20 * adapted by Chad Page to use the new RAM disk interface. Theodore
21 * Ts'o rewrote it so that both the compressed RAM disk loader and the
22 * kernel decompressor uses the same inflate.c codebase. The RAM disk
23 * loader now also loads into a dynamic (buffer cache based) RAM disk,
24 * not the old static RAM disk. Support for the old static RAM disk has
25 * been completely removed.
27 * Loadable module support added by Tom Dyas.
29 * Further cleanups by Chad Page (page0588@sundance.sjsu.edu):
30 * Cosmetic changes in #ifdef MODULE, code movement, etc.
31 * When the RAM disk module is removed, free the protected buffers
32 * Default RAM disk size changed to 2.88 MB
34 * Added initrd: Werner Almesberger & Hans Lermen, Feb '96
36 * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB)
37 * - Chad Page
39 * Add support for fs images split across >1 disk, Paul Gortmaker, Mar '98
41 * Make block size and block size shift for RAM disks a global macro
42 * and set blk_size for -ENOSPC, Werner Fink <werner@suse.de>, Apr '99
45 #include <linux/config.h>
46 #include <linux/sched.h>
47 #include <linux/minix_fs.h>
48 #include <linux/ext2_fs.h>
49 #include <linux/romfs_fs.h>
50 #include <linux/fs.h>
51 #include <linux/kernel.h>
52 #include <linux/hdreg.h>
53 #include <linux/string.h>
54 #include <linux/mm.h>
55 #include <linux/mman.h>
56 #include <linux/malloc.h>
57 #include <linux/ioctl.h>
58 #include <linux/fd.h>
59 #include <linux/module.h>
60 #include <linux/init.h>
62 #include <asm/system.h>
63 #include <asm/uaccess.h>
64 #include <asm/byteorder.h>
66 extern void wait_for_keypress(void);
69 * 35 has been officially registered as the RAMDISK major number, but
70 * so is the original MAJOR number of 1. We're using 1 in
71 * include/linux/major.h for now
73 #define MAJOR_NR RAMDISK_MAJOR
74 #include <linux/blk.h>
75 #include <linux/blkpg.h>
78 * We use a block size of 512 bytes in comparision to BLOCK_SIZE
79 * defined in include/linux/blk.h. This because of the finer
80 * granularity for filling up a RAM disk.
82 #define RDBLK_SIZE_BITS 9
83 #define RDBLK_SIZE (1<<RDBLK_SIZE_BITS)
86 /* The RAM disk size is now a parameter */
87 #define NUM_RAMDISKS 16 /* This cannot be overridden (yet) */
89 #ifndef MODULE
90 /* We don't have to load RAM disks or gunzip them in a module. */
91 #define RD_LOADER
92 #define BUILD_CRAMDISK
94 void rd_load(void);
95 static int crd_load(struct file *fp, struct file *outfp);
97 #ifdef CONFIG_BLK_DEV_INITRD
98 static int initrd_users = 0;
99 #endif
100 #endif
102 /* Various static variables go here. Most are used only in the RAM disk code.
105 static unsigned long rd_length[NUM_RAMDISKS]; /* Size of RAM disks in bytes */
106 static int rd_hardsec[NUM_RAMDISKS]; /* Size of real blocks in bytes */
107 static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */
108 static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */
111 * Parameters for the boot-loading of the RAM disk. These are set by
112 * init/main.c (from arguments to the kernel command line) or from the
113 * architecture-specific setup routine (from the stored boot sector
114 * information).
116 int rd_size = 4096; /* Size of the RAM disks */
118 #ifndef MODULE
119 int rd_doload = 0; /* 1 = load RAM disk, 0 = don't load */
120 int rd_prompt = 1; /* 1 = prompt for RAM disk, 0 = don't prompt */
121 int rd_image_start = 0; /* starting block # of image */
122 #ifdef CONFIG_BLK_DEV_INITRD
123 unsigned long initrd_start,initrd_end;
124 int mount_initrd = 1; /* zero if initrd should not be mounted */
125 int initrd_below_start_ok = 0;
126 #endif
127 #endif
130 * Basically, my strategy here is to set up a buffer-head which can't be
131 * deleted, and make that my Ramdisk. If the request is outside of the
132 * allocated size, we must get rid of it...
135 static void rd_request(void)
137 unsigned int minor;
138 unsigned long offset, len;
140 repeat:
141 if (!CURRENT)
142 return;
144 INIT_REQUEST;
146 minor = MINOR(CURRENT->rq_dev);
148 if (minor >= NUM_RAMDISKS) {
149 end_request(0);
150 goto repeat;
153 offset = CURRENT->sector << RDBLK_SIZE_BITS;
154 len = CURRENT->current_nr_sectors << RDBLK_SIZE_BITS;
156 if ((offset + len) > rd_length[minor]) {
157 end_request(0);
158 goto repeat;
161 if ((CURRENT->cmd != READ) && (CURRENT->cmd != WRITE)) {
162 printk(KERN_INFO "RAMDISK: bad command: %d\n", CURRENT->cmd);
163 end_request(0);
164 goto repeat;
168 * If we're reading, fill the buffer with 0's. This is okay since
169 * we're using protected buffers which should never get freed...
171 * If we're writing, we protect the buffer.
174 if (CURRENT->cmd == READ)
175 memset(CURRENT->buffer, 0, len);
176 else
177 set_bit(BH_Protected, &CURRENT->bh->b_state);
179 end_request(1);
180 goto repeat;
183 static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
185 unsigned int minor;
187 if (!inode || !inode->i_rdev)
188 return -EINVAL;
190 minor = MINOR(inode->i_rdev);
192 switch (cmd) {
193 case BLKFLSBUF:
194 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
195 invalidate_buffers(inode->i_rdev);
196 break;
198 case BLKGETSIZE: /* Return device size */
199 if (!arg) return -EINVAL;
200 return put_user(rd_length[minor] >> RDBLK_SIZE_BITS, (long *) arg);
202 case BLKROSET:
203 case BLKROGET:
204 case BLKSSZGET:
205 return blk_ioctl(inode->i_rdev, cmd, arg);
207 default:
208 return -EINVAL;
211 return 0;
215 #ifdef CONFIG_BLK_DEV_INITRD
217 static ssize_t initrd_read(struct file *file, char *buf,
218 size_t count, loff_t *ppos)
220 int left;
222 left = initrd_end - initrd_start - *ppos;
223 if (count > left) count = left;
224 if (count == 0) return 0;
225 copy_to_user(buf, (char *)initrd_start + *ppos, count);
226 *ppos += count;
227 return count;
231 static int initrd_release(struct inode *inode,struct file *file)
233 unsigned long i;
235 if (--initrd_users) return 0;
236 for (i = initrd_start; i < initrd_end; i += PAGE_SIZE)
237 free_page(i);
238 initrd_start = 0;
239 return 0;
243 static struct file_operations initrd_fops = {
244 NULL, /* lseek */
245 initrd_read, /* read */
246 NULL, /* write */
247 NULL, /* readdir */
248 NULL, /* poll */
249 NULL, /* ioctl */
250 NULL, /* mmap */
251 NULL, /* open */
252 NULL, /* flush */
253 initrd_release, /* release */
254 NULL /* fsync */
257 #endif
260 static int rd_open(struct inode * inode, struct file * filp)
262 #ifdef CONFIG_BLK_DEV_INITRD
263 if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
264 if (!initrd_start) return -ENODEV;
265 initrd_users++;
266 filp->f_op = &initrd_fops;
267 return 0;
269 #endif
271 if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
272 return -ENXIO;
274 MOD_INC_USE_COUNT;
276 return 0;
279 static int rd_release(struct inode * inode, struct file * filp)
281 MOD_DEC_USE_COUNT;
282 return 0;
285 static struct file_operations fd_fops = {
286 NULL, /* lseek - default */
287 block_read, /* read - block dev read */
288 block_write, /* write - block dev write */
289 NULL, /* readdir - not here! */
290 NULL, /* poll */
291 rd_ioctl, /* ioctl */
292 NULL, /* mmap */
293 rd_open, /* open */
294 NULL, /* flush */
295 rd_release, /* module needs to decrement use count */
296 block_fsync /* fsync */
299 /* This is the registration and initialization section of the RAM disk driver */
300 __initfunc(int rd_init(void))
302 int i;
304 if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) {
305 printk("RAMDISK: Could not get major %d", MAJOR_NR);
306 return -EIO;
309 blk_dev[MAJOR_NR].request_fn = &rd_request;
311 for (i = 0; i < NUM_RAMDISKS; i++) {
312 /* rd_size is given in kB */
313 rd_length[i] = (rd_size << BLOCK_SIZE_BITS);
314 rd_hardsec[i] = RDBLK_SIZE;
315 rd_blocksizes[i] = BLOCK_SIZE;
316 rd_kbsize[i] = (rd_length[i] >> BLOCK_SIZE_BITS);
319 hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */
320 blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */
321 blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */
323 printk("RAM disk driver initialized: %d RAM disks of %dK size\n",
324 NUM_RAMDISKS, rd_size);
326 return 0;
329 /* loadable module support */
331 #ifdef MODULE
333 MODULE_PARM (rd_size, "1i");
334 MODULE_PARM_DESC(rd_size, "Size of each RAM disk.");
336 int init_module(void)
338 int error = rd_init();
339 if (!error)
340 printk(KERN_INFO "RAMDISK: Loaded as module.\n");
341 return error;
344 /* Before freeing the module, invalidate all of the protected buffers! */
345 void cleanup_module(void)
347 int i;
349 for (i = 0 ; i < NUM_RAMDISKS; i++)
350 invalidate_buffers(MKDEV(MAJOR_NR, i));
352 unregister_blkdev( MAJOR_NR, "ramdisk" );
353 blk_dev[MAJOR_NR].request_fn = 0;
356 #endif /* MODULE */
358 /* End of non-loading portions of the RAM disk driver */
360 #ifdef RD_LOADER
362 * This routine tries to find a RAM disk image to load, and returns the
363 * number of blocks to read for a non-compressed image, 0 if the image
364 * is a compressed image, and -1 if an image with the right magic
365 * numbers could not be found.
367 * We currently check for the following magic numbers:
368 * minix
369 * ext2
370 * romfs
371 * gzip
373 __initfunc(int
374 identify_ramdisk_image(kdev_t device, struct file *fp, int start_block))
376 const int size = 512;
377 struct minix_super_block *minixsb;
378 struct ext2_super_block *ext2sb;
379 struct romfs_super_block *romfsb;
380 int nblocks = -1;
381 unsigned char *buf;
383 buf = kmalloc(size, GFP_KERNEL);
384 if (buf == 0)
385 return -1;
387 minixsb = (struct minix_super_block *) buf;
388 ext2sb = (struct ext2_super_block *) buf;
389 romfsb = (struct romfs_super_block *) buf;
390 memset(buf, 0xe5, size);
393 * Read block 0 to test for gzipped kernel
395 if (fp->f_op->llseek)
396 fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0);
397 fp->f_pos = start_block * BLOCK_SIZE;
399 fp->f_op->read(fp, buf, size, &fp->f_pos);
402 * If it matches the gzip magic numbers, return -1
404 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
405 printk(KERN_NOTICE
406 "RAMDISK: Compressed image found at block %d\n",
407 start_block);
408 nblocks = 0;
409 goto done;
412 /* romfs is at block zero too */
413 if (romfsb->word0 == ROMSB_WORD0 &&
414 romfsb->word1 == ROMSB_WORD1) {
415 printk(KERN_NOTICE
416 "RAMDISK: romfs filesystem found at block %d\n",
417 start_block);
418 nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
419 goto done;
423 * Read block 1 to test for minix and ext2 superblock
425 if (fp->f_op->llseek)
426 fp->f_op->llseek(fp, (start_block+1) * BLOCK_SIZE, 0);
427 fp->f_pos = (start_block+1) * BLOCK_SIZE;
429 fp->f_op->read(fp, buf, size, &fp->f_pos);
431 /* Try minix */
432 if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
433 minixsb->s_magic == MINIX_SUPER_MAGIC2) {
434 printk(KERN_NOTICE
435 "RAMDISK: Minix filesystem found at block %d\n",
436 start_block);
437 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
438 goto done;
441 /* Try ext2 */
442 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
443 printk(KERN_NOTICE
444 "RAMDISK: ext2 filesystem found at block %d\n",
445 start_block);
446 nblocks = le32_to_cpu(ext2sb->s_blocks_count);
447 goto done;
450 printk(KERN_NOTICE
451 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
452 start_block);
454 done:
455 if (fp->f_op->llseek)
456 fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0);
457 fp->f_pos = start_block * BLOCK_SIZE;
459 kfree(buf);
460 return nblocks;
464 * This routine loads in the RAM disk image.
466 __initfunc(static void rd_load_image(kdev_t device, int offset, int unit))
468 struct inode inode, out_inode;
469 struct file infile, outfile;
470 struct dentry in_dentry, out_dentry;
471 mm_segment_t fs;
472 kdev_t ram_device;
473 int nblocks, i;
474 char *buf;
475 unsigned short rotate = 0;
476 unsigned short devblocks = 0;
477 char rotator[4] = { '|' , '/' , '-' , '\\' };
479 ram_device = MKDEV(MAJOR_NR, unit);
481 memset(&infile, 0, sizeof(infile));
482 memset(&inode, 0, sizeof(inode));
483 memset(&in_dentry, 0, sizeof(in_dentry));
484 inode.i_rdev = device;
485 init_waitqueue_head(&inode.i_wait);
486 infile.f_mode = 1; /* read only */
487 infile.f_dentry = &in_dentry;
488 in_dentry.d_inode = &inode;
490 memset(&outfile, 0, sizeof(outfile));
491 memset(&out_inode, 0, sizeof(out_inode));
492 memset(&out_dentry, 0, sizeof(out_dentry));
493 out_inode.i_rdev = ram_device;
494 init_waitqueue_head(&out_inode.i_wait);
495 outfile.f_mode = 3; /* read/write */
496 outfile.f_dentry = &out_dentry;
497 out_dentry.d_inode = &out_inode;
499 if (blkdev_open(&inode, &infile) != 0) return;
500 if (blkdev_open(&out_inode, &outfile) != 0) return;
502 fs = get_fs();
503 set_fs(KERNEL_DS);
505 nblocks = identify_ramdisk_image(device, &infile, offset);
506 if (nblocks < 0)
507 goto done;
509 if (nblocks == 0) {
510 #ifdef BUILD_CRAMDISK
511 if (crd_load(&infile, &outfile) == 0)
512 goto successful_load;
513 #else
514 printk(KERN_NOTICE
515 "RAMDISK: Kernel does not support compressed "
516 "RAM disk images\n");
517 #endif
518 goto done;
521 if (nblocks > (rd_length[unit] >> RDBLK_SIZE_BITS)) {
522 printk("RAMDISK: image too big! (%d/%ld blocks)\n",
523 nblocks, rd_length[unit] >> RDBLK_SIZE_BITS);
524 goto done;
528 * OK, time to copy in the data
530 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
531 if (buf == 0) {
532 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
533 goto done;
536 if (blk_size[MAJOR(device)])
537 devblocks = blk_size[MAJOR(device)][MINOR(device)];
539 #ifdef CONFIG_BLK_DEV_INITRD
540 if (MAJOR(device) == MAJOR_NR && MINOR(device) == INITRD_MINOR)
541 devblocks = nblocks;
542 #endif
544 if (devblocks == 0) {
545 printk(KERN_ERR "RAMDISK: could not determine device size\n");
546 goto done;
549 printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ",
550 nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
551 for (i=0; i < nblocks; i++) {
552 if (i && (i % devblocks == 0)) {
553 printk("done disk #%d.\n", i/devblocks);
554 rotate = 0;
555 invalidate_buffers(device);
556 if (infile.f_op->release)
557 infile.f_op->release(&inode, &infile);
558 printk("Please insert disk #%d and press ENTER\n", i/devblocks+1);
559 wait_for_keypress();
560 if (blkdev_open(&inode, &infile) != 0) {
561 printk("Error opening disk.\n");
562 goto done;
564 infile.f_pos = 0;
565 printk("Loading disk #%d... ", i/devblocks+1);
567 infile.f_op->read(&infile, buf, BLOCK_SIZE, &infile.f_pos);
568 outfile.f_op->write(&outfile, buf, BLOCK_SIZE, &outfile.f_pos);
569 if (!(i % 16)) {
570 printk("%c\b", rotator[rotate & 0x3]);
571 rotate++;
574 printk("done.\n");
575 kfree(buf);
577 successful_load:
578 invalidate_buffers(device);
579 ROOT_DEV = MKDEV(MAJOR_NR, unit);
581 done:
582 if (infile.f_op->release)
583 infile.f_op->release(&inode, &infile);
584 set_fs(fs);
588 __initfunc(static void rd_load_disk(int n))
590 #ifdef CONFIG_BLK_DEV_INITRD
591 extern kdev_t real_root_dev;
592 #endif
594 if (rd_doload == 0)
595 return;
597 if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR
598 #ifdef CONFIG_BLK_DEV_INITRD
599 && MAJOR(real_root_dev) != FLOPPY_MAJOR
600 #endif
602 return;
604 if (rd_prompt) {
605 #ifdef CONFIG_BLK_DEV_FD
606 floppy_eject();
607 #endif
608 printk(KERN_NOTICE
609 "VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER\n");
610 wait_for_keypress();
613 rd_load_image(ROOT_DEV,rd_image_start, n);
617 __initfunc(void rd_load(void))
619 rd_load_disk(0);
622 __initfunc(void rd_load_secondary(void))
624 rd_load_disk(1);
627 #ifdef CONFIG_BLK_DEV_INITRD
628 __initfunc(void initrd_load(void))
630 rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),rd_image_start,0);
632 #endif
634 #endif /* RD_LOADER */
636 #ifdef BUILD_CRAMDISK
639 * gzip declarations
642 #define OF(args) args
644 #define memzero(s, n) memset ((s), 0, (n))
647 typedef unsigned char uch;
648 typedef unsigned short ush;
649 typedef unsigned long ulg;
651 #define INBUFSIZ 4096
652 #define WSIZE 0x8000 /* window size--must be a power of two, and */
653 /* at least 32K for zip's deflate method */
655 static uch *inbuf;
656 static uch *window;
658 static unsigned insize = 0; /* valid bytes in inbuf */
659 static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
660 static unsigned outcnt = 0; /* bytes in output buffer */
661 static int exit_code = 0;
662 static long bytes_out = 0;
663 static struct file *crd_infp, *crd_outfp;
665 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
667 /* Diagnostic functions (stubbed out) */
668 #define Assert(cond,msg)
669 #define Trace(x)
670 #define Tracev(x)
671 #define Tracevv(x)
672 #define Tracec(c,x)
673 #define Tracecv(c,x)
675 #define STATIC static
677 static int fill_inbuf(void);
678 static void flush_window(void);
679 static void *malloc(int size);
680 static void free(void *where);
681 static void error(char *m);
682 static void gzip_mark(void **);
683 static void gzip_release(void **);
685 #include "../../lib/inflate.c"
687 __initfunc(static void *malloc(int size))
689 return kmalloc(size, GFP_KERNEL);
692 __initfunc(static void free(void *where))
694 kfree(where);
697 __initfunc(static void gzip_mark(void **ptr))
701 __initfunc(static void gzip_release(void **ptr))
706 /* ===========================================================================
707 * Fill the input buffer. This is called only when the buffer is empty
708 * and at least one byte is really needed.
710 __initfunc(static int fill_inbuf(void))
712 if (exit_code) return -1;
714 insize = crd_infp->f_op->read(crd_infp, inbuf, INBUFSIZ,
715 &crd_infp->f_pos);
716 if (insize == 0) return -1;
718 inptr = 1;
720 return inbuf[0];
723 /* ===========================================================================
724 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
725 * (Used for the decompressed data only.)
727 __initfunc(static void flush_window(void))
729 ulg c = crc; /* temporary variable */
730 unsigned n;
731 uch *in, ch;
733 crd_outfp->f_op->write(crd_outfp, window, outcnt, &crd_outfp->f_pos);
734 in = window;
735 for (n = 0; n < outcnt; n++) {
736 ch = *in++;
737 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
739 crc = c;
740 bytes_out += (ulg)outcnt;
741 outcnt = 0;
744 __initfunc(static void error(char *x))
746 printk(KERN_ERR "%s", x);
747 exit_code = 1;
750 __initfunc(static int
751 crd_load(struct file * fp, struct file *outfp))
753 int result;
755 insize = 0; /* valid bytes in inbuf */
756 inptr = 0; /* index of next byte to be processed in inbuf */
757 outcnt = 0; /* bytes in output buffer */
758 exit_code = 0;
759 bytes_out = 0;
760 crc = (ulg)0xffffffffL; /* shift register contents */
762 crd_infp = fp;
763 crd_outfp = outfp;
764 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
765 if (inbuf == 0) {
766 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
767 return -1;
769 window = kmalloc(WSIZE, GFP_KERNEL);
770 if (window == 0) {
771 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
772 kfree(inbuf);
773 return -1;
775 makecrc();
776 result = gunzip();
777 kfree(inbuf);
778 kfree(window);
779 return result;
782 #endif /* BUILD_CRAMDISK */