diff options
author | Vasiliy Kulikov <segooon@gmail.com> | 2012-01-10 18:11:27 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-10 19:30:54 -0500 |
commit | 97412950b10e64f347aec4a9b759395c2465adf6 (patch) | |
tree | 1b68e499cb9fcda81f88d6d0ee57826f4a6d7a56 /fs | |
parent | 640708a2cff7f81e246243b0073c66e6ece7e53e (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')
-rw-r--r-- | fs/proc/inode.c | 10 | ||||
-rw-r--r-- | fs/proc/internal.h | 1 | ||||
-rw-r--r-- | fs/proc/root.c | 55 |
3 files changed, 64 insertions, 2 deletions
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 51a176622b8f..27c762f34870 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/time.h> | 7 | #include <linux/time.h> |
8 | #include <linux/proc_fs.h> | 8 | #include <linux/proc_fs.h> |
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/pid_namespace.h> | ||
10 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
11 | #include <linux/string.h> | 12 | #include <linux/string.h> |
12 | #include <linux/stat.h> | 13 | #include <linux/stat.h> |
@@ -17,7 +18,9 @@ | |||
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | #include <linux/sysctl.h> | 20 | #include <linux/sysctl.h> |
21 | #include <linux/seq_file.h> | ||
20 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/mount.h> | ||
21 | 24 | ||
22 | #include <asm/system.h> | 25 | #include <asm/system.h> |
23 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
@@ -101,12 +104,19 @@ void __init proc_init_inodecache(void) | |||
101 | init_once); | 104 | init_once); |
102 | } | 105 | } |
103 | 106 | ||
107 | static int proc_show_options(struct seq_file *seq, struct dentry *root) | ||
108 | { | ||
109 | return 0; | ||
110 | } | ||
111 | |||
104 | static const struct super_operations proc_sops = { | 112 | static const struct super_operations proc_sops = { |
105 | .alloc_inode = proc_alloc_inode, | 113 | .alloc_inode = proc_alloc_inode, |
106 | .destroy_inode = proc_destroy_inode, | 114 | .destroy_inode = proc_destroy_inode, |
107 | .drop_inode = generic_delete_inode, | 115 | .drop_inode = generic_delete_inode, |
108 | .evict_inode = proc_evict_inode, | 116 | .evict_inode = proc_evict_inode, |
109 | .statfs = simple_statfs, | 117 | .statfs = simple_statfs, |
118 | .remount_fs = proc_remount, | ||
119 | .show_options = proc_show_options, | ||
110 | }; | 120 | }; |
111 | 121 | ||
112 | static void __pde_users_dec(struct proc_dir_entry *pde) | 122 | static void __pde_users_dec(struct proc_dir_entry *pde) |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 7838e5cfec14..292577531ad1 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -117,6 +117,7 @@ void pde_put(struct proc_dir_entry *pde); | |||
117 | 117 | ||
118 | int proc_fill_super(struct super_block *); | 118 | int proc_fill_super(struct super_block *); |
119 | struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); | 119 | struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); |
120 | int proc_remount(struct super_block *sb, int *flags, char *data); | ||
120 | 121 | ||
121 | /* | 122 | /* |
122 | * These are generic /proc routines that use the internal | 123 | * These are generic /proc routines that use the internal |
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 | ||
40 | enum { | ||
41 | Opt_err, | ||
42 | }; | ||
43 | |||
44 | static const match_table_t tokens = { | ||
45 | {Opt_err, NULL}, | ||
46 | }; | ||
47 | |||
48 | static 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 | |||
76 | int 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 | |||
39 | static struct dentry *proc_mount(struct file_system_type *fs_type, | 82 | static 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); |