* [PATCH 1/5] initmpfs: replace MS_NOUSER in initramfs
2013-06-29 20:12 [PATCH 0/5] initmpfs: use tmpfs instead of ramfs for rootfs Rob Landley
@ 2013-06-29 20:12 ` Rob Landley
2013-06-30 1:15 ` Eric W. Biederman
2013-06-29 20:12 ` [PATCH 2/5] initmpfs: Move bdi setup from init_rootfs to init_ramfs Rob Landley
` (3 subsequent siblings)
4 siblings, 1 reply; 9+ messages in thread
From: Rob Landley @ 2013-06-29 20:12 UTC (permalink / raw)
To: linux-kernel; +Cc: Al Viro, Eric W. Biederman
From: Rob Landley <rob@landley.net>
Mounting MS_NOUSER prevents --bind mounts from rootfs. Prevent new rootfs
mounts with a different mechanism that doesn't affect bind mounts.
Signed-off-by: Rob Landley <rob@landley.net>
---
fs/ramfs/inode.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index c24f1e1..14b9c35 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -247,7 +247,14 @@ struct dentry *ramfs_mount(struct file_system_type *fs_type,
static struct dentry *rootfs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
- return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
+ static int once;
+
+ if (once)
+ return ERR_PTR(-ENODEV);
+ else
+ once++;
+
+ return mount_nodev(fs_type, flags, data, ramfs_fill_super);
}
static void ramfs_kill_sb(struct super_block *sb)
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 1/5] initmpfs: replace MS_NOUSER in initramfs
2013-06-29 20:12 ` [PATCH 1/5] initmpfs: replace MS_NOUSER in initramfs Rob Landley
@ 2013-06-30 1:15 ` Eric W. Biederman
2013-06-30 2:45 ` Rob Landley
2013-06-30 3:09 ` Rob Landley
0 siblings, 2 replies; 9+ messages in thread
From: Eric W. Biederman @ 2013-06-30 1:15 UTC (permalink / raw)
To: Rob Landley; +Cc: linux-kernel, Al Viro
Rob Landley <rob@landley.net> writes:
> From: Rob Landley <rob@landley.net>
>
> Mounting MS_NOUSER prevents --bind mounts from rootfs. Prevent new rootfs
> mounts with a different mechanism that doesn't affect bind mounts.
I don't see patches 4 and 5 so I don't know if you have covered this
elsewhere but a very important part of the reason for MS_NOUSER is to
prevent unmounting of rootfs.
The entire vfs breaks if you are allowed to unmount rootfs, and it
appears this patch is allowing that.
Eric
> Signed-off-by: Rob Landley <rob@landley.net>
> ---
>
> fs/ramfs/inode.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
> index c24f1e1..14b9c35 100644
> --- a/fs/ramfs/inode.c
> +++ b/fs/ramfs/inode.c
> @@ -247,7 +247,14 @@ struct dentry *ramfs_mount(struct file_system_type *fs_type,
> static struct dentry *rootfs_mount(struct file_system_type *fs_type,
> int flags, const char *dev_name, void *data)
> {
> - return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
> + static int once;
> +
> + if (once)
> + return ERR_PTR(-ENODEV);
> + else
> + once++;
> +
> + return mount_nodev(fs_type, flags, data, ramfs_fill_super);
> }
>
> static void ramfs_kill_sb(struct super_block *sb)
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 1/5] initmpfs: replace MS_NOUSER in initramfs
2013-06-30 1:15 ` Eric W. Biederman
@ 2013-06-30 2:45 ` Rob Landley
2013-06-30 3:09 ` Rob Landley
1 sibling, 0 replies; 9+ messages in thread
From: Rob Landley @ 2013-06-30 2:45 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: linux-kernel, Al Viro
On 06/29/2013 08:15:40 PM, Eric W. Biederman wrote:
> Rob Landley <rob@landley.net> writes:
>
> > From: Rob Landley <rob@landley.net>
> >
> > Mounting MS_NOUSER prevents --bind mounts from rootfs. Prevent new
> rootfs
> > mounts with a different mechanism that doesn't affect bind mounts.
>
> I don't see patches 4 and 5 so I don't know if you have covered this
> elsewhere but a very important part of the reason for MS_NOUSER is to
> prevent unmounting of rootfs.
Actually rootfs has separate protections against umounting. I tried
several varieties of "umount -f /" and "cd /; umount -l .; umount -f
.." and so on; they're all ignored.
> The entire vfs breaks if you are allowed to unmount rootfs, and it
> appears this patch is allowing that.
Yes, I hit that many moons ago. (Doing either mount --move or
pivot_root on initramfs, and then umounting it once it was in a
subdirectory: system locked hard; I can try to dig up a link if you
like, it was something like 2005? Maybe 2.6.11? It got fixed. This was
before I implemented switch_root in busybox, because the experience is
what taught me the difference between pivot_root and switch_root.)
I tested "mount --bind / home" on initmpfs and got "invalid argument".
(Haven't tried pivot_root again because that binary's not on my test
system, but when you're _not_ on rootfs that'll kill the system if you
do it in the global namespace without knowing what you're doing. I can
specifically test that if you like...)
Rob
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/5] initmpfs: replace MS_NOUSER in initramfs
2013-06-30 1:15 ` Eric W. Biederman
2013-06-30 2:45 ` Rob Landley
@ 2013-06-30 3:09 ` Rob Landley
1 sibling, 0 replies; 9+ messages in thread
From: Rob Landley @ 2013-06-30 3:09 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: linux-kernel, Al Viro
On 06/29/2013 08:15:40 PM, Eric W. Biederman wrote:
> Rob Landley <rob@landley.net> writes:
>
> > From: Rob Landley <rob@landley.net>
> >
> > Mounting MS_NOUSER prevents --bind mounts from rootfs. Prevent new
> rootfs
> > mounts with a different mechanism that doesn't affect bind mounts.
>
> I don't see patches 4 and 5 so I don't know if you have covered this
> elsewhere but a very important part of the reason for MS_NOUSER is to
> prevent unmounting of rootfs.
>
> The entire vfs breaks if you are allowed to unmount rootfs, and it
> appears this patch is allowing that.
I mean I tried "mount --move / home". (--bind worked.)
Long day...
Rob
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/5] initmpfs: Move bdi setup from init_rootfs to init_ramfs
2013-06-29 20:12 [PATCH 0/5] initmpfs: use tmpfs instead of ramfs for rootfs Rob Landley
2013-06-29 20:12 ` [PATCH 1/5] initmpfs: replace MS_NOUSER in initramfs Rob Landley
@ 2013-06-29 20:12 ` Rob Landley
2013-06-29 20:12 ` [PATCH 3/5] initmpfs: Move rootfs code from fs/ramfs/ to init/ Rob Landley
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Rob Landley @ 2013-06-29 20:12 UTC (permalink / raw)
To: linux-kernel; +Cc: Al Viro, Eric W. Biederman
From: Rob Landley <rob@landley.net>
Even though ramfs hasn't got a backing device, commit e0bf68ddec4f added one
anyway, and put the initialization in init_rootfs() since that's the first
user, leaving it out of init_ramfs() to avoid duplication.
But initmpfs uses init_tmpfs() instead, so move the init into the filesystem's
init function, add a "once" guard to prevent duplicate initialization, and
call the filesystem init from rootfs init.
This goes part of the way to allowing ramfs to be built as a module.
Signed-off-by: Rob Landley <rob@landley.net>
---
fs/ramfs/inode.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
--- initold/fs/ramfs/inode.c 2013-06-28 15:12:03.205879730 -0500
+++ initold2/fs/ramfs/inode.c 2013-06-28 15:12:12.425880115 -0500
@@ -277,21 +277,36 @@
static int __init init_ramfs_fs(void)
{
- return register_filesystem(&ramfs_fs_type);
+ static int once;
+ int err;
+
+ if (once)
+ return 0;
+ else
+ once++;
+
+ err = bdi_init(&ramfs_backing_dev_info);
+ if (err)
+ return err;
+
+ err = register_filesystem(&ramfs_fs_type);
+ if (err)
+ bdi_destroy(&ramfs_backing_dev_info);
+
+ return err;
}
module_init(init_ramfs_fs)
int __init init_rootfs(void)
{
- int err;
+ int err = register_filesystem(&rootfs_fs_type);
- err = bdi_init(&ramfs_backing_dev_info);
if (err)
return err;
- err = register_filesystem(&rootfs_fs_type);
+ err = init_ramfs_fs();
if (err)
- bdi_destroy(&ramfs_backing_dev_info);
+ unregister_filesystem(&rootfs_fs_type);
return err;
}
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 3/5] initmpfs: Move rootfs code from fs/ramfs/ to init/
2013-06-29 20:12 [PATCH 0/5] initmpfs: use tmpfs instead of ramfs for rootfs Rob Landley
2013-06-29 20:12 ` [PATCH 1/5] initmpfs: replace MS_NOUSER in initramfs Rob Landley
2013-06-29 20:12 ` [PATCH 2/5] initmpfs: Move bdi setup from init_rootfs to init_ramfs Rob Landley
@ 2013-06-29 20:12 ` Rob Landley
2013-06-29 20:12 ` [PATCH 4/5] initmpfs: Make rootfs use tmpfs when CONFIG_TMPFS enabled Rob Landley
2013-06-29 20:12 ` [PATCH 5/5] initmpfs: Use initramfs if rootfstype= or root= specified Rob Landley
4 siblings, 0 replies; 9+ messages in thread
From: Rob Landley @ 2013-06-29 20:12 UTC (permalink / raw)
To: linux-kernel
Cc: linux-fsdevel, Jeff Layton, Jens Axboe, Stephen Warren,
Rusty Russell, Jim Cromie, Sam Ravnborg, Greg Kroah-Hartman,
Andrew Morton, Eric W. Biederman, Alexander Viro
From: Rob Landley <rob@landley.net>
When the rootfs code was a wrapper around ramfs, having them in the same
file made sense. Now that it can wrap another filesystem type, move it
in with the init code instead.
This also allows a subsequent patch to access rootfstype= command line arg.
Signed-off-by: Rob Landley <rob@landley.net>
---
fs/namespace.c | 2 +-
fs/ramfs/inode.c | 34 +---------------------------------
include/linux/init.h | 1 +
include/linux/ramfs.h | 2 +-
init/do_mounts.c | 34 ++++++++++++++++++++++++++++++++++
5 files changed, 38 insertions(+), 35 deletions(-)
--- initold/fs/namespace.c 2013-06-28 15:09:19.389872904 -0500
+++ initold2/fs/namespace.c 2013-06-28 15:16:05.261889820 -0500
@@ -17,7 +17,7 @@
#include <linux/security.h>
#include <linux/idr.h>
#include <linux/acct.h> /* acct_auto_close_mnt */
-#include <linux/ramfs.h> /* init_rootfs */
+#include <linux/init.h> /* init_rootfs */
#include <linux/fs_struct.h> /* get_fs_root et.al. */
#include <linux/fsnotify.h> /* fsnotify_vfsmount_delete */
#include <linux/uaccess.h>
--- initold/fs/ramfs/inode.c 2013-06-28 15:15:37.549888666 -0500
+++ initold2/fs/ramfs/inode.c 2013-06-28 15:16:05.273889820 -0500
@@ -244,19 +244,6 @@
return mount_nodev(fs_type, flags, data, ramfs_fill_super);
}
-static struct dentry *rootfs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
-{
- static int once;
-
- if (once)
- return ERR_PTR(-ENODEV);
- else
- once++;
-
- return mount_nodev(fs_type, flags, data, ramfs_fill_super);
-}
-
static void ramfs_kill_sb(struct super_block *sb)
{
kfree(sb->s_fs_info);
@@ -269,13 +256,8 @@
.kill_sb = ramfs_kill_sb,
.fs_flags = FS_USERNS_MOUNT,
};
-static struct file_system_type rootfs_fs_type = {
- .name = "rootfs",
- .mount = rootfs_mount,
- .kill_sb = kill_litter_super,
-};
-static int __init init_ramfs_fs(void)
+int __init init_ramfs_fs(void)
{
static int once;
int err;
@@ -296,17 +276,3 @@
return err;
}
module_init(init_ramfs_fs)
-
-int __init init_rootfs(void)
-{
- int err = register_filesystem(&rootfs_fs_type);
-
- if (err)
- return err;
-
- err = init_ramfs_fs();
- if (err)
- unregister_filesystem(&rootfs_fs_type);
-
- return err;
-}
--- initold/include/linux/init.h 2013-06-28 15:09:19.517872909 -0500
+++ initold2/include/linux/init.h 2013-06-28 15:16:05.321889821 -0500
@@ -154,6 +154,7 @@
void setup_arch(char **);
void prepare_namespace(void);
void __init load_default_modules(void);
+int __init init_rootfs(void);
extern void (*late_time_init)(void);
--- initold/include/linux/ramfs.h 2013-06-28 15:09:19.537872910 -0500
+++ initold2/include/linux/ramfs.h 2013-06-28 15:16:05.513889832 -0500
@@ -25,7 +25,7 @@
extern const struct file_operations ramfs_file_operations;
extern const struct vm_operations_struct generic_file_vm_ops;
-extern int __init init_rootfs(void);
+extern int __init init_ramfs_fs(void);
int ramfs_fill_super(struct super_block *sb, void *data, int silent);
--- initold/init/do_mounts.c 2013-06-28 15:09:19.585872913 -0500
+++ initold2/init/do_mounts.c 2013-06-28 15:16:05.561889831 -0500
@@ -26,6 +26,7 @@
#include <linux/async.h>
#include <linux/fs_struct.h>
#include <linux/slab.h>
+#include <linux/ramfs.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
@@ -588,3 +589,36 @@
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot(".");
}
+
+static struct dentry *rootfs_mount(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data)
+{
+ static int once;
+
+ if (once)
+ return ERR_PTR(-ENODEV);
+ else
+ once++;
+
+ return mount_nodev(fs_type, flags, data, ramfs_fill_super);
+}
+
+static struct file_system_type rootfs_fs_type = {
+ .name = "rootfs",
+ .mount = rootfs_mount,
+ .kill_sb = kill_litter_super,
+};
+
+int __init init_rootfs(void)
+{
+ int err = register_filesystem(&rootfs_fs_type);
+
+ if (err)
+ return err;
+
+ err = init_ramfs_fs();
+ if (err)
+ unregister_filesystem(&rootfs_fs_type);
+
+ return err;
+}
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index c24f1e1..3b9f114 100644
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 4/5] initmpfs: Make rootfs use tmpfs when CONFIG_TMPFS enabled.
2013-06-29 20:12 [PATCH 0/5] initmpfs: use tmpfs instead of ramfs for rootfs Rob Landley
` (2 preceding siblings ...)
2013-06-29 20:12 ` [PATCH 3/5] initmpfs: Move rootfs code from fs/ramfs/ to init/ Rob Landley
@ 2013-06-29 20:12 ` Rob Landley
2013-06-29 20:12 ` [PATCH 5/5] initmpfs: Use initramfs if rootfstype= or root= specified Rob Landley
4 siblings, 0 replies; 9+ messages in thread
From: Rob Landley @ 2013-06-29 20:12 UTC (permalink / raw)
To: linux-kernel
Cc: linux-mm, Al Viro, Greg Kroah-Hartman, Jens Axboe, Stephen Warren,
Andrew Morton, Hugh Dickins
From: Rob Landley <rob@landley.net>
Conditionally call the appropriate fs_init function and fill_super functions.
Add a use once guard to shmem_init() to simply succeed on a second call.
(Note that IS_ENABLED() is a compile time constant so dead code elimination
removes unused function calls when CONFIG_TMPFS is disabled.)
Signed-off-by: Rob Landley <rob@landley.net>
---
init/do_mounts.c | 10 ++++++++--
mm/shmem.c | 4 ++++
2 files changed, 12 insertions(+), 2 deletions(-)
--- initold/init/do_mounts.c 2013-06-27 00:02:26.283442977 -0500
+++ initwork/init/do_mounts.c 2013-06-27 00:45:21.599550312 -0500
@@ -27,6 +27,7 @@
#include <linux/fs_struct.h>
#include <linux/slab.h>
#include <linux/ramfs.h>
+#include <linux/shmem_fs.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
@@ -600,7 +599,8 @@
else
once++;
- return mount_nodev(fs_type, flags, data, ramfs_fill_super);
+ return mount_nodev(fs_type, flags, data,
+ IS_ENABLED(CONFIG_TMPFS) ? shmem_fill_super : ramfs_fill_super);
}
static struct file_system_type rootfs_fs_type = {
@@ -616,7 +616,11 @@
if (err)
return err;
- err = init_ramfs_fs();
+ if (IS_ENABLED(CONFIG_TMPFS))
+ err = shmem_init();
+ else
+ err = init_ramfs_fs();
+
if (err)
unregister_filesystem(&rootfs_fs_type);
--- initold/mm/shmem.c 2013-06-25 13:09:22.215743137 -0500
+++ initwork/mm/shmem.c 2013-06-27 00:16:58.195479317 -0500
@@ -2787,6 +2787,10 @@
{
int error;
+ /* If rootfs called this, don't re-init */
+ if (shmem_inode_cachep)
+ return 0;
+
error = bdi_init(&shmem_backing_dev_info);
if (error)
goto out4;
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 5/5] initmpfs: Use initramfs if rootfstype= or root= specified.
2013-06-29 20:12 [PATCH 0/5] initmpfs: use tmpfs instead of ramfs for rootfs Rob Landley
` (3 preceding siblings ...)
2013-06-29 20:12 ` [PATCH 4/5] initmpfs: Make rootfs use tmpfs when CONFIG_TMPFS enabled Rob Landley
@ 2013-06-29 20:12 ` Rob Landley
4 siblings, 0 replies; 9+ messages in thread
From: Rob Landley @ 2013-06-29 20:12 UTC (permalink / raw)
To: linux-kernel
Cc: Al Viro, Greg Kroah-Hartman, Jens Axboe, Stephen Warren,
Andrew Morton
From: Rob Landley <rob@landley.net>
Command line option rootfstype=ramfs to obtain old initramfs behavior,
and use ramfs instead of tmpfs for stub when root= defined (for cosmetic
reasons).
Signed-off-by: Rob Landley <rob@landley.net>
---
init/do_mounts.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
--- initold/init/do_mounts.c 2013-06-29 13:27:00.485256840 -0500
+++ initwork/init/do_mounts.c 2013-06-29 13:34:17.925275072 -0500
@@ -591,18 +591,22 @@
sys_chroot(".");
}
+static bool is_tmpfs;
static struct dentry *rootfs_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
static int once;
+ void *fill = ramfs_fill_super;
if (once)
return ERR_PTR(-ENODEV);
else
once++;
- return mount_nodev(fs_type, flags, data,
- IS_ENABLED(CONFIG_TMPFS) ? shmem_fill_super : ramfs_fill_super);
+ if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
+ fill = shmem_fill_super;
+
+ return mount_nodev(fs_type, flags, data, fill);
}
static struct file_system_type rootfs_fs_type = {
@@ -618,9 +622,12 @@
if (err)
return err;
- if (IS_ENABLED(CONFIG_TMPFS))
+ if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] &&
+ (!root_fs_names || strstr(root_fs_names, "tmpfs")))
+ {
err = shmem_init();
- else
+ is_tmpfs = true;
+ } else
err = init_ramfs_fs();
if (err)
^ permalink raw reply [flat|nested] 9+ messages in thread