[PATCH 12/20] inflate: internalize (arch) most of the output window handling

From: Matt Mackall
Date: Mon Oct 31 2005 - 16:03:43 EST


inflate: internalize most of the output window handling

This moves the inflate window definition and handling into
lib/inflate.c and rather than calling a global flush_window function,
now calls a flush callback. The callback in most callers is also
greatly simplified.

Signed-off-by: Matt Mackall <mpm@xxxxxxxxxxx>

Index: 2.6.14/lib/inflate.c
===================================================================
--- 2.6.14.orig/lib/inflate.c 2005-10-28 21:10:35.000000000 -0700
+++ 2.6.14/lib/inflate.c 2005-10-28 21:13:20.000000000 -0700
@@ -144,7 +144,10 @@ static void free(void *where)
if (!malloc_count)
malloc_ptr = free_mem_ptr;
}
+
+static u8 window[0x8000]; /* use a statically allocated window */
#else
+static u8 *window; /* dynamically allocate */
#define malloc(a) kmalloc(a, GFP_KERNEL)
#define free(a) kfree(a)
#endif
@@ -170,8 +173,9 @@ struct huft {

struct iostate {
u8 *window, *ibuf;
- int ipos, isize, itotal, opos, osize, bits;
+ int ipos, isize, itotal, opos, osize, ototal, bits;
void (*fill)(u8 *ibuf, int len);
+ void (*flush)(const u8 *obuf, int len);
u32 buf, crc;
};

@@ -191,10 +195,6 @@ static int INIT inflate(struct iostate *
stream to find repeated byte strings. This is implemented here as a
circular buffer. The index is updated simply by incrementing and then
ANDing with 0x7fff (32K-1). */
-/* It is left to other modules to supply the 32 K area. It is assumed
- to be usable as if it were declared "u8 window[32768];" or as just
- "u8 *window;" and then malloc'ed in the latter case. The definition
- must be in unzip.h, included above. */

static void flush_output(struct iostate *io)
{
@@ -204,8 +204,8 @@ static void flush_output(struct iostate
io->crc = crc_32_tab[(io->window[i] ^ (int)io->crc) & 0xff]
^ (io->crc >> 8);

- outcnt = io->opos;
- flush_window();
+ io->flush(io->window, io->opos);
+ io->ototal += io->opos;
io->opos = 0;
}

@@ -991,8 +991,10 @@ static void INIT makecrc(void)
* @ibuf: input character pool
* @isize: size of pool
* @fill: function to fill the input pool
+ * @flush: function to flush the output pool
*/
-static int INIT gunzip(u8 *ibuf, int isize, void (*fill)(u8 *buf, int size))
+static int INIT gunzip(u8 *ibuf, int isize, void (*fill)(u8 *buf, int size),
+ void (*flush)(const u8 *buf, int size))
{
u8 flags;
unsigned char magic[2]; /* magic header */
@@ -1002,13 +1004,13 @@ static int INIT gunzip(u8 *ibuf, int isi
int res;
struct iostate io;

- io.window = window;
- io.osize = WSIZE;
- io.opos = io.bits = io.buf = io.ipos = io.itotal = 0;
+ io.osize = 0x8000; /* 32k for inflate */
+ io.opos = io.bits = io.buf = io.ipos = io.itotal = io.ototal = 0;
io.crc = 0xffffffffUL;
io.isize = isize;
io.ibuf = ibuf;
io.fill = fill;
+ io.flush = flush;

makecrc(); /* initialize the CRC table */

@@ -1066,7 +1068,16 @@ static int INIT gunzip(u8 *ibuf, int isi
;

/* Decompress */
- if ((res = inflate(&io))) {
+ io.window = window ? window : malloc(io.osize);
+ if (!io.window) {
+ error("couldn't allocate gunzip window\n");
+ return -1;
+ }
+ res = inflate(&io);
+ if (!window)
+ free(io.window);
+
+ if (res) {
switch (res) {
case 0:
break;
@@ -1106,7 +1117,7 @@ static int INIT gunzip(u8 *ibuf, int isi
error("crc error");
return -1;
}
- if (orig_len != bytes_out) {
+ if (orig_len != io.ototal) {
error("length error");
return -1;
}
Index: 2.6.14/arch/alpha/boot/misc.c
===================================================================
--- 2.6.14.orig/arch/alpha/boot/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/alpha/boot/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -32,21 +32,12 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch *window; /* Sliding window buffer */
-static unsigned outcnt; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

static char *input_data;
static int input_data_size;

static uch *output_data;
-static ulg output_ptr;
-static ulg bytes_out;

extern int end;
static ulg free_mem_ptr;
@@ -56,24 +47,11 @@ static ulg free_mem_ptr_end;

#include "../../../lib/inflate.c"

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-void flush_window(void)
+/* flush gunzip output window */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
-/* puts("."); */
+ while(len--)
+ *output_data++ = *buf++;
}

static void error(char *x)
@@ -91,6 +69,7 @@ decompress_kernel(void *output_start,
size_t ksize,
size_t kzsize)
{
+ int count;
output_data = (uch *)output_start;
input_data = (uch *)input_start;
input_data_size = kzsize; /* use compressed size */
@@ -100,11 +79,8 @@ decompress_kernel(void *output_start,
free_mem_ptr_end = (ulg)output_start + ksize + 0x200000;
/* FIXME FIXME FIXME */

- /* put in temp area to reduce initial footprint */
- window = malloc(WSIZE);
-
/* puts("Uncompressing Linux..."); */
- gunzip(input_data, input_data_size, NULL);
+ count = gunzip(input_data, input_data_size, NULL, flush_window);
/* puts(" done, booting the kernel.\n"); */
- return output_ptr;
+ return count;
}
Index: 2.6.14/arch/arm/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/arm/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/arm/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -50,21 +50,12 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
-static unsigned outcnt; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

extern char input_data[];
extern char input_data_end[];

static uch *output_data;
-static ulg output_ptr;
-static ulg bytes_out;

static void putstr(const char *);

@@ -80,23 +71,11 @@ static ulg free_mem_ptr_end;
#define NO_INFLATE_MALLOC
#endif

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-void flush_window(void)
+/* flush gunzip output window */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
+ while(len--)
+ *output_data++ = *buf++;
putstr(".");
}

@@ -123,7 +102,7 @@ decompress_kernel(ulg output_start, ulg
arch_decomp_setup();

putstr("Uncompressing Linux...");
- gunzip(input_data, input_data_end - input_data, NULL);
+ gunzip(input_data, input_data_end - input_data, NULL, flush_window);
putstr(" done, booting the kernel.\n");
return output_ptr;
}
@@ -136,7 +115,7 @@ int main()
output_data = output_buffer;

putstr("Uncompressing Linux...");
- gunzip(input_data, input_data_end - input_data, NULL);
+ gunzip(input_data, input_data_end - input_data, NULL, flush_window);
putstr("done.\n");
return 0;
}
Index: 2.6.14/arch/arm26/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/arm26/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/arm26/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -35,21 +35,11 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
-static unsigned outcnt; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

extern char input_data[];
extern char input_data_end[];
-
static uch *output_data;
-static ulg output_ptr;
-static ulg bytes_out;

static void puts(const char *);

@@ -65,23 +55,11 @@ static ulg free_mem_ptr_end;
#define NO_INFLATE_MALLOC
#endif

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-void flush_window(void)
+/* flush the gunzip output window */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
+ while (len--)
+ *output_data++ = *buf++;
puts(".");
}

@@ -110,7 +88,7 @@ decompress_kernel(ulg output_start, ulg
arch_decomp_setup();

puts("Uncompressing Linux...");
- gunzip(input_data, input_data_end - input_data, NULL);
+ gunzip(input_data, input_data_end - input_data, NULL, flush_window);
puts(" done, booting the kernel.\n");
return output_ptr;
}
@@ -123,7 +101,7 @@ int main()
output_data = output_buffer;

puts("Uncompressing Linux...");
- gunzip(input_data, input_data_end - input_data, NULL);
+ gunzip(input_data, input_data_end - input_data, NULL, flush_window);
puts("done.\n");
return 0;
}
Index: 2.6.14/arch/cris/arch-v10/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/cris/arch-v10/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/cris/arch-v10/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -32,21 +32,12 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
unsigned compsize; /* compressed size, used by head.S */
-static unsigned outcnt = 0; /* bytes in output buffer */

-static void flush_window(void);
static void error(char *m);

extern char *input_data; /* lives in head.S */
-
-static long bytes_out = 0;
static uch *output_data;
-static unsigned long output_ptr = 0;

static void puts(const char *);

@@ -85,25 +76,11 @@ puts(const char *s)
#endif
}

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-
-static void
-flush_window()
+/* flush the gunzip output window */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
+ while (len--)
+ *output_data++ = *buf++;
}

static void
@@ -163,6 +140,6 @@ decompress_kernel()
}

puts("Uncompressing Linux...\n");
- compsize = gunzip(input_data, 0x7fffffff, NULL);
+ compsize = gunzip(input_data, 0x7fffffff, NULL, flush_window);
puts("Done. Now booting the kernel.\n");
}
Index: 2.6.14/arch/cris/arch-v32/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/cris/arch-v32/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/cris/arch-v32/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -34,20 +34,10 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

extern char *input_data; /* lives in head.S */
-
-static long bytes_out = 0;
static uch *output_data;
-static unsigned long output_ptr = 0;

static void puts(const char *);

@@ -98,25 +88,11 @@ puts(const char *s)
#endif
}

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-
-static void
-flush_window()
+/* flush the gunzip output window */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
+ while (len--)
+ *output_data++ = *buf++;
}

static void
@@ -207,6 +183,6 @@ decompress_kernel()
}

puts("Uncompressing Linux...\n");
- gunzip(input_data, 0x7fffffff, NULL);
+ gunzip(input_data, 0x7fffffff, NULL, flush_window);
puts("Done. Now booting the kernel.\n");
}
Index: 2.6.14/arch/i386/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/i386/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/i386/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -27,13 +27,6 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

/*
@@ -49,10 +42,8 @@ static unsigned char *real_mode; /* Poin

extern char input_data[];
extern int input_len;
-
-static long bytes_out = 0;
+static long bytes_out;
static uch *output_data;
-static unsigned long output_ptr = 0;

static void putstr(const char *);

@@ -126,43 +117,15 @@ static void putstr(const char *s)
outb_p(0xff & (pos >> 1), vidport+1);
}

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window_low(void)
-{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
-}
-
-static void flush_window_high(void)
+/* flush the gunzip output buffer */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, ch;
- in = window;
- for (n = 0; n < outcnt; n++) {
- ch = *output_data++ = *in++;
- if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start;
- }
-
- bytes_out += (ulg)outcnt;
- outcnt = 0;
-}
-
-static void flush_window(void)
-{
- if (high_loaded) flush_window_high();
- else flush_window_low();
+ bytes_out += len;
+ while (len--) {
+ *output_data++ = *buf++;
+ if (high_loaded && (u32)output_data == low_buffer_end)
+ output_data = high_buffer_start;
+ }
}

static void error(char *x)
@@ -254,7 +217,7 @@ asmlinkage int decompress_kernel(struct
else setup_output_buffer_if_we_run_high(mv);

putstr("Uncompressing Linux... ");
- gunzip(input_data, input_len, NULL);
+ gunzip(input_data, input_len, NULL, flush_window);
putstr("Ok, booting the kernel.\n");
if (high_loaded) close_output_buffer_if_we_run_high(mv);
return high_loaded;
Index: 2.6.14/arch/m32r/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/m32r/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/m32r/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -21,21 +21,11 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

static unsigned char *input_data;
static int input_len;
-
-static long bytes_out = 0;
static uch *output_data;
-static unsigned long output_ptr = 0;

#include "m32r_sio.c"

@@ -46,23 +36,11 @@ static unsigned long free_mem_end_ptr;

#include "../../../../lib/inflate.c"

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
+/* flush the gunzip output buffer */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
+ while (len--)
+ *output_data++ = *buf++;
}

static void error(char *x)
@@ -87,6 +65,6 @@ decompress_kernel(int mmu_on, unsigned c
input_len = zimage_len;

puts("Uncompressing Linux... ");
- gunzip(input_data, input_len, NULL);
+ gunzip(input_data, input_len, NULL, flush_window);
puts("Ok, booting the kernel.\n");
}
Index: 2.6.14/arch/sh/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/sh/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/sh/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -23,21 +23,11 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

extern char input_data[];
extern int input_len;
-
-static long bytes_out = 0;
static uch *output_data;
-static unsigned long output_ptr = 0;

int puts(const char *);

@@ -74,23 +64,11 @@ int puts(const char *s)
}
#endif

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
+/* flush the gunzip output window */
+static void flush_window(const u8 *buf, int len)
+{
+ while (len--)
+ *output_data++ = *buf++;
}

static void error(char *x)
@@ -114,6 +92,6 @@ void decompress_kernel(void)
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;

puts("Uncompressing Linux... ");
- gunzip(input_data, input_len, NULL);
+ gunzip(input_data, input_len, NULL, flush_window);
puts("Ok, booting the kernel.\n");
}
Index: 2.6.14/arch/sh64/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/sh64/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/sh64/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -23,21 +23,11 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

extern char input_data[];
extern int input_len;
-
-static long bytes_out = 0;
static uch *output_data;
-static unsigned long output_ptr = 0;

static void puts(const char *);

@@ -54,23 +44,12 @@ void puts(const char *s)
{
}

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
+/* flush the gunzip window */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, *out, ch;
+ while(len--)
+ *output_data++ = *buf++;

- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg) outcnt;
- output_ptr += (ulg) outcnt;
- outcnt = 0;
puts(".");
}

@@ -95,7 +74,7 @@ void decompress_kernel(void)

puts("Uncompressing Linux... ");
cache_control(CACHE_ENABLE);
- gunzip(input_data, input_len, NULL);
+ gunzip(input_data, input_len, NULL, flush_window);
puts("\n");

#if 0
Index: 2.6.14/arch/x86_64/boot/compressed/misc.c
===================================================================
--- 2.6.14.orig/arch/x86_64/boot/compressed/misc.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/arch/x86_64/boot/compressed/misc.c 2005-10-28 21:13:20.000000000 -0700
@@ -20,13 +20,6 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch window[WSIZE]; /* Sliding window buffer */
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-static void flush_window(void);
static void error(char *m);

/*
@@ -43,9 +36,8 @@ static unsigned char *real_mode; /* Poin
extern unsigned char input_data[];
extern int input_len;

-static long bytes_out = 0;
+static long bytes_out;
static uch *output_data;
-static unsigned long output_ptr = 0;

static void putstr(const char *);

@@ -115,43 +107,15 @@ static void putstr(const char *s)
outb_p(0xff & (pos >> 1), vidport+1);
}

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window_low(void)
+/* flush the gunzip output window */
+static void flush_window(const u8 *buf, int len)
{
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++)
- ch = *out++ = *in++;
-
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
-}
-
-static void flush_window_high(void)
-{
- unsigned n;
- uch *in, ch;
- in = window;
- for (n = 0; n < outcnt; n++) {
- ch = *output_data++ = *in++;
- if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start;
- }
-
- bytes_out += (ulg)outcnt;
- outcnt = 0;
-}
-
-static void flush_window(void)
-{
- if (high_loaded) flush_window_high();
- else flush_window_low();
+ bytes_out += len;
+ while (len--) {
+ *output_data++ = *buf++;
+ if (high_loaded && output_data == (u8 *)low_buffer_end)
+ output_data = high_buffer_start;
+ }
}

static void error(char *x)
@@ -201,7 +165,7 @@ void setup_output_buffer_if_we_run_high(
mv->high_buffer_start = high_buffer_start;
}

-void close_output_buffer_if_we_run_high(struct moveparams *mv)
+void close_output_buffer_if_we_run_high(struct moveparams *mv, int bytes_out)
{
if (bytes_out > low_buffer_size) {
mv->lcount = low_buffer_size;
@@ -232,7 +196,7 @@ int decompress_kernel(struct moveparams
else setup_output_buffer_if_we_run_high(mv);

putstr(".\nDecompressing Linux...");
- gunzip(input_data, input_len, NULL);
+ gunzip(input_data, input_len, NULL, flush_window);
putstr("done.\nBooting the kernel.\n");
if (high_loaded) close_output_buffer_if_we_run_high(mv);
return high_loaded;
Index: 2.6.14/init/do_mounts_rd.c
===================================================================
--- 2.6.14.orig/init/do_mounts_rd.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/init/do_mounts_rd.c 2005-10-28 21:13:20.000000000 -0700
@@ -278,20 +278,13 @@ typedef unsigned short ush;
typedef unsigned long ulg;

#define INBUFSIZ 4096
-#define WSIZE 0x8000 /* window size--must be a power of two, and */
- /* at least 32K for zip's deflate method */
-
static uch *inbuf;
-static uch *window;
-static unsigned outcnt; /* bytes in output buffer */
static int exit_code;
static int unzip_error;
-static long bytes_out;
static int crd_infd, crd_outfd;

#define INIT __init

-static void __init flush_window(void);
static void __init error(char *m);

#define NO_INFLATE_MALLOC
@@ -308,27 +301,17 @@ static void __init fill_inbuf(u8 *buf, i
error("RAMDISK: ran out of compressed data");
}

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
+/* Write the output window from gunzip */
+static void __init flush_buffer(const u8 *buf, int len)
{
- unsigned n, written;
- uch *in, ch;
-
- written = sys_write(crd_outfd, window, outcnt);
- if (written != outcnt && unzip_error == 0) {
- printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
- written, outcnt, bytes_out);
- unzip_error = 1;
- }
- in = window;
- for (n = 0; n < outcnt; n++)
- ch = *in++;
+ unsigned written;

- bytes_out += (ulg)outcnt;
- outcnt = 0;
+ written = sys_write(crd_outfd, buf, len);
+ if (written != len && unzip_error == 0) {
+ printk(KERN_ERR "RAMDISK: incomplete write (%d != %d)\n",
+ written, len);
+ unzip_error = 1;
+ }
}

static void __init error(char *x)
@@ -342,9 +325,7 @@ static int __init crd_load(int in_fd, in
{
int result;

- outcnt = 0; /* bytes in output buffer */
exit_code = 0;
- bytes_out = 0;

crd_infd = in_fd;
crd_outfd = out_fd;
@@ -353,17 +334,10 @@ static int __init crd_load(int in_fd, in
printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
return -1;
}
- window = kmalloc(WSIZE, GFP_KERNEL);
- if (window == 0) {
- printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
- kfree(inbuf);
- return -1;
- }
- result = gunzip(inbuf, INBUFSIZ, fill_inbuf);
+ result = gunzip(inbuf, INBUFSIZ, fill_inbuf, flush_buffer);
if (unzip_error)
result = 1;
kfree(inbuf);
- kfree(window);
return result;
}

Index: 2.6.14/init/initramfs.c
===================================================================
--- 2.6.14.orig/init/initramfs.c 2005-10-28 21:09:20.000000000 -0700
+++ 2.6.14/init/initramfs.c 2005-10-28 21:13:20.000000000 -0700
@@ -309,12 +309,12 @@ static int __init write_buffer(char *buf
return len - count;
}

-static void __init flush_buffer(char *buf, unsigned len)
+static void __init flush_buffer(const u8 *buf, int len)
{
int written;
if (message)
return;
- while ((written = write_buffer(buf, len)) < len && !message) {
+ while ((written = write_buffer((char *)buf, len)) < len && !message) {
char c = buf[written];
if (c == '0') {
buf += written;
@@ -337,41 +337,14 @@ typedef unsigned char uch;
typedef unsigned short ush;
typedef unsigned long ulg;

-#define WSIZE 0x8000 /* window size--must be a power of two, and */
- /* at least 32K for zip's deflate method */
-
-static uch *window;
-
-static unsigned outcnt; /* bytes in output buffer */
-static long bytes_out;
-
#define INIT __init

-static void __init flush_window(void);
static void __init error(char *m);

#define NO_INFLATE_MALLOC

#include "../lib/inflate.c"

-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
-{
- unsigned n;
- uch *in, ch;
-
- flush_buffer(window, outcnt);
- in = window;
- for (n = 0; n < outcnt; n++)
- ch = *in++;
-
- bytes_out += (ulg)outcnt;
- outcnt = 0;
-}
-
static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
{
int written, cnt;
@@ -379,8 +352,7 @@ static char * __init unpack_to_rootfs(ch
header_buf = kmalloc(110, GFP_KERNEL);
symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
- window = kmalloc(WSIZE, GFP_KERNEL);
- if (!window || !header_buf || !symlink_buf || !name_buf)
+ if (!header_buf || !symlink_buf || !name_buf)
panic("can't allocate buffers");
state = Start;
this_header = 0;
@@ -401,16 +373,13 @@ static char * __init unpack_to_rootfs(ch
continue;
}
this_header = 0;
- outcnt = 0; /* bytes in output buffer */
- bytes_out = 0;
- cnt = gunzip(buf, len, NULL);
+ cnt = gunzip(buf, len, NULL, flush_buffer);
if (state != Reset)
error("junk in gzipped archive");
this_header = saved_offset + cnt;
buf += cnt;
len -= cnt;
}
- kfree(window);
kfree(name_buf);
kfree(symlink_buf);
kfree(header_buf);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/