@@ -250,11 +250,11 @@ static void __init read_into(char *buf, unsigned size, enum state next)
}
}
-static __initdata char *header_buf, *name_buf;
+static __initdata char *cpio_buf;
static int __init do_start(void)
{
- read_into(header_buf, CPIO_HDRLEN, GotHeader);
+ read_into(cpio_buf, CPIO_HDRLEN, GotHeader);
return 0;
}
@@ -294,14 +294,14 @@ static int __init do_header(void)
if (S_ISLNK(mode)) {
if (body_len > PATH_MAX)
return 0;
- collect = collected = name_buf;
+ collect = collected = cpio_buf;
remains = N_ALIGN(name_len) + body_len;
next_state = GotSymlink;
state = Collect;
return 0;
}
if (S_ISREG(mode) || !body_len)
- read_into(name_buf, N_ALIGN(name_len), GotName);
+ read_into(cpio_buf, N_ALIGN(name_len), GotName);
return 0;
}
@@ -511,11 +511,16 @@ char * __init unpack_to_rootfs(char *buf, unsigned long len)
const char *compress_name;
static __initdata char msg_buf[64];
- header_buf = kmalloc(CPIO_HDRLEN, GFP_KERNEL);
- /* 2x PATH_MAX as @name_buf is also used for staging symlink targets */
- name_buf = kmalloc(N_ALIGN(PATH_MAX) + PATH_MAX + 1, GFP_KERNEL);
- if (!header_buf || !name_buf)
- panic_show_mem("can't allocate buffers");
+ /*
+ * @cpio_buf can be used for staging the 110 byte newc/crc cpio header,
+ * after which parse_header() converts and stashes fields into
+ * corresponding types. The same buffer can then be reused for file
+ * path staging. 2 x PATH_MAX covers any possible symlink target.
+ */
+ BUILD_BUG_ON(CPIO_HDRLEN > N_ALIGN(PATH_MAX) + PATH_MAX + 1);
+ cpio_buf = kmalloc(N_ALIGN(PATH_MAX) + PATH_MAX + 1, GFP_KERNEL);
+ if (!cpio_buf)
+ panic_show_mem("can't allocate buffer");
state = Start;
this_header = 0;
@@ -559,8 +564,7 @@ char * __init unpack_to_rootfs(char *buf, unsigned long len)
len -= my_inptr;
}
dir_utime();
- kfree(name_buf);
- kfree(header_buf);
+ kfree(cpio_buf);
return message;
}
header_buf is only used in FSM states up to GotHeader, while name_buf is only used in states following GotHeader (Collect is shared, but the collect pointer tracks each buffer). These buffers can therefore be combined into a single cpio_buf, which can be used for both header and file name storage. Signed-off-by: David Disseldorp <ddiss@suse.de> --- init/initramfs.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)