8 #warning "Sparse checking disabled for this file"
13 #include <linux/slab.h>
14 #include <linux/types.h>
15 #include <linux/fcntl.h>
17 #include <linux/string.h>
31 #define N_ALIGN(len) ((((len) + 1) & ~3) + 2)
40 static inline int hash(
int major,
int minor,
int ino)
42 unsigned long tmp = ino + minor + (major << 3);
47 static char __init *find_link(
int major,
int minor,
int ino,
51 for (p =
head +
hash(major, minor, ino); *
p; p = &(*p)->next) {
54 if ((*p)->minor != minor)
56 if ((*p)->major != major)
58 if (((*p)->mode ^ mode) &
S_IFMT)
64 panic(
"can't allocate link hash entry");
75 static void __init free_hash(
void)
110 panic(
"can't allocate dir_entry buffer");
111 INIT_LIST_HEAD(&de->
list);
114 list_add(&de->
list, &dir_list);
117 static void __init dir_utime(
void)
141 unsigned long parsed[12];
146 for (i = 0, s += 6; i < 12; i++, s += 8) {
156 body_len = parsed[6];
159 rdev = new_encode_dev(
MKDEV(parsed[9], parsed[10]));
160 name_len = parsed[11];
178 static __initdata loff_t this_header, next_header;
180 static inline void __init eat(
unsigned n)
199 collect = collected =
buf;
206 static __initdata char *header_buf, *symlink_buf, *name_buf;
208 static int __init do_start(
void)
214 static int __init do_collect(
void)
216 unsigned n = remains;
219 memcpy(collect, victim, n);
222 if ((remains -= n) != 0)
228 static int __init do_header(
void)
230 if (
memcmp(collected,
"070707", 6)==0) {
231 error(
"incorrect cpio method used: use -H newc option");
234 if (
memcmp(collected,
"070701", 6)) {
235 error(
"no cpio magic");
239 next_header = this_header +
N_ALIGN(name_len) + body_len;
240 next_header = (next_header + 3) & ~3;
242 if (name_len <= 0 || name_len >
PATH_MAX)
245 if (body_len > PATH_MAX)
247 collect = collected = symlink_buf;
248 remains =
N_ALIGN(name_len) + body_len;
253 if (
S_ISREG(mode) || !body_len)
258 static int __init do_skip(
void)
260 if (this_header + count < next_header) {
264 eat(next_header - this_header);
272 while(count && *victim ==
'\0')
274 if (count && (this_header & 3))
275 error(
"broken padding");
279 static int __init maybe_link(
void)
282 char *old = find_link(major, minor, ino, mode, collected);
284 return (
sys_link(old, collected) < 0) ? -1 : 1;
303 static int __init do_name(
void)
307 if (
strcmp(collected,
"TRAILER!!!") == 0) {
311 clean_path(collected, mode);
313 int ml = maybe_link();
318 wfd =
sys_open(collected, openflags, mode);
333 dir_add(collected, mtime);
336 if (maybe_link() == 0) {
340 do_utime(collected, mtime);
346 static int __init do_copy(
void)
348 if (count >= body_len) {
351 do_utime(vcollected, mtime);
364 static int __init do_symlink(
void)
366 collected[
N_ALIGN(name_len) + body_len] =
'\0';
367 clean_path(collected, 0);
370 do_utime(collected, mtime);
387 static int __init write_buffer(
char *buf,
unsigned len)
397 static int __init flush_buffer(
void *bufv,
unsigned len)
399 char *buf = (
char *) bufv;
404 while ((written = write_buffer(buf, len)) < len && !
message) {
405 char c = buf[written];
415 error(
"junk in compressed archive");
420 static unsigned my_inptr;
424 static char *
__init unpack_to_rootfs(
char *buf,
unsigned len)
428 const char *compress_name;
435 if (!header_buf || !symlink_buf || !name_buf)
436 panic(
"can't allocate buffers");
442 loff_t saved_offset = this_header;
443 if (*buf ==
'0' && !(this_header & 3)) {
445 written = write_buffer(buf, len);
462 error(
"decompressor failed");
463 }
else if (compress_name) {
466 "compression method %s not configured",
471 error(
"junk in compressed archive");
473 error(
"junk in compressed archive");
474 this_header = saved_offset + my_inptr;
487 static int __init retain_initrd_param(
char *
str)
491 do_retain_initrd = 1;
494 __setup(
"retain_initrd", retain_initrd_param);
499 #include <linux/kexec.h>
501 static void __init free_initrd(
void)
507 if (do_retain_initrd)
515 if (initrd_start < crashk_end && initrd_end > crashk_start) {
533 #ifdef CONFIG_BLK_DEV_RAM
534 #define BUF_SIZE 1024
535 static void __init clean_rootfs(
void)
570 dirp = (
void *)dirp + dirp->
d_reclen;
582 static int __init populate_rootfs(
void)
584 char *
err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
588 #ifdef CONFIG_BLK_DEV_RAM
598 unpack_to_rootfs(__initramfs_start, __initramfs_size);
601 "; looks like an initrd\n", err);