diff options
Diffstat (limited to 'init/initramfs.c')
-rw-r--r-- | init/initramfs.c | 123 |
1 files changed, 42 insertions, 81 deletions
diff --git a/init/initramfs.c b/init/initramfs.c index 4f5ba75aaa7c..40bd4fb95788 100644 --- a/init/initramfs.c +++ b/init/initramfs.c | |||
@@ -389,11 +389,14 @@ static int __init write_buffer(char *buf, unsigned len) | |||
389 | return len - count; | 389 | return len - count; |
390 | } | 390 | } |
391 | 391 | ||
392 | static void __init flush_buffer(char *buf, unsigned len) | 392 | |
393 | static int __init flush_buffer(void *bufv, unsigned len) | ||
393 | { | 394 | { |
395 | char *buf = (char *) bufv; | ||
394 | int written; | 396 | int written; |
397 | int origLen = len; | ||
395 | if (message) | 398 | if (message) |
396 | return; | 399 | return -1; |
397 | while ((written = write_buffer(buf, len)) < len && !message) { | 400 | while ((written = write_buffer(buf, len)) < len && !message) { |
398 | char c = buf[written]; | 401 | char c = buf[written]; |
399 | if (c == '0') { | 402 | if (c == '0') { |
@@ -407,73 +410,14 @@ static void __init flush_buffer(char *buf, unsigned len) | |||
407 | } else | 410 | } else |
408 | error("junk in compressed archive"); | 411 | error("junk in compressed archive"); |
409 | } | 412 | } |
413 | return origLen; | ||
410 | } | 414 | } |
411 | 415 | ||
412 | /* | 416 | static unsigned my_inptr; /* index of next byte to be processed in inbuf */ |
413 | * gzip declarations | ||
414 | */ | ||
415 | |||
416 | #define OF(args) args | ||
417 | |||
418 | #ifndef memzero | ||
419 | #define memzero(s, n) memset ((s), 0, (n)) | ||
420 | #endif | ||
421 | |||
422 | typedef unsigned char uch; | ||
423 | typedef unsigned short ush; | ||
424 | typedef unsigned long ulg; | ||
425 | |||
426 | #define WSIZE 0x8000 /* window size--must be a power of two, and */ | ||
427 | /* at least 32K for zip's deflate method */ | ||
428 | |||
429 | static uch *inbuf; | ||
430 | static uch *window; | ||
431 | |||
432 | static unsigned insize; /* valid bytes in inbuf */ | ||
433 | static unsigned inptr; /* index of next byte to be processed in inbuf */ | ||
434 | static unsigned outcnt; /* bytes in output buffer */ | ||
435 | static long bytes_out; | ||
436 | |||
437 | #define get_byte() (inptr < insize ? inbuf[inptr++] : -1) | ||
438 | |||
439 | /* Diagnostic functions (stubbed out) */ | ||
440 | #define Assert(cond,msg) | ||
441 | #define Trace(x) | ||
442 | #define Tracev(x) | ||
443 | #define Tracevv(x) | ||
444 | #define Tracec(c,x) | ||
445 | #define Tracecv(c,x) | ||
446 | |||
447 | #define STATIC static | ||
448 | #define INIT __init | ||
449 | |||
450 | static void __init flush_window(void); | ||
451 | static void __init error(char *m); | ||
452 | |||
453 | #define NO_INFLATE_MALLOC | ||
454 | 417 | ||
455 | #include "../lib/inflate.c" | 418 | #include <linux/decompress/bunzip2.h> |
456 | 419 | #include <linux/decompress/unlzma.h> | |
457 | /* =========================================================================== | 420 | #include <linux/decompress/inflate.h> |
458 | * Write the output window window[0..outcnt-1] and update crc and bytes_out. | ||
459 | * (Used for the decompressed data only.) | ||
460 | */ | ||
461 | static void __init flush_window(void) | ||
462 | { | ||
463 | ulg c = crc; /* temporary variable */ | ||
464 | unsigned n; | ||
465 | uch *in, ch; | ||
466 | |||
467 | flush_buffer(window, outcnt); | ||
468 | in = window; | ||
469 | for (n = 0; n < outcnt; n++) { | ||
470 | ch = *in++; | ||
471 | c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); | ||
472 | } | ||
473 | crc = c; | ||
474 | bytes_out += (ulg)outcnt; | ||
475 | outcnt = 0; | ||
476 | } | ||
477 | 421 | ||
478 | static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) | 422 | static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) |
479 | { | 423 | { |
@@ -482,9 +426,10 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) | |||
482 | header_buf = kmalloc(110, GFP_KERNEL); | 426 | header_buf = kmalloc(110, GFP_KERNEL); |
483 | symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); | 427 | symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); |
484 | name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); | 428 | name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); |
485 | window = kmalloc(WSIZE, GFP_KERNEL); | 429 | |
486 | if (!window || !header_buf || !symlink_buf || !name_buf) | 430 | if (!header_buf || !symlink_buf || !name_buf) |
487 | panic("can't allocate buffers"); | 431 | panic("can't allocate buffers"); |
432 | |||
488 | state = Start; | 433 | state = Start; |
489 | this_header = 0; | 434 | this_header = 0; |
490 | message = NULL; | 435 | message = NULL; |
@@ -504,22 +449,38 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) | |||
504 | continue; | 449 | continue; |
505 | } | 450 | } |
506 | this_header = 0; | 451 | this_header = 0; |
507 | insize = len; | 452 | if (!gunzip(buf, len, NULL, flush_buffer, NULL, |
508 | inbuf = buf; | 453 | &my_inptr, error) && |
509 | inptr = 0; | 454 | message == NULL) |
510 | outcnt = 0; /* bytes in output buffer */ | 455 | goto ok; |
511 | bytes_out = 0; | 456 | |
512 | crc = (ulg)0xffffffffL; /* shift register contents */ | 457 | #ifdef CONFIG_RD_BZIP2 |
513 | makecrc(); | 458 | message = NULL; /* Zero out message, or else cpio will |
514 | gunzip(); | 459 | think an error has already occured */ |
460 | if (!bunzip2(buf, len, NULL, flush_buffer, NULL, | ||
461 | &my_inptr, error) && | ||
462 | message == NULL) { | ||
463 | goto ok; | ||
464 | } | ||
465 | #endif | ||
466 | |||
467 | #ifdef CONFIG_RD_LZMA | ||
468 | message = NULL; /* Zero out message, or else cpio will | ||
469 | think an error has already occured */ | ||
470 | if (!unlzma(buf, len, NULL, flush_buffer, NULL, | ||
471 | &my_inptr, error) && | ||
472 | message == NULL) { | ||
473 | goto ok; | ||
474 | } | ||
475 | #endif | ||
476 | ok: | ||
515 | if (state != Reset) | 477 | if (state != Reset) |
516 | error("junk in gzipped archive"); | 478 | error("junk in compressed archive"); |
517 | this_header = saved_offset + inptr; | 479 | this_header = saved_offset + my_inptr; |
518 | buf += inptr; | 480 | buf += my_inptr; |
519 | len -= inptr; | 481 | len -= my_inptr; |
520 | } | 482 | } |
521 | dir_utime(); | 483 | dir_utime(); |
522 | kfree(window); | ||
523 | kfree(name_buf); | 484 | kfree(name_buf); |
524 | kfree(symlink_buf); | 485 | kfree(symlink_buf); |
525 | kfree(header_buf); | 486 | kfree(header_buf); |