diff options
Diffstat (limited to 'drivers/base/devtmpfs.c')
-rw-r--r-- | drivers/base/devtmpfs.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index ba5c80903efe..30d0523014e0 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -56,20 +56,32 @@ static int __init mount_param(char *str) | |||
56 | } | 56 | } |
57 | __setup("devtmpfs.mount=", mount_param); | 57 | __setup("devtmpfs.mount=", mount_param); |
58 | 58 | ||
59 | static struct dentry *dev_mount(struct file_system_type *fs_type, int flags, | 59 | static struct vfsmount *mnt; |
60 | |||
61 | static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags, | ||
60 | const char *dev_name, void *data) | 62 | const char *dev_name, void *data) |
61 | { | 63 | { |
64 | struct super_block *s = mnt->mnt_sb; | ||
65 | atomic_inc(&s->s_active); | ||
66 | down_write(&s->s_umount); | ||
67 | return dget(s->s_root); | ||
68 | } | ||
69 | |||
70 | static struct file_system_type internal_fs_type = { | ||
71 | .name = "devtmpfs", | ||
62 | #ifdef CONFIG_TMPFS | 72 | #ifdef CONFIG_TMPFS |
63 | return mount_single(fs_type, flags, data, shmem_fill_super); | 73 | .init_fs_context = shmem_init_fs_context, |
74 | .parameters = &shmem_fs_parameters, | ||
64 | #else | 75 | #else |
65 | return mount_single(fs_type, flags, data, ramfs_fill_super); | 76 | .init_fs_context = ramfs_init_fs_context, |
77 | .parameters = &ramfs_fs_parameters, | ||
66 | #endif | 78 | #endif |
67 | } | 79 | .kill_sb = kill_litter_super, |
80 | }; | ||
68 | 81 | ||
69 | static struct file_system_type dev_fs_type = { | 82 | static struct file_system_type dev_fs_type = { |
70 | .name = "devtmpfs", | 83 | .name = "devtmpfs", |
71 | .mount = dev_mount, | 84 | .mount = public_dev_mount, |
72 | .kill_sb = kill_litter_super, | ||
73 | }; | 85 | }; |
74 | 86 | ||
75 | #ifdef CONFIG_BLOCK | 87 | #ifdef CONFIG_BLOCK |
@@ -378,12 +390,11 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, | |||
378 | 390 | ||
379 | static int devtmpfsd(void *p) | 391 | static int devtmpfsd(void *p) |
380 | { | 392 | { |
381 | char options[] = "mode=0755"; | ||
382 | int *err = p; | 393 | int *err = p; |
383 | *err = ksys_unshare(CLONE_NEWNS); | 394 | *err = ksys_unshare(CLONE_NEWNS); |
384 | if (*err) | 395 | if (*err) |
385 | goto out; | 396 | goto out; |
386 | *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); | 397 | *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); |
387 | if (*err) | 398 | if (*err) |
388 | goto out; | 399 | goto out; |
389 | ksys_chdir("/.."); /* will traverse into overmounted root */ | 400 | ksys_chdir("/.."); /* will traverse into overmounted root */ |
@@ -420,7 +431,16 @@ out: | |||
420 | */ | 431 | */ |
421 | int __init devtmpfs_init(void) | 432 | int __init devtmpfs_init(void) |
422 | { | 433 | { |
423 | int err = register_filesystem(&dev_fs_type); | 434 | char opts[] = "mode=0755"; |
435 | int err; | ||
436 | |||
437 | mnt = vfs_kern_mount(&internal_fs_type, 0, "devtmpfs", opts); | ||
438 | if (IS_ERR(mnt)) { | ||
439 | printk(KERN_ERR "devtmpfs: unable to create devtmpfs %ld\n", | ||
440 | PTR_ERR(mnt)); | ||
441 | return PTR_ERR(mnt); | ||
442 | } | ||
443 | err = register_filesystem(&dev_fs_type); | ||
424 | if (err) { | 444 | if (err) { |
425 | printk(KERN_ERR "devtmpfs: unable to register devtmpfs " | 445 | printk(KERN_ERR "devtmpfs: unable to register devtmpfs " |
426 | "type %i\n", err); | 446 | "type %i\n", err); |