Skip to content

Commit

Permalink
fastboot: remove duplicate unpack_to_rootfs()
Browse files Browse the repository at this point in the history
we check if initrd is initramfs first and then do the real unpack. The check
isn't required, we can directly do unpack.  If the initrd isn't an
initramfs, we can remove the garbage.  In my laptop, this saves 0.1s boot
time.

This patch penalizes non-initramfs initrd case, but nowadays, initramfs is
the most widely used method for initrds.

Signed-off-by: Shaohua Li <[email protected]>
Acked-by: Arjan van de Ven <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
Li, Shaohua authored and fenrus75 committed Mar 28, 2009
1 parent 0c40626 commit df52092
Showing 1 changed file with 56 additions and 15 deletions.
71 changes: 56 additions & 15 deletions init/initramfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/dirent.h>
#include <linux/syscalls.h>
#include <linux/utime.h>

Expand Down Expand Up @@ -166,8 +167,6 @@ static __initdata char *victim;
static __initdata unsigned count;
static __initdata loff_t this_header, next_header;

static __initdata int dry_run;

static inline void __init eat(unsigned n)
{
victim += n;
Expand Down Expand Up @@ -229,10 +228,6 @@ static int __init do_header(void)
parse_header(collected);
next_header = this_header + N_ALIGN(name_len) + body_len;
next_header = (next_header + 3) & ~3;
if (dry_run) {
read_into(name_buf, N_ALIGN(name_len), GotName);
return 0;
}
state = SkipIt;
if (name_len <= 0 || name_len > PATH_MAX)
return 0;
Expand Down Expand Up @@ -303,8 +298,6 @@ static int __init do_name(void)
free_hash();
return 0;
}
if (dry_run)
return 0;
clean_path(collected, mode);
if (S_ISREG(mode)) {
int ml = maybe_link();
Expand Down Expand Up @@ -476,10 +469,9 @@ static void __init flush_window(void)
outcnt = 0;
}

static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
static char * __init unpack_to_rootfs(char *buf, unsigned len)
{
int written;
dry_run = check_only;
header_buf = kmalloc(110, GFP_KERNEL);
symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
Expand Down Expand Up @@ -574,24 +566,73 @@ static void __init free_initrd(void)
initrd_end = 0;
}

#define BUF_SIZE 1024
static void __init clean_rootfs(void)
{
int fd;
void *buf;
struct linux_dirent64 *dirp;
int count;

fd = sys_open("/", O_RDONLY, 0);
WARN_ON(fd < 0);
if (fd < 0)
return;
buf = kzalloc(BUF_SIZE, GFP_KERNEL);
WARN_ON(!buf);
if (!buf) {
sys_close(fd);
return;
}

dirp = buf;
count = sys_getdents64(fd, dirp, BUF_SIZE);
while (count > 0) {
while (count > 0) {
struct stat st;
int ret;

ret = sys_newlstat(dirp->d_name, &st);
WARN_ON_ONCE(ret);
if (!ret) {
if (S_ISDIR(st.st_mode))
sys_rmdir(dirp->d_name);
else
sys_unlink(dirp->d_name);
}

count -= dirp->d_reclen;
dirp = (void *)dirp + dirp->d_reclen;
}
dirp = buf;
memset(buf, 0, BUF_SIZE);
count = sys_getdents64(fd, dirp, BUF_SIZE);
}

sys_close(fd);
kfree(buf);
}

static int __init populate_rootfs(void)
{
char *err = unpack_to_rootfs(__initramfs_start,
__initramfs_end - __initramfs_start, 0);
__initramfs_end - __initramfs_start);
if (err)
panic(err);
if (initrd_start) {
#ifdef CONFIG_BLK_DEV_RAM
int fd;
printk(KERN_INFO "checking if image is initramfs...");
err = unpack_to_rootfs((char *)initrd_start,
initrd_end - initrd_start, 1);
initrd_end - initrd_start);
if (!err) {
printk(" it is\n");
unpack_to_rootfs((char *)initrd_start,
initrd_end - initrd_start, 0);
free_initrd();
return 0;
} else {
clean_rootfs();
unpack_to_rootfs(__initramfs_start,
__initramfs_end - __initramfs_start);
}
printk("it isn't (%s); looks like an initrd\n", err);
fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
Expand All @@ -604,7 +645,7 @@ static int __init populate_rootfs(void)
#else
printk(KERN_INFO "Unpacking initramfs...");
err = unpack_to_rootfs((char *)initrd_start,
initrd_end - initrd_start, 0);
initrd_end - initrd_start);
if (err)
panic(err);
printk(" done\n");
Expand Down

0 comments on commit df52092

Please sign in to comment.