wok rev 5159

linux: fix stacked initrd desallocation
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Mar 24 20:46:57 2010 +0100 (2010-03-24)
parents 8399ea7a8262
children 8ef66badbbaa
files linux/stuff/linux-freeinitrd-2.6.30.6.u
line diff
     1.1 --- a/linux/stuff/linux-freeinitrd-2.6.30.6.u	Wed Mar 24 21:44:12 2010 +0100
     1.2 +++ b/linux/stuff/linux-freeinitrd-2.6.30.6.u	Wed Mar 24 20:46:57 2010 +0100
     1.3 @@ -12,12 +12,13 @@
     1.4  
     1.5  --- linux-2.6.30.4/init/initramfs.c
     1.6  +++ linux-2.6.30.4/init/initramfs.c
     1.7 -@@ -374,6 +374,47 @@
     1.8 +@@ -374,6 +374,52 @@
     1.9   	[Reset]		= do_reset,
    1.10   };
    1.11   
    1.12  +#include <linux/initrd.h>
    1.13 -+#define INITRD_PAGE ((PAGE_SIZE > 1024*1024) ? PAGE_SIZE : 1024*1024)
    1.14 ++#define INITRD_PAGE ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024)
    1.15 ++#define INITRD_DOT  (1024*1024)
    1.16  +
    1.17  +static void free_rootfs_mem(unsigned long start, unsigned long end)
    1.18  +{
    1.19 @@ -28,7 +29,7 @@
    1.20  +			 void (*free_initrd_mem)(unsigned long, unsigned long));
    1.21  +
    1.22  +static struct {
    1.23 -+	int offset, last, inptr;
    1.24 ++	int offset, last, inptr, freed;
    1.25  +	char *max;
    1.26  +} fill;
    1.27  +
    1.28 @@ -38,7 +39,11 @@
    1.29  +		unsigned rem = fill.offset % INITRD_PAGE;
    1.30  +		unsigned end = initrd_start + fill.offset - rem;
    1.31  +		_free_initrd(initrd_start, end, free_rootfs_mem);
    1.32 -+		printk(".");
    1.33 ++		fill.freed += fill.offset - rem;
    1.34 ++		if (fill.freed >= INITRD_DOT) {
    1.35 ++			fill.freed -= INITRD_DOT;
    1.36 ++			printk(".");
    1.37 ++		}
    1.38  +		initrd_start = end;
    1.39  +		fill.offset = rem;
    1.40  +	}
    1.41 @@ -50,8 +55,8 @@
    1.42  +	if (max > size) max = size;
    1.43  +	if (max > INITRD_PAGE) max = INITRD_PAGE;
    1.44  +	memcpy(buffer, (void *)(initrd_start + fill.offset), max);
    1.45 ++	release_inbuf();
    1.46  +	fill.offset += max;
    1.47 -+	release_inbuf();
    1.48  +	fill.inptr += fill.last;
    1.49  +	fill.last = max;
    1.50  +	return max;
    1.51 @@ -60,7 +65,7 @@
    1.52   static int __init write_buffer(char *buf, unsigned len)
    1.53   {
    1.54   	count = len;
    1.55 -@@ -417,6 +458,7 @@
    1.56 +@@ -418,6 +464,7 @@
    1.57   	decompress_fn decompress;
    1.58   	const char *compress_name;
    1.59   	static __initdata char msg_buf[64];
    1.60 @@ -68,13 +73,13 @@
    1.61   
    1.62   	header_buf = kmalloc(110, GFP_KERNEL);
    1.63   	symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
    1.64 -@@ -430,8 +472,31 @@
    1.65 +@@ -431,8 +478,31 @@
    1.66   	message = NULL;
    1.67   	while (!message && len) {
    1.68   		loff_t saved_offset = this_header;
    1.69  +		fill.offset = buf - (char *) initrd_start;
    1.70  +		fill.max = buf + len;
    1.71 -+		fill.inptr = fill.last = 0;
    1.72 ++		fill.inptr = fill.last = fill.freed = 0;
    1.73   		if (*buf == '0' && !(this_header & 3)) {
    1.74   			state = Start;
    1.75  +			if (early_free_initrd) {
    1.76 @@ -100,7 +105,7 @@
    1.77   			written = write_buffer(buf, len);
    1.78   			buf += written;
    1.79   			len -= written;
    1.80 -@@ -445,9 +510,15 @@
    1.81 +@@ -446,9 +516,15 @@
    1.82   		}
    1.83   		this_header = 0;
    1.84   		decompress = decompress_method(buf, len, &compress_name);
    1.85 @@ -118,7 +123,7 @@
    1.86   		else if (compress_name) {
    1.87   			if (!message) {
    1.88   				snprintf(msg_buf, sizeof msg_buf,
    1.89 -@@ -484,7 +555,8 @@
    1.90 +@@ -485,7 +561,8 @@
    1.91   #include <linux/initrd.h>
    1.92   #include <linux/kexec.h>
    1.93   
    1.94 @@ -128,7 +133,7 @@
    1.95   {
    1.96   #ifdef CONFIG_KEXEC
    1.97   	unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
    1.98 -@@ -512,6 +584,12 @@
    1.99 +@@ -513,6 +590,12 @@
   1.100   #endif
   1.101   		free_initrd_mem(initrd_start, initrd_end);
   1.102   skip: