This source file includes following definitions.
- rd_request
- rd_ioctl
- rd_open
- rd_release
- rd_init
- identify_ramdisk_image
- rd_load
- malloc
- free
- gzip_mark
- gzip_release
- fill_inbuf
- flush_window
- error
- crd_load
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <linux/sched.h>
31 #include <linux/minix_fs.h>
32 #include <linux/ext2_fs.h>
33 #include <linux/fs.h>
34 #include <linux/kernel.h>
35 #include <linux/string.h>
36 #include <linux/mm.h>
37 #include <linux/mman.h>
38 #include <linux/malloc.h>
39 #include <linux/ioctl.h>
40 #include <linux/module.h>
41
42 #include <asm/system.h>
43 #include <asm/segment.h>
44
45 extern void wait_for_keypress(void);
46
47
48
49
50
51
52 #define MAJOR_NR RAMDISK_MAJOR
53 #include <linux/blk.h>
54
55 #define BUILD_CRAMDISK
56 #define NUM_RAMDISKS 8
57
58 #ifndef MODULE
59 void rd_load(void);
60 static int crd_load(struct file *fp, struct file *outfp);
61 #endif
62
63
64
65 static int rd_length[NUM_RAMDISKS];
66 static int rd_blocksizes[NUM_RAMDISKS];
67
68
69
70
71
72
73
74 #ifndef MODULE
75 int rd_doload = 0;
76 int rd_prompt = 1;
77 int rd_image_start = 0;
78 #endif
79
80
81
82
83
84
85
86 static void rd_request(void)
87 {
88 unsigned int minor;
89 int offset, len;
90
91 repeat:
92 INIT_REQUEST;
93
94 minor = MINOR(CURRENT->rq_dev);
95
96 if (minor >= NUM_RAMDISKS) {
97 end_request(0);
98 goto repeat;
99 }
100
101 offset = CURRENT->sector << 9;
102 len = CURRENT->current_nr_sectors << 9;
103
104 if ((offset + len) > rd_length[minor]) {
105 end_request(0);
106 goto repeat;
107 }
108
109 if (CURRENT->cmd == READ) {
110 memset(CURRENT->buffer, 0, len);
111 }
112 set_bit(BH_Protected, &CURRENT->bh->b_state);
113
114 end_request(1);
115 goto repeat;
116 }
117
118 static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
119 {
120 int err;
121
122 if (!inode || !inode->i_rdev)
123 return -EINVAL;
124
125 switch (cmd) {
126 case BLKFLSBUF:
127 if (!suser()) return -EACCES;
128 invalidate_buffers(inode->i_rdev);
129 break;
130 case BLKGETSIZE:
131 if (!arg) return -EINVAL;
132 err = verify_area(VERIFY_WRITE, (long *) arg,
133 sizeof(long));
134 if (err)
135 return err;
136 put_user(rd_length[MINOR(inode->i_rdev)] / 512,
137 (long *) arg);
138 return 0;
139
140 default:
141 break;
142 };
143
144 return 0;
145 }
146
147 static int rd_open(struct inode * inode, struct file * filp)
148 {
149
150 if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
151 return -ENODEV;
152
153 MOD_INC_USE_COUNT;
154
155 return 0;
156 }
157
158 #ifdef MODULE
159 static void rd_release(struct inode * inode, struct file * filp)
160 {
161 MOD_DEC_USE_COUNT;
162 }
163 #endif
164
165 static struct file_operations fd_fops = {
166 NULL,
167 block_read,
168 block_write,
169 NULL,
170 NULL,
171 rd_ioctl,
172 NULL,
173 rd_open,
174 #ifndef MODULE
175 NULL,
176 #else
177 rd_release,
178 #endif
179 block_fsync
180 };
181
182
183 int rd_init(void)
184 {
185 int i;
186
187 if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) {
188 printk("RAMDISK: Could not get major %d", MAJOR_NR);
189 return -EIO;
190 }
191
192 blk_dev[MAJOR_NR].request_fn = &rd_request;
193
194 for (i = 0; i < NUM_RAMDISKS; i++) {
195 rd_length[i] = (16384 * 1024);
196 rd_blocksizes[i] = 1024;
197 }
198
199 blksize_size[MAJOR_NR] = rd_blocksizes;
200
201 return 0;
202 }
203
204 #ifndef MODULE
205
206
207
208
209
210
211
212
213
214
215
216 int
217 identify_ramdisk_image(int device, struct file *fp, int start_block)
218 {
219 const int size = 512;
220 struct minix_super_block *minixsb;
221 struct ext2_super_block *ext2sb;
222 int nblocks = -1;
223 int max_blocks;
224 unsigned char *buf;
225
226 buf = kmalloc(size, GFP_KERNEL);
227 if (buf == 0)
228 return -1;
229
230 minixsb = (struct minix_super_block *) buf;
231 ext2sb = (struct ext2_super_block *) buf;
232 memset(buf, 0xe5, size);
233
234
235
236
237 if (fp->f_op->lseek)
238 fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
239 fp->f_pos = start_block * BLOCK_SIZE;
240
241 fp->f_op->read(fp->f_inode, fp, buf, size);
242
243
244
245
246 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
247 printk(KERN_NOTICE
248 "RAMDISK: Compressed image found at block %d\n",
249 start_block);
250 nblocks = 0;
251 goto done;
252 }
253
254
255
256
257 if (fp->f_op->lseek)
258 fp->f_op->lseek(fp->f_inode, fp,
259 (start_block+1) * BLOCK_SIZE, 0);
260 fp->f_pos = (start_block+1) * BLOCK_SIZE;
261
262 fp->f_op->read(fp->f_inode, fp, buf, size);
263
264
265 if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
266 minixsb->s_magic == MINIX_SUPER_MAGIC2) {
267 printk(KERN_NOTICE
268 "RAMDISK: Minix filesystem found at block %d\n",
269 start_block);
270 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
271 goto done;
272 }
273
274
275 if (ext2sb->s_magic == EXT2_SUPER_MAGIC) {
276 printk(KERN_NOTICE
277 "RAMDISK: Ext2 filesystem found at block %d\n",
278 start_block);
279 nblocks = ext2sb->s_blocks_count;
280 goto done;
281 }
282 printk(KERN_NOTICE
283 "RAMDISK: Couldn't find valid ramdisk image starting at %d.\n",
284 start_block);
285
286 done:
287 if (fp->f_op->lseek)
288 fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
289 fp->f_pos = start_block * BLOCK_SIZE;
290
291 if ((nblocks > 0) && blk_size[MAJOR(device)]) {
292 max_blocks = blk_size[MAJOR(device)][MINOR(device)];
293 max_blocks -= start_block;
294 if (nblocks > max_blocks) {
295 printk(KERN_NOTICE
296 "RAMDISK: Restricting filesystem size "
297 "from %d to %d blocks.\n",
298 nblocks, max_blocks);
299 nblocks = max_blocks;
300 }
301 }
302 kfree(buf);
303 return nblocks;
304 }
305
306
307
308
309 void rd_load()
310 {
311 struct inode inode, out_inode;
312 struct file infile, outfile;
313 unsigned short fs;
314 int device, ram_device;
315 int nblocks, i;
316 char *buf;
317 unsigned short rotate = 0;
318 char rotator[4] = { '|' , '/' , '-' , '\\' };
319
320 if (rd_doload == 0)
321 return;
322
323 device = ROOT_DEV;
324 ram_device = (MAJOR_NR << 8);
325
326 if (MAJOR(device) != FLOPPY_MAJOR) return;
327
328 if (rd_prompt) {
329 printk(KERN_NOTICE
330 "VFS: Insert ramdisk floppy and press ENTER\n");
331 wait_for_keypress();
332 }
333
334 memset(&infile, 0, sizeof(infile));
335 memset(&inode, 0, sizeof(inode));
336 inode.i_rdev = device;
337 infile.f_mode = 1;
338 infile.f_inode = &inode;
339
340 memset(&outfile, 0, sizeof(outfile));
341 memset(&out_inode, 0, sizeof(out_inode));
342 out_inode.i_rdev = ram_device;
343 outfile.f_mode = 3;
344 outfile.f_inode = &out_inode;
345
346 if (blkdev_open(&inode, &infile) != 0) return;
347 if (blkdev_open(&out_inode, &outfile) != 0) return;
348
349 fs = get_fs();
350 set_fs(KERNEL_DS);
351
352 nblocks = identify_ramdisk_image(device, &infile, rd_image_start);
353 if (nblocks < 0)
354 goto done;
355
356 if (nblocks == 0) {
357 #ifdef BUILD_CRAMDISK
358 if (crd_load(&infile, &outfile) == 0)
359 goto successful_load;
360 #else
361 printk(KERN_NOTICE
362 "RAMDISK: Kernel does not support compressed "
363 "ramdisk images\n");
364 #endif
365 goto done;
366 }
367
368 if (nblocks > (rd_length[0] >> BLOCK_SIZE_BITS)) {
369 printk("RAMDISK: image too big! (%d/%d blocks)\n",
370 nblocks, rd_length[0] >> BLOCK_SIZE_BITS);
371 goto done;
372 }
373
374
375
376
377 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
378 if (buf == 0) {
379 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
380 goto done;
381 }
382
383 printk(KERN_NOTICE "RAMDISK: Loading %d blocks into ram disk... ", nblocks);
384 for (i=0; i < nblocks; i++) {
385 infile.f_op->read(infile.f_inode, &infile, buf,
386 BLOCK_SIZE);
387 outfile.f_op->write(outfile.f_inode, &outfile, buf,
388 BLOCK_SIZE);
389 if (!(i % 16)) {
390 printk("%c\b", rotator[rotate & 0x3]);
391 rotate++;
392 }
393 }
394 printk("done.\n");
395 kfree(buf);
396
397 successful_load:
398 invalidate_buffers(ROOT_DEV);
399 ROOT_DEV = (MAJOR_NR << 8);
400
401 done:
402 if (infile.f_op->release)
403 infile.f_op->release(&inode, &infile);
404 set_fs(fs);
405 }
406
407 #ifdef BUILD_CRAMDISK
408
409
410
411
412
413 #define OF(args) args
414
415 #define memzero(s, n) memset ((s), 0, (n))
416
417
418 typedef unsigned char uch;
419 typedef unsigned short ush;
420 typedef unsigned long ulg;
421
422 #define INBUFSIZ 4096
423 #define WSIZE 0x8000
424
425
426 static uch *inbuf;
427 static uch *window;
428
429 static unsigned insize = 0;
430 static unsigned inptr = 0;
431 static unsigned outcnt = 0;
432 static exit_code = 0;
433 static long bytes_out = 0;
434 static struct file *crd_infp, *crd_outfp;
435
436 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
437
438
439 #define Assert(cond,msg)
440 #define Trace(x)
441 #define Tracev(x)
442 #define Tracevv(x)
443 #define Tracec(c,x)
444 #define Tracecv(c,x)
445
446 #define STATIC static
447
448 static int fill_inbuf(void);
449 static void flush_window(void);
450 static void *malloc(int size);
451 static void free(void *where);
452 static void error(char *m);
453 static void gzip_mark(void **);
454 static void gzip_release(void **);
455
456 #include "../../lib/inflate.c"
457
458 static void *malloc(int size)
459 {
460 return kmalloc(size, GFP_KERNEL);
461 }
462
463 static void free(void *where)
464 {
465 kfree(where);
466 }
467
468 static void gzip_mark(void **ptr)
469 {
470 }
471
472 static void gzip_release(void **ptr)
473 {
474 }
475
476
477
478
479
480
481 static int fill_inbuf()
482 {
483 if (exit_code) return -1;
484
485 insize = crd_infp->f_op->read(crd_infp->f_inode, crd_infp,
486 inbuf, INBUFSIZ);
487 if (insize == 0) return -1;
488
489 inptr = 1;
490
491 return inbuf[0];
492 }
493
494
495
496
497
498 static void flush_window()
499 {
500 ulg c = crc;
501 unsigned n;
502 uch *in, ch;
503
504 crd_outfp->f_op->write(crd_outfp->f_inode, crd_outfp, window,
505 outcnt);
506 in = window;
507 for (n = 0; n < outcnt; n++) {
508 ch = *in++;
509 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
510 }
511 crc = c;
512 bytes_out += (ulg)outcnt;
513 outcnt = 0;
514 }
515
516 static void error(char *x)
517 {
518 printk(KERN_ERR "%s", x);
519 exit_code = 1;
520 }
521
522 static int
523 crd_load(struct file * fp, struct file *outfp)
524 {
525 int result;
526
527 crd_infp = fp;
528 crd_outfp = outfp;
529 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
530 if (inbuf == 0) {
531 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
532 return -1;
533 }
534 window = kmalloc(WSIZE, GFP_KERNEL);
535 if (window == 0) {
536 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
537 kfree(inbuf);
538 return -1;
539 }
540 makecrc();
541 result = gunzip();
542 kfree(inbuf);
543 kfree(window);
544 return result;
545 }
546
547 #endif
548
549 #endif
550
551
552
553
554 #ifdef MODULE
555
556 int init_module(void)
557 {
558 int error = rd_init();
559 if (!error)
560 printk(KERN_INFO "RAMDISK: Loaded as module.\n");
561 return error;
562 }
563
564 void cleanup_module(void)
565 {
566 unregister_blkdev( MAJOR_NR, "ramdisk" );
567 blk_dev[MAJOR_NR].request_fn = 0;
568 }
569
570 #endif