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