diff options
Diffstat (limited to 'drivers/base/devtmpfs.c')
-rw-r--r-- | drivers/base/devtmpfs.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index ba5c80903efe..bafdf86b0497 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c @@ -56,22 +56,38 @@ static int __init mount_param(char *str) } __setup("devtmpfs.mount=", mount_param); +static struct vfsmount *mnt; + +static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data) +{ + struct super_block *s = mnt->mnt_sb; + atomic_inc(&s->s_active); + down_write(&s->s_umount); + return dget(s->s_root); +} + static struct dentry *dev_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { #ifdef CONFIG_TMPFS - return mount_single(fs_type, flags, data, shmem_fill_super); + return mount_nodev(fs_type, flags, data, shmem_fill_super); #else - return mount_single(fs_type, flags, data, ramfs_fill_super); + return ramfs_mount(fs_type, flags, dev_name, data); #endif } -static struct file_system_type dev_fs_type = { +static struct file_system_type internal_fs_type = { .name = "devtmpfs", .mount = dev_mount, .kill_sb = kill_litter_super, }; +static struct file_system_type dev_fs_type = { + .name = "devtmpfs", + .mount = public_dev_mount, +}; + #ifdef CONFIG_BLOCK static inline int is_blockdev(struct device *dev) { @@ -378,12 +394,11 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, static int devtmpfsd(void *p) { - char options[] = "mode=0755"; int *err = p; *err = ksys_unshare(CLONE_NEWNS); if (*err) goto out; - *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); + *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); if (*err) goto out; ksys_chdir("/.."); /* will traverse into overmounted root */ @@ -420,7 +435,16 @@ out: */ int __init devtmpfs_init(void) { - int err = register_filesystem(&dev_fs_type); + char opts[] = "mode=0755"; + int err; + + mnt = vfs_kern_mount(&internal_fs_type, 0, "devtmpfs", opts); + if (IS_ERR(mnt)) { + printk(KERN_ERR "devtmpfs: unable to create devtmpfs %ld\n", + PTR_ERR(mnt)); + return PTR_ERR(mnt); + } + err = register_filesystem(&dev_fs_type); if (err) { printk(KERN_ERR "devtmpfs: unable to register devtmpfs " "type %i\n", err); |