diff options
Diffstat (limited to 'fs/proc/root.c')
-rw-r--r-- | fs/proc/root.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/fs/proc/root.c b/fs/proc/root.c index f4b1a9d2eca6..fe4f64b3250b 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/pid_namespace.h> | 23 | #include <linux/pid_namespace.h> |
24 | #include <linux/parser.h> | 24 | #include <linux/parser.h> |
25 | #include <linux/cred.h> | 25 | #include <linux/cred.h> |
26 | #include <linux/magic.h> | ||
26 | 27 | ||
27 | #include "internal.h" | 28 | #include "internal.h" |
28 | 29 | ||
@@ -36,7 +37,7 @@ static const match_table_t tokens = { | |||
36 | {Opt_err, NULL}, | 37 | {Opt_err, NULL}, |
37 | }; | 38 | }; |
38 | 39 | ||
39 | int proc_parse_options(char *options, struct pid_namespace *pid) | 40 | static int proc_parse_options(char *options, struct pid_namespace *pid) |
40 | { | 41 | { |
41 | char *p; | 42 | char *p; |
42 | substring_t args[MAX_OPT_ARGS]; | 43 | substring_t args[MAX_OPT_ARGS]; |
@@ -78,6 +79,54 @@ int proc_parse_options(char *options, struct pid_namespace *pid) | |||
78 | return 1; | 79 | return 1; |
79 | } | 80 | } |
80 | 81 | ||
82 | static int proc_fill_super(struct super_block *s, void *data, int silent) | ||
83 | { | ||
84 | struct pid_namespace *ns = get_pid_ns(s->s_fs_info); | ||
85 | struct inode *root_inode; | ||
86 | int ret; | ||
87 | |||
88 | if (!proc_parse_options(data, ns)) | ||
89 | return -EINVAL; | ||
90 | |||
91 | /* User space would break if executables or devices appear on proc */ | ||
92 | s->s_iflags |= SB_I_USERNS_VISIBLE | SB_I_NOEXEC | SB_I_NODEV; | ||
93 | s->s_flags |= SB_NODIRATIME | SB_NOSUID | SB_NOEXEC; | ||
94 | s->s_blocksize = 1024; | ||
95 | s->s_blocksize_bits = 10; | ||
96 | s->s_magic = PROC_SUPER_MAGIC; | ||
97 | s->s_op = &proc_sops; | ||
98 | s->s_time_gran = 1; | ||
99 | |||
100 | /* | ||
101 | * procfs isn't actually a stacking filesystem; however, there is | ||
102 | * too much magic going on inside it to permit stacking things on | ||
103 | * top of it | ||
104 | */ | ||
105 | s->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH; | ||
106 | |||
107 | /* procfs dentries and inodes don't require IO to create */ | ||
108 | s->s_shrink.seeks = 0; | ||
109 | |||
110 | pde_get(&proc_root); | ||
111 | root_inode = proc_get_inode(s, &proc_root); | ||
112 | if (!root_inode) { | ||
113 | pr_err("proc_fill_super: get root inode failed\n"); | ||
114 | return -ENOMEM; | ||
115 | } | ||
116 | |||
117 | s->s_root = d_make_root(root_inode); | ||
118 | if (!s->s_root) { | ||
119 | pr_err("proc_fill_super: allocate dentry failed\n"); | ||
120 | return -ENOMEM; | ||
121 | } | ||
122 | |||
123 | ret = proc_setup_self(s); | ||
124 | if (ret) { | ||
125 | return ret; | ||
126 | } | ||
127 | return proc_setup_thread_self(s); | ||
128 | } | ||
129 | |||
81 | int proc_remount(struct super_block *sb, int *flags, char *data) | 130 | int proc_remount(struct super_block *sb, int *flags, char *data) |
82 | { | 131 | { |
83 | struct pid_namespace *pid = sb->s_fs_info; | 132 | struct pid_namespace *pid = sb->s_fs_info; |