wok annotate linux-libre/stuff/linux-libre-freeinitrd-3.18.129-gnu.u @ rev 23329

updated perl-file-desktopentry (0.04 -> 0.22)
author Hans-G?nter Theisgen
date Mon Mar 30 17:44:58 2020 +0100 (2020-03-30)
parents
children
rev   line source
pascal@20604 1 --- linux-libre-3.18.129-gnu/init/initramfs.c
pascal@20604 2 +++ linux-libre-3.18.129-gnu/init/initramfs.c
pascal@20604 3 @@ -409,6 +409,52 @@
pascal@20604 4 [Reset] = do_reset,
pascal@20604 5 };
pascal@20604 6
pascal@20604 7 +#include <linux/initrd.h>
pascal@20604 8 +#define INITRD_PAGE ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024)
pascal@20604 9 +#define INITRD_DOT (1024*1024)
pascal@20604 10 +
pascal@20604 11 +static void free_rootfs_mem(unsigned long start, unsigned long end)
pascal@20604 12 +{
pascal@20604 13 + free_init_pages(NULL, start, end);
pascal@20604 14 +}
pascal@20604 15 +
pascal@20604 16 +static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end,
pascal@20604 17 + void (*free_initrd_mem)(unsigned long, unsigned long));
pascal@20604 18 +
pascal@20604 19 +static struct {
pascal@20604 20 + int offset, last, inptr, freed;
pascal@20604 21 + char *max;
pascal@20604 22 +} fill;
pascal@20604 23 +
pascal@20604 24 +static void release_inbuf(unsigned n)
pascal@20604 25 +{
pascal@20604 26 + if (n >= INITRD_PAGE) {
pascal@20604 27 + unsigned rem = n % INITRD_PAGE;
pascal@20604 28 + unsigned end = initrd_start + n - rem;
pascal@20604 29 + _free_initrd(initrd_start, end, free_rootfs_mem);
pascal@20604 30 + fill.freed += n - rem;
pascal@20604 31 + if (fill.freed >= INITRD_DOT) {
pascal@20604 32 + fill.freed -= INITRD_DOT;
pascal@20604 33 + printk(".");
pascal@20604 34 + }
pascal@20604 35 + initrd_start = end;
pascal@20604 36 + fill.offset = rem;
pascal@20604 37 + }
pascal@20604 38 +}
pascal@20604 39 +
pascal@20604 40 +static int fill_buffer(void *buffer, unsigned size)
pascal@20604 41 +{
pascal@20604 42 + int max = fill.max - (char *) initrd_start - fill.offset;
pascal@20604 43 + if (max > size) max = size;
pascal@20604 44 + if (max > INITRD_PAGE) max = INITRD_PAGE;
pascal@20604 45 + memcpy(buffer, (void *)(initrd_start + fill.offset), max);
pascal@20604 46 + release_inbuf(fill.offset);
pascal@20604 47 + fill.offset += max;
pascal@20604 48 + fill.inptr += fill.last;
pascal@20604 49 + fill.last = max;
pascal@20604 50 + return max;
pascal@20604 51 +}
pascal@20604 52 +
pascal@20604 53 static long __init write_buffer(char *buf, unsigned long len)
pascal@20604 54 {
pascal@20604 55 byte_count = len;
pascal@20604 56 @@ -452,6 +498,7 @@
pascal@20604 57 decompress_fn decompress;
pascal@20604 58 const char *compress_name;
pascal@20604 59 static __initdata char msg_buf[64];
pascal@20604 60 + int early_free_initrd = (buf == (char *) initrd_start);
pascal@20604 61
pascal@20604 62 header_buf = kmalloc(110, GFP_KERNEL);
pascal@20604 63 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
pascal@20604 64 @@ -465,11 +512,16 @@
pascal@20604 65 message = NULL;
pascal@20604 66 while (!message && len) {
pascal@20604 67 loff_t saved_offset = this_header;
pascal@20604 68 + fill.offset = buf - (char *) initrd_start;
pascal@20604 69 + fill.max = buf + len;
pascal@20604 70 + fill.inptr = fill.last = fill.freed = 0;
pascal@20604 71 if (*buf == '0' && !(this_header & 3)) {
pascal@20604 72 state = Start;
pascal@20604 73 written = write_buffer(buf, len);
pascal@20604 74 buf += written;
pascal@20604 75 len -= written;
pascal@20604 76 + if (early_free_initrd)
pascal@20604 77 + release_inbuf(buf - (char *) initrd_start);
pascal@20604 78 continue;
pascal@20604 79 }
pascal@20604 80 if (!*buf) {
pascal@20604 81 @@ -482,7 +534,13 @@
pascal@20604 82 decompress = decompress_method(buf, len, &compress_name);
pascal@20604 83 pr_debug("Detected %s compressed data\n", compress_name);
pascal@20604 84 if (decompress) {
pascal@20604 85 - int res = decompress(buf, len, NULL, flush_buffer, NULL,
pascal@20604 86 + int res;
pascal@20604 87 + if (early_free_initrd) {
pascal@20604 88 + res = decompress(NULL, 0, fill_buffer,
pascal@20604 89 + flush_buffer, NULL, &my_inptr, error);
pascal@20604 90 + my_inptr += fill.inptr;
pascal@20604 91 + }
pascal@20604 92 + else res = decompress(buf, len, NULL, flush_buffer, NULL,
pascal@20604 93 &my_inptr, error);
pascal@20604 94 if (res)
pascal@20604 95 error("decompressor failed");
pascal@20604 96 @@ -524,7 +582,8 @@
pascal@20604 97 #include <linux/initrd.h>
pascal@20604 98 #include <linux/kexec.h>
pascal@20604 99
pascal@20604 100 -static void __init free_initrd(void)
pascal@20604 101 +static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end,
pascal@20604 102 + void (*free_initrd_mem)(unsigned long, unsigned long))
pascal@20604 103 {
pascal@20604 104 #ifdef CONFIG_KEXEC
pascal@20604 105 unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
pascal@20604 106 @@ -552,6 +611,12 @@
pascal@20604 107 #endif
pascal@20604 108 free_initrd_mem(initrd_start, initrd_end);
pascal@20604 109 skip:
pascal@20604 110 + ;
pascal@20604 111 +}
pascal@20604 112 +
pascal@20604 113 +static void __init free_initrd(void)
pascal@20604 114 +{
pascal@20604 115 + _free_initrd(initrd_start, initrd_end, free_initrd_mem);
pascal@20604 116 initrd_start = 0;
pascal@20604 117 initrd_end = 0;
pascal@20604 118 }