diff -ur linux-2.6.14.orig/fs/Kconfig linux-2.6.14/fs/Kconfig --- linux-2.6.14.orig/fs/Kconfig 2005-09-11 03:19:07.000000000 +0000 +++ linux-2.6.14/fs/Kconfig 2005-09-11 03:19:42.000000000 +0000 @@ -805,6 +805,18 @@ See for details. +config EARLYUSERSPACE_ON_TMPFS + bool "Unpack the early userspace onto tmpfs" + depends TMPFS + default y + help + Use this to have your early userspace placed (decompressed) + onto tmpfs as opposed ramfs. This will allow you to + restrict the size of your root-filesystem and it will also + be swappable. + + If unsure, say Y. + config HUGETLBFS bool "HugeTLB file system support" depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || X86_64 || BROKEN Only in linux-2.6.14/fs: Kconfig.orig diff -ur linux-2.6.14.orig/init/initramfs.c linux-2.6.14/init/initramfs.c --- linux-2.6.14.orig/init/initramfs.c 2005-08-28 23:41:01.000000000 +0000 +++ linux-2.6.14/init/initramfs.c 2005-09-11 03:19:42.000000000 +0000 @@ -6,6 +6,7 @@ #include #include #include +#include static __initdata char *message; static void __init error(char *x) @@ -463,6 +464,49 @@ return message; } +/* If we want the rootfs on initramfs so we mount initramfs over the + * rootfs before we unpack it. The little dance we do by creating a + * pivot point and moving the root to that is in fact necessary + * because lookups of "." don't resolve mountpoints. + */ +static inline void __init overmount_rootfs(void) + { +#ifdef CONFIG_EARLYUSERSPACE_ON_TMPFS + int init_tmpfs(void); + int (*initfunc)(void) = init_tmpfs; + mm_segment_t oldfs; + char pivot[] = "/pivot"; + + /* Explicitly go and init the overmount fs early (long-term + * the need for this will probably go away. */ + + if (initfunc()) + goto err; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + if (sys_mkdir(pivot, 0700) < 0) + goto err; + if (sys_mount("tmpfs", pivot, "tmpfs", 0, "size=90%")) + goto err; + + /* Below here errors are unlikely and icky to deal with. */ + sys_chdir(pivot); + sys_mount(".", "/", NULL, MS_MOVE, NULL); + sys_chdir("."); + sys_chroot("."); + printk(KERN_INFO "Overmounted tmpfs\n"); + goto out; + + err: + printk(KERN_ERR "Overmount error\n"); + + out: + set_fs(oldfs); +#endif /* CONFIG_EARLYUSERSPACE_ON_TMPFS */ +} + extern char __initramfs_start[], __initramfs_end[]; #ifdef CONFIG_BLK_DEV_INITRD #include @@ -482,6 +526,9 @@ initrd_end - initrd_start, 1); if (!err) { printk(" it is\n"); +#ifdef CONFIG_EARLYUSERSPACE_ON_TMPFS + overmount_rootfs(); +#endif /* CONFIG_EARLYUSERSPACE_ON_TMPFS */ unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start, 0); free_initrd_mem(initrd_start, initrd_end); diff -ur linux-2.6.14.orig/init/main.c linux-2.6.14/init/main.c --- linux-2.6.14.orig/init/main.c 2005-09-11 03:19:07.000000000 +0000 +++ linux-2.6.14/init/main.c 2005-09-11 03:22:43.000000000 +0000 @@ -701,6 +701,11 @@ if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) { ramdisk_execute_command = NULL; prepare_namespace(); +#ifdef CONFIG_EARLYUSERSPACE_ON_TMPFS + int init_tmpfs(void); + int (*initfunc)(void) = init_tmpfs; + initfunc(); +#endif /* CONFIG_EARLYUSERSPACE_ON_TMPFS */ } /* diff -ur linux-2.6.14.orig/mm/shmem.c linux-2.6.14/mm/shmem.c --- linux-2.6.14.orig/mm/shmem.c 2005-09-11 03:19:07.000000000 +0000 +++ linux-2.6.14/mm/shmem.c 2005-09-11 03:19:42.000000000 +0000 @@ -2136,7 +2136,7 @@ }; static struct vfsmount *shm_mnt; -static int __init init_tmpfs(void) +int __init init_tmpfs(void) { int error; @@ -2169,7 +2169,12 @@ shm_mnt = ERR_PTR(error); return error; } +/* Don't do this if we are calling it early explicity */ +#ifndef CONFIG_EARLYUSERSPACE_ON_TMPFS +/* If CONFIG_EARLYUSERSPACE_ON_TMPFS is set then we will interpose + * ramfs so this will get called explicitly and early */ module_init(init_tmpfs) +#endif /* !CONFIG_EARLYUSERSPACE_ON_TMPFS */ /* * shmem_file_setup - get an unlinked file living in tmpfs