wok annotate linux/stuff/linux-freeinitrd.u @ rev 20334

Do not use efi shell (again)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sat Jun 02 16:13:06 2018 +0200 (2018-06-02)
parents 708b5293dd29
children
rev   line source
pascal@20261 1 --- linux-3.16.53/init/initramfs.c
pascal@20261 2 +++ linux-3.16.53/init/initramfs.c
pascal@20261 3 @@ -384,6 +384,52 @@
pankso@12285 4 [Reset] = do_reset,
pankso@12285 5 };
pankso@12285 6
pankso@12285 7 +#include <linux/initrd.h>
pankso@12285 8 +#define INITRD_PAGE ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024)
pankso@12285 9 +#define INITRD_DOT (1024*1024)
pankso@12285 10 +
pankso@12285 11 +static void free_rootfs_mem(unsigned long start, unsigned long end)
pankso@12285 12 +{
pascal@20279 13 + free_init_pages(NULL, start, end);
pankso@12285 14 +}
pankso@12285 15 +
pankso@12285 16 +static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end,
pankso@12285 17 + void (*free_initrd_mem)(unsigned long, unsigned long));
pankso@12285 18 +
pankso@12285 19 +static struct {
pascal@17037 20 + unsigned long offset, last, inptr, freed;
pankso@12285 21 + char *max;
pankso@12285 22 +} fill;
pankso@12285 23 +
pankso@12285 24 +static void release_inbuf(unsigned n)
pankso@12285 25 +{
pankso@12285 26 + if (n >= INITRD_PAGE) {
pascal@17037 27 + unsigned long rem = n % INITRD_PAGE;
pascal@17037 28 + unsigned long end = initrd_start + n - rem;
pankso@12285 29 + _free_initrd(initrd_start, end, free_rootfs_mem);
pankso@12285 30 + fill.freed += n - rem;
pankso@12285 31 + if (fill.freed >= INITRD_DOT) {
pankso@12285 32 + fill.freed -= INITRD_DOT;
pankso@12285 33 + printk(".");
pankso@12285 34 + }
pankso@12285 35 + initrd_start = end;
pankso@12285 36 + fill.offset = rem;
pankso@12285 37 + }
pankso@12285 38 +}
pankso@12285 39 +
pascal@17037 40 +static unsigned long fill_buffer(void *buffer, unsigned size)
pankso@12285 41 +{
pascal@17037 42 + unsigned long max = fill.max - (char *) initrd_start - fill.offset;
pankso@12285 43 + if (max > size) max = size;
pankso@12285 44 + if (max > INITRD_PAGE) max = INITRD_PAGE;
pankso@12285 45 + memcpy(buffer, (void *)(initrd_start + fill.offset), max);
pankso@12285 46 + release_inbuf(fill.offset);
pankso@12285 47 + fill.offset += max;
pankso@12285 48 + fill.inptr += fill.last;
pankso@12285 49 + fill.last = max;
pankso@12285 50 + return max;
pankso@12285 51 +}
pankso@12285 52 +
pankso@12285 53 static int __init write_buffer(char *buf, unsigned len)
pankso@12285 54 {
pankso@12285 55 count = len;
pascal@20261 56 @@ -427,6 +473,7 @@
pankso@12285 57 decompress_fn decompress;
pankso@12285 58 const char *compress_name;
pankso@12285 59 static __initdata char msg_buf[64];
pankso@12285 60 + int early_free_initrd = (buf == (char *) initrd_start);
pankso@12285 61
pankso@12285 62 header_buf = kmalloc(110, GFP_KERNEL);
pankso@12285 63 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
pascal@20261 64 @@ -440,11 +487,16 @@
pankso@12285 65 message = NULL;
pankso@12285 66 while (!message && len) {
pankso@12285 67 loff_t saved_offset = this_header;
pankso@12285 68 + fill.offset = buf - (char *) initrd_start;
pankso@12285 69 + fill.max = buf + len;
pankso@12285 70 + fill.inptr = fill.last = fill.freed = 0;
pankso@12285 71 if (*buf == '0' && !(this_header & 3)) {
pankso@12285 72 state = Start;
pankso@12285 73 written = write_buffer(buf, len);
pankso@12285 74 buf += written;
pankso@12285 75 len -= written;
pankso@12285 76 + if (early_free_initrd)
pankso@12285 77 + release_inbuf(buf - (char *) initrd_start);
pankso@12285 78 continue;
pankso@12285 79 }
pankso@12285 80 if (!*buf) {
pascal@20261 81 @@ -457,7 +509,12 @@
pankso@12285 82 decompress = decompress_method(buf, len, &compress_name);
pascal@20261 83 pr_debug("Detected %s compressed data\n", compress_name);
pankso@12285 84 if (decompress) {
pankso@12285 85 - res = decompress(buf, len, NULL, flush_buffer, NULL,
pankso@12285 86 + if (early_free_initrd) {
pankso@12285 87 + res = decompress(NULL, 0, fill_buffer,
pankso@12285 88 + flush_buffer, NULL, &my_inptr, error);
pankso@12285 89 + my_inptr += fill.inptr;
pankso@12285 90 + }
pankso@12285 91 + else res = decompress(buf, len, NULL, flush_buffer, NULL,
pankso@12285 92 &my_inptr, error);
pankso@12285 93 if (res)
pankso@12285 94 error("decompressor failed");
pascal@20261 95 @@ -499,7 +556,8 @@
pankso@12285 96 #include <linux/initrd.h>
pankso@12285 97 #include <linux/kexec.h>
pankso@12285 98
pankso@12285 99 -static void __init free_initrd(void)
pankso@12285 100 +static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end,
pankso@12285 101 + void (*free_initrd_mem)(unsigned long, unsigned long))
pankso@12285 102 {
pankso@12285 103 #ifdef CONFIG_KEXEC
pankso@12285 104 unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
pascal@20261 105 @@ -527,6 +585,12 @@
pankso@12285 106 #endif
pankso@12285 107 free_initrd_mem(initrd_start, initrd_end);
pankso@12285 108 skip:
pankso@12285 109 + ;
pankso@12285 110 +}
pankso@12285 111 +
pankso@12285 112 +static void __init free_initrd(void)
pankso@12285 113 +{
pankso@12285 114 + _free_initrd(initrd_start, initrd_end, free_initrd_mem);
pankso@12285 115 initrd_start = 0;
pankso@12285 116 initrd_end = 0;
pankso@12285 117 }