Import 2.1.118
[davej-history.git] / drivers / block / rd.c
blobdd1933a47336eb7801d80c04b776e353f4dea7c8
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
43 #include <linux/config.h>
44 #include <linux/sched.h>
45 #include <linux/minix_fs.h>
46 #include <linux/ext2_fs.h>
47 #include <linux/romfs_fs.h>
48 #include <linux/fs.h>
49 #include <linux/kernel.h>
50 #include <linux/string.h>
51 #include <linux/mm.h>
52 #include <linux/mman.h>
53 #include <linux/malloc.h>
54 #include <linux/ioctl.h>
55 #include <linux/fd.h>
56 #include <linux/module.h>
57 #include <linux/init.h>
59 #include <asm/system.h>
60 #include <asm/uaccess.h>
61 #include <asm/byteorder.h>
63 extern void wait_for_keypress(void);
66 * 35 has been officially registered as the RAMDISK major number, but
67 * so is the original MAJOR number of 1. We're using 1 in
68 * include/linux/major.h for now
70 #define MAJOR_NR RAMDISK_MAJOR
71 #include <linux/blk.h>
73 /* The RAM disk size is now a parameter */
74 #define NUM_RAMDISKS 16 /* This cannot be overridden (yet) */
76 #ifndef MODULE
77 /* We don't have to load RAM disks or gunzip them in a module. */
78 #define RD_LOADER
79 #define BUILD_CRAMDISK
81 void rd_load(void);
82 static int crd_load(struct file *fp, struct file *outfp);
84 #ifdef CONFIG_BLK_DEV_INITRD
85 static int initrd_users = 0;
86 #endif
87 #endif
89 /* Various static variables go here. Most are used only in the RAM disk code.
92 static int rd_length[NUM_RAMDISKS];
93 static int rd_blocksizes[NUM_RAMDISKS];
96 * Parameters for the boot-loading of the RAM disk. These are set by
97 * init/main.c (from arguments to the kernel command line) or from the
98 * architecture-specific setup routine (from the stored boot sector
99 * information).
101 int rd_size = 4096; /* Size of the RAM disks */
103 #ifndef MODULE
104 int rd_doload = 0; /* 1 = load RAM disk, 0 = don't load */
105 int rd_prompt = 1; /* 1 = prompt for RAM disk, 0 = don't prompt */
106 int rd_image_start = 0; /* starting block # of image */
107 #ifdef CONFIG_BLK_DEV_INITRD
108 unsigned long initrd_start,initrd_end;
109 int mount_initrd = 1; /* zero if initrd should not be mounted */
110 int initrd_below_start_ok = 0;
111 #endif
112 #endif
115 * Basically, my strategy here is to set up a buffer-head which can't be
116 * deleted, and make that my Ramdisk. If the request is outside of the
117 * allocated size, we must get rid of it...
120 static void rd_request(void)
122 unsigned int minor;
123 int offset, len;
125 repeat:
126 INIT_REQUEST;
128 minor = MINOR(CURRENT->rq_dev);
130 if (minor >= NUM_RAMDISKS) {
131 end_request(0);
132 goto repeat;
135 offset = CURRENT->sector << 9;
136 len = CURRENT->current_nr_sectors << 9;
138 if ((offset + len) > rd_length[minor]) {
139 end_request(0);
140 goto repeat;
144 * If we're reading, fill the buffer with 0's. This is okay since
145 * we're using protected buffers which should never get freed...
147 * If we're writing, we protect the buffer.
150 if (CURRENT->cmd == READ)
151 memset(CURRENT->buffer, 0, len);
152 else
153 set_bit(BH_Protected, &CURRENT->bh->b_state);
155 end_request(1);
156 goto repeat;
159 static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
161 int err;
163 if (!inode || !inode->i_rdev)
164 return -EINVAL;
166 switch (cmd) {
167 case BLKFLSBUF:
168 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
169 invalidate_buffers(inode->i_rdev);
170 break;
171 case BLKGETSIZE: /* Return device size */
172 if (!arg) return -EINVAL;
173 err = verify_area(VERIFY_WRITE, (long *) arg,
174 sizeof(long));
175 if (err)
176 return err;
177 put_user(rd_length[MINOR(inode->i_rdev)] / 512,
178 (long *) arg);
179 return 0;
181 default:
182 break;
185 return 0;
189 #ifdef CONFIG_BLK_DEV_INITRD
191 static ssize_t initrd_read(struct file *file, char *buf,
192 size_t count, loff_t *ppos)
194 int left;
196 left = initrd_end - initrd_start - *ppos;
197 if (count > left) count = left;
198 if (count == 0) return 0;
199 copy_to_user(buf, (char *)initrd_start + *ppos, count);
200 *ppos += count;
201 return count;
205 static int initrd_release(struct inode *inode,struct file *file)
207 unsigned long i;
209 if (--initrd_users) return 0;
210 for (i = initrd_start; i < initrd_end; i += PAGE_SIZE)
211 free_page(i);
212 initrd_start = 0;
213 return 0;
217 static struct file_operations initrd_fops = {
218 NULL, /* lseek */
219 initrd_read, /* read */
220 NULL, /* write */
221 NULL, /* readdir */
222 NULL, /* poll */
223 NULL, /* ioctl */
224 NULL, /* mmap */
225 NULL, /* open */
226 NULL, /* flush */
227 initrd_release, /* release */
228 NULL /* fsync */
231 #endif
234 static int rd_open(struct inode * inode, struct file * filp)
236 #ifdef CONFIG_BLK_DEV_INITRD
237 if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
238 if (!initrd_start) return -ENODEV;
239 initrd_users++;
240 filp->f_op = &initrd_fops;
241 return 0;
243 #endif
245 if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
246 return -ENXIO;
248 MOD_INC_USE_COUNT;
250 return 0;
253 static int rd_release(struct inode * inode, struct file * filp)
255 MOD_DEC_USE_COUNT;
256 return 0;
259 static struct file_operations fd_fops = {
260 NULL, /* lseek - default */
261 block_read, /* read - block dev read */
262 block_write, /* write - block dev write */
263 NULL, /* readdir - not here! */
264 NULL, /* poll */
265 rd_ioctl, /* ioctl */
266 NULL, /* mmap */
267 rd_open, /* open */
268 NULL, /* flush */
269 rd_release, /* module needs to decrement use count */
270 block_fsync /* fsync */
273 /* This is the registration and initialization section of the RAM disk driver */
274 __initfunc(int rd_init(void))
276 int i;
278 if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) {
279 printk("RAMDISK: Could not get major %d", MAJOR_NR);
280 return -EIO;
283 blk_dev[MAJOR_NR].request_fn = &rd_request;
285 for (i = 0; i < NUM_RAMDISKS; i++) {
286 rd_length[i] = (rd_size * 1024);
287 rd_blocksizes[i] = 1024;
290 blksize_size[MAJOR_NR] = rd_blocksizes;
292 printk("RAM disk driver initialized: %d RAM disks of %dK size\n",
293 NUM_RAMDISKS, rd_size);
295 return 0;
298 /* loadable module support */
300 #ifdef MODULE
302 int init_module(void)
304 int error = rd_init();
305 if (!error)
306 printk(KERN_INFO "RAMDISK: Loaded as module.\n");
307 return error;
310 /* Before freeing the module, invalidate all of the protected buffers! */
311 void cleanup_module(void)
313 int i;
315 for (i = 0 ; i < NUM_RAMDISKS; i++)
316 invalidate_buffers(MKDEV(MAJOR_NR, i));
318 unregister_blkdev( MAJOR_NR, "ramdisk" );
319 blk_dev[MAJOR_NR].request_fn = 0;
322 #endif /* MODULE */
324 /* End of non-loading portions of the RAM disk driver */
326 #ifdef RD_LOADER
328 * This routine tries to find a RAM disk image to load, and returns the
329 * number of blocks to read for a non-compressed image, 0 if the image
330 * is a compressed image, and -1 if an image with the right magic
331 * numbers could not be found.
333 * We currently check for the following magic numbers:
334 * minix
335 * ext2
336 * romfs
337 * gzip
339 __initfunc(int
340 identify_ramdisk_image(kdev_t device, struct file *fp, int start_block))
342 const int size = 512;
343 struct minix_super_block *minixsb;
344 struct ext2_super_block *ext2sb;
345 struct romfs_super_block *romfsb;
346 int nblocks = -1;
347 unsigned char *buf;
349 buf = kmalloc(size, GFP_KERNEL);
350 if (buf == 0)
351 return -1;
353 minixsb = (struct minix_super_block *) buf;
354 ext2sb = (struct ext2_super_block *) buf;
355 romfsb = (struct romfs_super_block *) buf;
356 memset(buf, 0xe5, size);
359 * Read block 0 to test for gzipped kernel
361 if (fp->f_op->llseek)
362 fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0);
363 fp->f_pos = start_block * BLOCK_SIZE;
365 fp->f_op->read(fp, buf, size, &fp->f_pos);
368 * If it matches the gzip magic numbers, return -1
370 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
371 printk(KERN_NOTICE
372 "RAMDISK: Compressed image found at block %d\n",
373 start_block);
374 nblocks = 0;
375 goto done;
378 /* romfs is at block zero too */
379 if (romfsb->word0 == ROMSB_WORD0 &&
380 romfsb->word1 == ROMSB_WORD1) {
381 printk(KERN_NOTICE
382 "RAMDISK: romfs filesystem found at block %d\n",
383 start_block);
384 nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
385 goto done;
389 * Read block 1 to test for minix and ext2 superblock
391 if (fp->f_op->llseek)
392 fp->f_op->llseek(fp, (start_block+1) * BLOCK_SIZE, 0);
393 fp->f_pos = (start_block+1) * BLOCK_SIZE;
395 fp->f_op->read(fp, buf, size, &fp->f_pos);
397 /* Try minix */
398 if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
399 minixsb->s_magic == MINIX_SUPER_MAGIC2) {
400 printk(KERN_NOTICE
401 "RAMDISK: Minix filesystem found at block %d\n",
402 start_block);
403 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
404 goto done;
407 /* Try ext2 */
408 if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
409 printk(KERN_NOTICE
410 "RAMDISK: ext2 filesystem found at block %d\n",
411 start_block);
412 nblocks = le32_to_cpu(ext2sb->s_blocks_count);
413 goto done;
416 printk(KERN_NOTICE
417 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
418 start_block);
420 done:
421 if (fp->f_op->llseek)
422 fp->f_op->llseek(fp, start_block * BLOCK_SIZE, 0);
423 fp->f_pos = start_block * BLOCK_SIZE;
425 kfree(buf);
426 return nblocks;
430 * This routine loads in the RAM disk image.
432 __initfunc(static void rd_load_image(kdev_t device,int offset))
434 struct inode inode, out_inode;
435 struct file infile, outfile;
436 struct dentry in_dentry, out_dentry;
437 mm_segment_t fs;
438 kdev_t ram_device;
439 int nblocks, i;
440 char *buf;
441 unsigned short rotate = 0;
442 unsigned short devblocks = 0;
443 char rotator[4] = { '|' , '/' , '-' , '\\' };
445 ram_device = MKDEV(MAJOR_NR, 0);
447 memset(&infile, 0, sizeof(infile));
448 memset(&inode, 0, sizeof(inode));
449 memset(&in_dentry, 0, sizeof(in_dentry));
450 inode.i_rdev = device;
451 infile.f_mode = 1; /* read only */
452 infile.f_dentry = &in_dentry;
453 in_dentry.d_inode = &inode;
455 memset(&outfile, 0, sizeof(outfile));
456 memset(&out_inode, 0, sizeof(out_inode));
457 memset(&out_dentry, 0, sizeof(out_dentry));
458 out_inode.i_rdev = ram_device;
459 outfile.f_mode = 3; /* read/write */
460 outfile.f_dentry = &out_dentry;
461 out_dentry.d_inode = &out_inode;
463 if (blkdev_open(&inode, &infile) != 0) return;
464 if (blkdev_open(&out_inode, &outfile) != 0) return;
466 fs = get_fs();
467 set_fs(KERNEL_DS);
469 nblocks = identify_ramdisk_image(device, &infile, offset);
470 if (nblocks < 0)
471 goto done;
473 if (nblocks == 0) {
474 #ifdef BUILD_CRAMDISK
475 if (crd_load(&infile, &outfile) == 0)
476 goto successful_load;
477 #else
478 printk(KERN_NOTICE
479 "RAMDISK: Kernel does not support compressed "
480 "RAM disk images\n");
481 #endif
482 goto done;
485 if (nblocks > (rd_length[0] >> BLOCK_SIZE_BITS)) {
486 printk("RAMDISK: image too big! (%d/%d blocks)\n",
487 nblocks, rd_length[0] >> BLOCK_SIZE_BITS);
488 goto done;
492 * OK, time to copy in the data
494 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
495 if (buf == 0) {
496 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
497 goto done;
500 if (blk_size[MAJOR(device)])
501 devblocks = blk_size[MAJOR(device)][MINOR(device)];
503 #ifdef CONFIG_BLK_DEV_INITRD
504 if (MAJOR(device) == MAJOR_NR && MINOR(device) == INITRD_MINOR)
505 devblocks = nblocks;
506 #endif
508 if (devblocks == 0) {
509 printk(KERN_ERR "RAMDISK: could not determine device size\n");
510 goto done;
513 printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ",
514 nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
515 for (i=0; i < nblocks; i++) {
516 if (i && (i % devblocks == 0)) {
517 printk("done disk #%d.\n", i/devblocks);
518 rotate = 0;
519 invalidate_buffers(device);
520 if (infile.f_op->release)
521 infile.f_op->release(&inode, &infile);
522 printk("Please insert disk #%d and press ENTER\n", i/devblocks+1);
523 wait_for_keypress();
524 if (blkdev_open(&inode, &infile) != 0) {
525 printk("Error opening disk.\n");
526 goto done;
528 infile.f_pos = 0;
529 printk("Loading disk #%d... ", i/devblocks+1);
531 infile.f_op->read(&infile, buf, BLOCK_SIZE, &infile.f_pos);
532 outfile.f_op->write(&outfile, buf, BLOCK_SIZE, &outfile.f_pos);
533 if (!(i % 16)) {
534 printk("%c\b", rotator[rotate & 0x3]);
535 rotate++;
538 printk("done.\n");
539 kfree(buf);
541 successful_load:
542 invalidate_buffers(device);
543 ROOT_DEV = MKDEV(MAJOR_NR,0);
545 done:
546 if (infile.f_op->release)
547 infile.f_op->release(&inode, &infile);
548 set_fs(fs);
552 __initfunc(void rd_load(void))
554 if (rd_doload == 0)
555 return;
557 if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR) return;
559 if (rd_prompt) {
560 #ifdef CONFIG_BLK_DEV_FD
561 floppy_eject();
562 #endif
563 printk(KERN_NOTICE
564 "VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER\n");
565 wait_for_keypress();
568 rd_load_image(ROOT_DEV,rd_image_start);
573 #ifdef CONFIG_BLK_DEV_INITRD
574 __initfunc(void initrd_load(void))
576 rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),0);
578 #endif
580 #endif /* RD_LOADER */
582 #ifdef BUILD_CRAMDISK
585 * gzip declarations
588 #define OF(args) args
590 #define memzero(s, n) memset ((s), 0, (n))
593 typedef unsigned char uch;
594 typedef unsigned short ush;
595 typedef unsigned long ulg;
597 #define INBUFSIZ 4096
598 #define WSIZE 0x8000 /* window size--must be a power of two, and */
599 /* at least 32K for zip's deflate method */
601 static uch *inbuf;
602 static uch *window;
604 static unsigned insize = 0; /* valid bytes in inbuf */
605 static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
606 static unsigned outcnt = 0; /* bytes in output buffer */
607 static int exit_code = 0;
608 static long bytes_out = 0;
609 static struct file *crd_infp, *crd_outfp;
611 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
613 /* Diagnostic functions (stubbed out) */
614 #define Assert(cond,msg)
615 #define Trace(x)
616 #define Tracev(x)
617 #define Tracevv(x)
618 #define Tracec(c,x)
619 #define Tracecv(c,x)
621 #define STATIC static
623 static int fill_inbuf(void);
624 static void flush_window(void);
625 static void *malloc(int size);
626 static void free(void *where);
627 static void error(char *m);
628 static void gzip_mark(void **);
629 static void gzip_release(void **);
631 #include "../../lib/inflate.c"
633 __initfunc(static void *malloc(int size))
635 return kmalloc(size, GFP_KERNEL);
638 __initfunc(static void free(void *where))
640 kfree(where);
643 __initfunc(static void gzip_mark(void **ptr))
647 __initfunc(static void gzip_release(void **ptr))
652 /* ===========================================================================
653 * Fill the input buffer. This is called only when the buffer is empty
654 * and at least one byte is really needed.
656 __initfunc(static int fill_inbuf(void))
658 if (exit_code) return -1;
660 insize = crd_infp->f_op->read(crd_infp, inbuf, INBUFSIZ,
661 &crd_infp->f_pos);
662 if (insize == 0) return -1;
664 inptr = 1;
666 return inbuf[0];
669 /* ===========================================================================
670 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
671 * (Used for the decompressed data only.)
673 __initfunc(static void flush_window(void))
675 ulg c = crc; /* temporary variable */
676 unsigned n;
677 uch *in, ch;
679 crd_outfp->f_op->write(crd_outfp, window, outcnt, &crd_outfp->f_pos);
680 in = window;
681 for (n = 0; n < outcnt; n++) {
682 ch = *in++;
683 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
685 crc = c;
686 bytes_out += (ulg)outcnt;
687 outcnt = 0;
690 __initfunc(static void error(char *x))
692 printk(KERN_ERR "%s", x);
693 exit_code = 1;
696 __initfunc(static int
697 crd_load(struct file * fp, struct file *outfp))
699 int result;
701 crd_infp = fp;
702 crd_outfp = outfp;
703 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
704 if (inbuf == 0) {
705 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
706 return -1;
708 window = kmalloc(WSIZE, GFP_KERNEL);
709 if (window == 0) {
710 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
711 kfree(inbuf);
712 return -1;
714 makecrc();
715 result = gunzip();
716 kfree(inbuf);
717 kfree(window);
718 return result;
721 #endif /* BUILD_CRAMDISK */