aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/root.c
diff options
context:
space:
mode:
authorVasiliy Kulikov <segooon@gmail.com>2012-01-10 18:11:27 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 19:30:54 -0500
commit97412950b10e64f347aec4a9b759395c2465adf6 (patch)
tree1b68e499cb9fcda81f88d6d0ee57826f4a6d7a56 /fs/proc/root.c
parent640708a2cff7f81e246243b0073c66e6ece7e53e (diff)
procfs: parse mount options
Add support for procfs mount options. Actual mount options are coming in the next patches. Signed-off-by: Vasiliy Kulikov <segoon@openwall.com> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Randy Dunlap <rdunlap@xenotime.net> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Greg KH <greg@kroah.com> Cc: Theodore Tso <tytso@MIT.EDU> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: James Morris <jmorris@namei.org> Cc: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc/root.c')
-rw-r--r--fs/proc/root.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 03102d978180..6a8ac1d361a9 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -18,6 +18,7 @@
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19#include <linux/mount.h> 19#include <linux/mount.h>
20#include <linux/pid_namespace.h> 20#include <linux/pid_namespace.h>
21#include <linux/parser.h>
21 22
22#include "internal.h" 23#include "internal.h"
23 24
@@ -36,6 +37,48 @@ static int proc_set_super(struct super_block *sb, void *data)
36 return err; 37 return err;
37} 38}
38 39
40enum {
41 Opt_err,
42};
43
44static const match_table_t tokens = {
45 {Opt_err, NULL},
46};
47
48static int proc_parse_options(char *options, struct pid_namespace *pid)
49{
50 char *p;
51 substring_t args[MAX_OPT_ARGS];
52
53 pr_debug("proc: options = %s\n", options);
54
55 if (!options)
56 return 1;
57
58 while ((p = strsep(&options, ",")) != NULL) {
59 int token;
60 if (!*p)
61 continue;
62
63 args[0].to = args[0].from = 0;
64 token = match_token(p, tokens, args);
65 switch (token) {
66 default:
67 pr_err("proc: unrecognized mount option \"%s\" "
68 "or missing value\n", p);
69 return 0;
70 }
71 }
72
73 return 1;
74}
75
76int proc_remount(struct super_block *sb, int *flags, char *data)
77{
78 struct pid_namespace *pid = sb->s_fs_info;
79 return !proc_parse_options(data, pid);
80}
81
39static struct dentry *proc_mount(struct file_system_type *fs_type, 82static struct dentry *proc_mount(struct file_system_type *fs_type,
40 int flags, const char *dev_name, void *data) 83 int flags, const char *dev_name, void *data)
41{ 84{
@@ -43,11 +86,15 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
43 struct super_block *sb; 86 struct super_block *sb;
44 struct pid_namespace *ns; 87 struct pid_namespace *ns;
45 struct proc_inode *ei; 88 struct proc_inode *ei;
89 char *options;
46 90
47 if (flags & MS_KERNMOUNT) 91 if (flags & MS_KERNMOUNT) {
48 ns = (struct pid_namespace *)data; 92 ns = (struct pid_namespace *)data;
49 else 93 options = NULL;
94 } else {
50 ns = current->nsproxy->pid_ns; 95 ns = current->nsproxy->pid_ns;
96 options = data;
97 }
51 98
52 sb = sget(fs_type, proc_test_super, proc_set_super, ns); 99 sb = sget(fs_type, proc_test_super, proc_set_super, ns);
53 if (IS_ERR(sb)) 100 if (IS_ERR(sb))
@@ -55,6 +102,10 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
55 102
56 if (!sb->s_root) { 103 if (!sb->s_root) {
57 sb->s_flags = flags; 104 sb->s_flags = flags;
105 if (!proc_parse_options(options, ns)) {
106 deactivate_locked_super(sb);
107 return ERR_PTR(-EINVAL);
108 }
58 err = proc_fill_super(sb); 109 err = proc_fill_super(sb);
59 if (err) { 110 if (err) {
60 deactivate_locked_super(sb); 111 deactivate_locked_super(sb);