root/drivers/block/rd.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rd_request
  2. rd_ioctl
  3. initrd_read
  4. initrd_release
  5. rd_open
  6. rd_release
  7. rd_init
  8. init_module
  9. cleanup_module
  10. identify_ramdisk_image
  11. rd_load_image
  12. rd_load
  13. initrd_load
  14. malloc
  15. free
  16. gzip_mark
  17. gzip_release
  18. fill_inbuf
  19. flush_window
  20. error
  21. crd_load

   1 /*
   2  * ramdisk.c - Multiple ramdisk driver - gzip-loading version - v. 0.8 beta.
   3  * 
   4  * (C) Chad Page, Theodore Ts'o, et. al, 1995. 
   5  *
   6  * This ramdisk 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  * ramdisk data.  This makes it possible to dynamically allocate the ramdisk
  11  * buffer - with some consequences I have to deal with as I write this. 
  12  * 
  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 ramdisk data in
  16  * 1995; Theodore then took over the driver again, and cleaned it up
  17  * for inclusion in the mainline kernel.
  18  *
  19  * The original CRAMDISK code was written by Richard Lyons, and
  20  * adapted by Chad Page to use the new ramdisk interface.  Theodore
  21  * Ts'o rewrote it so that both the compressed ramdisk loader and the
  22  * kernel decompressor uses the same inflate.c codebase.  The ramdisk
  23  * loader now also loads into a dynamic (buffer cache based) ramdisk,
  24  * not the old static ramdisk.  Support for the old static ramdisk has
  25  * been completely removed.
  26  *
  27  * Loadable module support added by Tom Dyas.
  28  *
  29  * Further cleanups by Chad Page (page0588@sundance.sjsu.edu):
  30  *      Cosmetic changes in #ifdef MODULE, code movement, etc...
  31  *      When the ramdisk is rmmod'ed, free the protected buffers
  32  *      Default ramdisk size changed to 2.88MB
  33  *
  34  *  Added initrd: Werner Almesberger & Hans Lermen, Feb '96
  35  */
  36 
  37 #include <linux/config.h>
  38 #include <linux/sched.h>
  39 #include <linux/minix_fs.h>
  40 #include <linux/ext2_fs.h>
  41 #include <linux/fs.h>
  42 #include <linux/kernel.h>
  43 #include <linux/string.h>
  44 #include <linux/mm.h>
  45 #include <linux/mman.h>
  46 #include <linux/malloc.h>
  47 #include <linux/ioctl.h>
  48 #include <linux/module.h>
  49 
  50 #include <asm/system.h>
  51 #include <asm/segment.h>
  52 
  53 extern void wait_for_keypress(void);
  54 
  55 /*
  56  * 35 has been officially registered as the RAMDISK major number, but
  57  * so is the original MAJOR number of 1.  We're using 1 in
  58  * include/linux/major.h for now
  59  */
  60 #define MAJOR_NR RAMDISK_MAJOR
  61 #include <linux/blk.h>
  62 
  63 /* These *should* be defined as parameters */
  64 #define NUM_RAMDISKS 8
  65 #define RD_DEFAULTSIZE  2880    /* 2.88 MB */
  66 
  67 #ifndef MODULE
  68 /* We don't have to load ramdisks or gunzip them in a module... */
  69 #define RD_LOADER
  70 #define BUILD_CRAMDISK
  71 
  72 void rd_load(void);
  73 static int crd_load(struct file *fp, struct file *outfp);
  74 
  75 #ifdef CONFIG_BLK_DEV_INITRD
  76 static int initrd_users = 0;
  77 #endif
  78 #endif
  79 
  80 /* Various static variables go here... mostly used within the ramdisk code only. */
  81 
  82 static int rd_length[NUM_RAMDISKS];
  83 static int rd_blocksizes[NUM_RAMDISKS];
  84 
  85 /*
  86  * Parameters for the boot-loading of the ramdisk.  These are set by
  87  * init/main.c (from arguments to the kernel command line) or from the
  88  * architecture-specific setup routine (from the stored bootsector
  89  * information). 
  90  */
  91 #ifndef MODULE
  92 int rd_doload = 0;              /* 1 = load ramdisk, 0 = don't load */
  93 int rd_prompt = 1;              /* 1 = prompt for ramdisk, 0 = don't prompt */
  94 int rd_image_start = 0;         /* starting block # of image */
  95 #ifdef CONFIG_BLK_DEV_INITRD
  96 unsigned long initrd_start,initrd_end;
  97 int mount_initrd = 1;           /* zero if initrd should not be mounted */
  98 #endif
  99 #endif
 100 
 101 /*
 102  *  Basically, my strategy here is to set up a buffer-head which can't be
 103  *  deleted, and make that my Ramdisk.  If the request is outside of the
 104  *  allocated size, we must get rid of it...
 105  *
 106  */
 107 static void rd_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 108 {
 109         unsigned int minor;
 110         int offset, len;
 111 
 112 repeat:
 113         INIT_REQUEST;
 114         
 115         minor = MINOR(CURRENT->rq_dev);
 116 
 117         if (minor >= NUM_RAMDISKS) {
 118                 end_request(0);
 119                 goto repeat;
 120         }
 121         
 122         offset = CURRENT->sector << 9;
 123         len = CURRENT->current_nr_sectors << 9;
 124 
 125         if ((offset + len) > rd_length[minor]) {
 126                 end_request(0);
 127                 goto repeat;
 128         }
 129 
 130         /*
 131          * If we're reading, fill the buffer with 0's.  This is okay since
 132          * we're using protected buffers which should never get freed...
 133          *
 134          * If we're writing, we protect the buffer.
 135          */
 136 
 137         if (CURRENT->cmd == READ) 
 138                 memset(CURRENT->buffer, 0, len); 
 139         else    
 140                 set_bit(BH_Protected, &CURRENT->bh->b_state);
 141 
 142         end_request(1);
 143         goto repeat;
 144 } 
 145 
 146 static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148         int err;
 149         
 150         if (!inode || !inode->i_rdev)   
 151                 return -EINVAL;
 152 
 153         switch (cmd) {
 154                 case BLKFLSBUF:
 155                         if (!suser()) return -EACCES;
 156                         invalidate_buffers(inode->i_rdev);
 157                         break;
 158                 case BLKGETSIZE:   /* Return device size */
 159                         if (!arg)  return -EINVAL;
 160                         err = verify_area(VERIFY_WRITE, (long *) arg,
 161                                           sizeof(long));
 162                         if (err)
 163                                 return err;
 164                         put_user(rd_length[MINOR(inode->i_rdev)] / 512, 
 165                                  (long *) arg);
 166                         return 0;
 167                         
 168                 default:
 169                         break;
 170         };
 171 
 172         return 0;
 173 }
 174 
 175 
 176 #ifdef CONFIG_BLK_DEV_INITRD
 177 
 178 static int initrd_read(struct inode *inode,struct file *file,char *buf,
     /* [previous][next][first][last][top][bottom][index][help] */
 179     int count)
 180 {
 181         int left;
 182 
 183         left = initrd_end-initrd_start-file->f_pos;
 184         if (count > left) count = left;
 185         if (count <= 0) return 0;
 186         memcpy_tofs(buf,(char *) initrd_start+file->f_pos,count);
 187         file->f_pos += count;
 188         return count;
 189 }
 190 
 191 
 192 static void initrd_release(struct inode *inode,struct file *file)
     /* [previous][next][first][last][top][bottom][index][help] */
 193 {
 194         unsigned long i;
 195 
 196         if (--initrd_users) return;
 197         for (i = initrd_start; i < initrd_end; i += PAGE_SIZE)
 198                 free_page(i);
 199         initrd_start = 0;
 200 }
 201 
 202 
 203 static struct file_operations initrd_fops = {
 204         NULL,           /* lseek */
 205         initrd_read,    /* read */
 206         NULL,           /* write */
 207         NULL,           /* readdir */
 208         NULL,           /* select */
 209         NULL,           /* ioctl */
 210         NULL,           /* mmap */
 211         NULL,           /* open */
 212         initrd_release, /* release */
 213         NULL            /* fsync */ 
 214 };
 215 
 216 #endif
 217 
 218 
 219 static int rd_open(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221 #ifdef CONFIG_BLK_DEV_INITRD
 222         if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
 223                 if (!initrd_start) return -ENODEV;
 224                 initrd_users++;
 225                 filp->f_op = &initrd_fops;
 226                 return 0;
 227         }
 228 #endif
 229 
 230         if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
 231                 return -ENODEV;
 232 
 233         MOD_INC_USE_COUNT;
 234 
 235         return 0;
 236 }
 237 
 238 #ifdef MODULE
 239 static void rd_release(struct inode * inode, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
 240 {
 241         MOD_DEC_USE_COUNT;
 242 }
 243 #endif
 244 
 245 static struct file_operations fd_fops = {
 246         NULL,           /* lseek - default */
 247         block_read,     /* read - block dev read */
 248         block_write,    /* write - block dev write */
 249         NULL,           /* readdir - not here! */
 250         NULL,           /* select */
 251         rd_ioctl,       /* ioctl */
 252         NULL,           /* mmap */
 253         rd_open,        /* open */
 254 #ifndef MODULE
 255         NULL,           /* no special release code... */
 256 #else
 257         rd_release,     /* module needs to decrement use count */
 258 #endif
 259         block_fsync             /* fsync */ 
 260 };
 261 
 262 /* This is the registration and initialization section of the ramdisk driver */
 263 int rd_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265         int             i;
 266 
 267         if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) {
 268                 printk("RAMDISK: Could not get major %d", MAJOR_NR);
 269                 return -EIO;
 270         }
 271 
 272         blk_dev[MAJOR_NR].request_fn = &rd_request;
 273 
 274         for (i = 0; i < NUM_RAMDISKS; i++) {
 275                 rd_length[i] = (RD_DEFAULTSIZE * 1024);
 276                 rd_blocksizes[i] = 1024;
 277         }
 278 
 279         blksize_size[MAJOR_NR] = rd_blocksizes;
 280 
 281         return 0;
 282 }
 283 
 284 /* loadable module support */
 285 
 286 #ifdef MODULE
 287 
 288 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 289 {
 290         int error = rd_init();
 291         if (!error)
 292                 printk(KERN_INFO "RAMDISK: Loaded as module.\n");
 293         return error;
 294 }
 295 
 296 /* Before freeing the module, invalidate all of the protected buffers! */
 297 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 298 {
 299         int i;
 300 
 301         for (i = 0 ; i < NUM_RAMDISKS; i++)
 302                 invalidate_buffers(MKDEV(MAJOR_NR, i));
 303 
 304         unregister_blkdev( MAJOR_NR, "ramdisk" );
 305         blk_dev[MAJOR_NR].request_fn = 0;
 306 }
 307 
 308 #endif  /* MODULE */
 309 
 310 /* End of non-loading portions of the ramdisk driver */
 311 
 312 #ifdef RD_LOADER 
 313 /*
 314  * This routine tries to a ramdisk image to load, and returns the
 315  * number of blocks to read for a non-compressed image, 0 if the image
 316  * is a compressed image, and -1 if an image with the right magic
 317  * numbers could not be found.
 318  *
 319  * We currently check for the following magic numbers:
 320  *      minix
 321  *      ext2
 322  *      gzip
 323  */
 324 int
 325 identify_ramdisk_image(kdev_t device, struct file *fp, int start_block)
     /* [previous][next][first][last][top][bottom][index][help] */
 326 {
 327         const int size = 512;
 328         struct minix_super_block *minixsb;
 329         struct ext2_super_block *ext2sb;
 330         int nblocks = -1;
 331         int max_blocks;
 332         unsigned char *buf;
 333 
 334         buf = kmalloc(size, GFP_KERNEL);
 335         if (buf == 0)
 336                 return -1;
 337 
 338         minixsb = (struct minix_super_block *) buf;
 339         ext2sb = (struct ext2_super_block *) buf;
 340         memset(buf, 0xe5, size);
 341 
 342         /*
 343          * Read block 0 to test for gzipped kernel
 344          */
 345         if (fp->f_op->lseek)
 346                 fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
 347         fp->f_pos = start_block * BLOCK_SIZE;
 348         
 349         fp->f_op->read(fp->f_inode, fp, buf, size);
 350 
 351         /*
 352          * If it matches the gzip magic numbers, return -1
 353          */
 354         if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
 355                 printk(KERN_NOTICE
 356                        "RAMDISK: Compressed image found at block %d\n",
 357                        start_block);
 358                 nblocks = 0;
 359                 goto done;
 360         }
 361 
 362         /*
 363          * Read block 1 to test for minix and ext2 superblock
 364          */
 365         if (fp->f_op->lseek)
 366                 fp->f_op->lseek(fp->f_inode, fp,
 367                                 (start_block+1) * BLOCK_SIZE, 0);
 368         fp->f_pos = (start_block+1) * BLOCK_SIZE;
 369 
 370         fp->f_op->read(fp->f_inode, fp, buf, size);
 371                 
 372         /* Try minix */
 373         if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
 374             minixsb->s_magic == MINIX_SUPER_MAGIC2) {
 375                 printk(KERN_NOTICE
 376                        "RAMDISK: Minix filesystem found at block %d\n",
 377                        start_block);
 378                 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
 379                 goto done;
 380         }
 381 
 382         /* Try ext2 */
 383         if (ext2sb->s_magic == EXT2_SUPER_MAGIC) {
 384                 printk(KERN_NOTICE
 385                        "RAMDISK: Ext2 filesystem found at block %d\n",
 386                        start_block);
 387                 nblocks = ext2sb->s_blocks_count;
 388                 goto done;
 389         }
 390         printk(KERN_NOTICE
 391                "RAMDISK: Couldn't find valid ramdisk image starting at %d.\n",
 392                start_block);
 393         
 394 done:
 395         if (fp->f_op->lseek)
 396                 fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
 397         fp->f_pos = start_block * BLOCK_SIZE;   
 398 
 399         if ((nblocks > 0) && blk_size[MAJOR(device)]) {
 400                 max_blocks = blk_size[MAJOR(device)][MINOR(device)];
 401                 max_blocks -= start_block;
 402                 if (nblocks > max_blocks) {
 403                         printk(KERN_NOTICE
 404                                "RAMDISK: Restricting filesystem size "
 405                                "from %d to %d blocks.\n",
 406                                nblocks, max_blocks);
 407                         nblocks = max_blocks;
 408                 }
 409         }
 410         kfree(buf);
 411         return nblocks;
 412 }
 413 
 414 /*
 415  * This routine loads in the ramdisk image.
 416  */
 417 static void rd_load_image(kdev_t device,int offset)
     /* [previous][next][first][last][top][bottom][index][help] */
 418 {
 419         struct inode inode, out_inode;
 420         struct file infile, outfile;
 421         unsigned short fs;
 422         kdev_t ram_device;
 423         int nblocks, i;
 424         char *buf;
 425         unsigned short rotate = 0;
 426         char rotator[4] = { '|' , '/' , '-' , '\\' };
 427 
 428         ram_device = MKDEV(MAJOR_NR, 0);
 429 
 430         memset(&infile, 0, sizeof(infile));
 431         memset(&inode, 0, sizeof(inode));
 432         inode.i_rdev = device;
 433         infile.f_mode = 1; /* read only */
 434         infile.f_inode = &inode;
 435 
 436         memset(&outfile, 0, sizeof(outfile));
 437         memset(&out_inode, 0, sizeof(out_inode));
 438         out_inode.i_rdev = ram_device;
 439         outfile.f_mode = 3; /* read/write */
 440         outfile.f_inode = &out_inode;
 441 
 442         if (blkdev_open(&inode, &infile) != 0) return;
 443         if (blkdev_open(&out_inode, &outfile) != 0) return;
 444 
 445         fs = get_fs();
 446         set_fs(KERNEL_DS);
 447         
 448         nblocks = identify_ramdisk_image(device, &infile, offset);
 449         if (nblocks < 0)
 450                 goto done;
 451 
 452         if (nblocks == 0) {
 453 #ifdef BUILD_CRAMDISK
 454                 if (crd_load(&infile, &outfile) == 0)
 455                         goto successful_load;
 456 #else
 457                 printk(KERN_NOTICE
 458                        "RAMDISK: Kernel does not support compressed "
 459                        "ramdisk images\n");
 460 #endif
 461                 goto done;
 462         }
 463 
 464         if (nblocks > (rd_length[0] >> BLOCK_SIZE_BITS)) {
 465                 printk("RAMDISK: image too big! (%d/%d blocks)\n",
 466                        nblocks, rd_length[0] >> BLOCK_SIZE_BITS);
 467                 goto done;
 468         }
 469                 
 470         /*
 471          * OK, time to copy in the data
 472          */
 473         buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
 474         if (buf == 0) {
 475                 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
 476                 goto done;
 477         }
 478 
 479         printk(KERN_NOTICE "RAMDISK: Loading %d blocks into ram disk... ", nblocks);
 480         for (i=0; i < nblocks; i++) {
 481                 infile.f_op->read(infile.f_inode, &infile, buf,
 482                                   BLOCK_SIZE);
 483                 outfile.f_op->write(outfile.f_inode, &outfile, buf,
 484                                     BLOCK_SIZE);
 485                 if (!(i % 16)) {
 486                         printk(KERN_NOTICE "%c\b", rotator[rotate & 0x3]);
 487                         rotate++;
 488                 }
 489         }
 490         printk("done.\n");
 491         kfree(buf);
 492 
 493 successful_load:
 494         invalidate_buffers(device);
 495         ROOT_DEV = MKDEV(MAJOR_NR,0);
 496 
 497 done:
 498         if (infile.f_op->release)
 499                 infile.f_op->release(&inode, &infile);
 500         set_fs(fs);
 501 }
 502 
 503 
 504 void rd_load()
     /* [previous][next][first][last][top][bottom][index][help] */
 505 {
 506         if (rd_doload == 0)
 507                 return;
 508         
 509         if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR) return;
 510 
 511         if (rd_prompt) {
 512                 printk(KERN_NOTICE
 513                        "VFS: Insert root floppy disk to be loaded into ramdisk and press ENTER\n");
 514                 wait_for_keypress();
 515         }
 516 
 517         rd_load_image(ROOT_DEV,rd_image_start);
 518 
 519 }
 520 
 521 
 522 #ifdef CONFIG_BLK_DEV_INITRD
 523 void initrd_load(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 524 {
 525         rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),0);
 526 }
 527 #endif
 528 
 529 #endif /* RD_LOADER */
 530 
 531 #ifdef BUILD_CRAMDISK
 532 
 533 /*
 534  * gzip declarations
 535  */
 536 
 537 #define OF(args)  args
 538 
 539 #define memzero(s, n)     memset ((s), 0, (n))
 540 
 541 
 542 typedef unsigned char  uch;
 543 typedef unsigned short ush;
 544 typedef unsigned long  ulg;
 545 
 546 #define INBUFSIZ 4096
 547 #define WSIZE 0x8000    /* window size--must be a power of two, and */
 548                         /*  at least 32K for zip's deflate method */
 549 
 550 static uch *inbuf;
 551 static uch *window;
 552 
 553 static unsigned insize = 0;  /* valid bytes in inbuf */
 554 static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
 555 static unsigned outcnt = 0;  /* bytes in output buffer */
 556 static exit_code = 0;
 557 static long bytes_out = 0;
 558 static struct file *crd_infp, *crd_outfp;
 559 
 560 #define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
 561                 
 562 /* Diagnostic functions (stubbed out) */
 563 #define Assert(cond,msg)
 564 #define Trace(x)
 565 #define Tracev(x)
 566 #define Tracevv(x)
 567 #define Tracec(c,x)
 568 #define Tracecv(c,x)
 569 
 570 #define STATIC static
 571 
 572 static int  fill_inbuf(void);
 573 static void flush_window(void);
 574 static void *malloc(int size);
 575 static void free(void *where);
 576 static void error(char *m);
 577 static void gzip_mark(void **);
 578 static void gzip_release(void **);
 579 
 580 #include "../../lib/inflate.c"
 581 
 582 static void *malloc(int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 583 {
 584         return kmalloc(size, GFP_KERNEL);
 585 }
 586 
 587 static void free(void *where)
     /* [previous][next][first][last][top][bottom][index][help] */
 588 {
 589         kfree(where);
 590 }
 591 
 592 static void gzip_mark(void **ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 593 {
 594 }
 595 
 596 static void gzip_release(void **ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 597 {
 598 }
 599 
 600 
 601 /* ===========================================================================
 602  * Fill the input buffer. This is called only when the buffer is empty
 603  * and at least one byte is really needed.
 604  */
 605 static int fill_inbuf()
     /* [previous][next][first][last][top][bottom][index][help] */
 606 {
 607         if (exit_code) return -1;
 608         
 609         insize = crd_infp->f_op->read(crd_infp->f_inode, crd_infp,
 610                                       inbuf, INBUFSIZ);
 611         if (insize == 0) return -1;
 612 
 613         inptr = 1;
 614 
 615         return inbuf[0];
 616 }
 617 
 618 /* ===========================================================================
 619  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
 620  * (Used for the decompressed data only.)
 621  */
 622 static void flush_window()
     /* [previous][next][first][last][top][bottom][index][help] */
 623 {
 624     ulg c = crc;         /* temporary variable */
 625     unsigned n;
 626     uch *in, ch;
 627     
 628     crd_outfp->f_op->write(crd_outfp->f_inode, crd_outfp, window,
 629                            outcnt);
 630     in = window;
 631     for (n = 0; n < outcnt; n++) {
 632             ch = *in++;
 633             c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
 634     }
 635     crc = c;
 636     bytes_out += (ulg)outcnt;
 637     outcnt = 0;
 638 }
 639 
 640 static void error(char *x)
     /* [previous][next][first][last][top][bottom][index][help] */
 641 {
 642         printk(KERN_ERR "%s", x);
 643         exit_code = 1;
 644 }
 645 
 646 static int
 647 crd_load(struct file * fp, struct file *outfp)
     /* [previous][next][first][last][top][bottom][index][help] */
 648 {
 649         int result;
 650         
 651         crd_infp = fp;
 652         crd_outfp = outfp;
 653         inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
 654         if (inbuf == 0) {
 655                 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
 656                 return -1;
 657         }
 658         window = kmalloc(WSIZE, GFP_KERNEL);
 659         if (window == 0) {
 660                 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
 661                 kfree(inbuf);
 662                 return -1;
 663         }
 664         makecrc();
 665         result = gunzip();
 666         kfree(inbuf);
 667         kfree(window);
 668         return result;
 669 }
 670 
 671 #endif  /* BUILD_CRAMDISK */
 672 

/* [previous][next][first][last][top][bottom][index][help] */