diff options
Diffstat (limited to 'fs/afs/super.c')
-rw-r--r-- | fs/afs/super.c | 100 |
1 files changed, 43 insertions, 57 deletions
diff --git a/fs/afs/super.c b/fs/afs/super.c index cebd03c91f57..41173f81ac47 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/parser.h> | ||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | 25 | ||
25 | #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ | 26 | #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ |
@@ -42,7 +43,7 @@ struct file_system_type afs_fs_type = { | |||
42 | .name = "afs", | 43 | .name = "afs", |
43 | .get_sb = afs_get_sb, | 44 | .get_sb = afs_get_sb, |
44 | .kill_sb = kill_anon_super, | 45 | .kill_sb = kill_anon_super, |
45 | .fs_flags = FS_BINARY_MOUNTDATA, | 46 | .fs_flags = 0, |
46 | }; | 47 | }; |
47 | 48 | ||
48 | static const struct super_operations afs_super_ops = { | 49 | static const struct super_operations afs_super_ops = { |
@@ -58,6 +59,20 @@ static const struct super_operations afs_super_ops = { | |||
58 | static struct kmem_cache *afs_inode_cachep; | 59 | static struct kmem_cache *afs_inode_cachep; |
59 | static atomic_t afs_count_active_inodes; | 60 | static atomic_t afs_count_active_inodes; |
60 | 61 | ||
62 | enum { | ||
63 | afs_no_opt, | ||
64 | afs_opt_cell, | ||
65 | afs_opt_rwpath, | ||
66 | afs_opt_vol, | ||
67 | }; | ||
68 | |||
69 | static const match_table_t afs_options_list = { | ||
70 | { afs_opt_cell, "cell=%s" }, | ||
71 | { afs_opt_rwpath, "rwpath" }, | ||
72 | { afs_opt_vol, "vol=%s" }, | ||
73 | { afs_no_opt, NULL }, | ||
74 | }; | ||
75 | |||
61 | /* | 76 | /* |
62 | * initialise the filesystem | 77 | * initialise the filesystem |
63 | */ | 78 | */ |
@@ -115,31 +130,6 @@ void __exit afs_fs_exit(void) | |||
115 | } | 130 | } |
116 | 131 | ||
117 | /* | 132 | /* |
118 | * check that an argument has a value | ||
119 | */ | ||
120 | static int want_arg(char **_value, const char *option) | ||
121 | { | ||
122 | if (!_value || !*_value || !**_value) { | ||
123 | printk(KERN_NOTICE "kAFS: %s: argument missing\n", option); | ||
124 | return 0; | ||
125 | } | ||
126 | return 1; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * check that there's no subsequent value | ||
131 | */ | ||
132 | static int want_no_value(char *const *_value, const char *option) | ||
133 | { | ||
134 | if (*_value && **_value) { | ||
135 | printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n", | ||
136 | option, *_value); | ||
137 | return 0; | ||
138 | } | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * parse the mount options | 133 | * parse the mount options |
144 | * - this function has been shamelessly adapted from the ext3 fs which | 134 | * - this function has been shamelessly adapted from the ext3 fs which |
145 | * shamelessly adapted it from the msdos fs | 135 | * shamelessly adapted it from the msdos fs |
@@ -148,48 +138,46 @@ static int afs_parse_options(struct afs_mount_params *params, | |||
148 | char *options, const char **devname) | 138 | char *options, const char **devname) |
149 | { | 139 | { |
150 | struct afs_cell *cell; | 140 | struct afs_cell *cell; |
151 | char *key, *value; | 141 | substring_t args[MAX_OPT_ARGS]; |
152 | int ret; | 142 | char *p; |
143 | int token; | ||
153 | 144 | ||
154 | _enter("%s", options); | 145 | _enter("%s", options); |
155 | 146 | ||
156 | options[PAGE_SIZE - 1] = 0; | 147 | options[PAGE_SIZE - 1] = 0; |
157 | 148 | ||
158 | ret = 0; | 149 | while ((p = strsep(&options, ","))) { |
159 | while ((key = strsep(&options, ","))) { | 150 | if (!*p) |
160 | value = strchr(key, '='); | 151 | continue; |
161 | if (value) | ||
162 | *value++ = 0; | ||
163 | |||
164 | _debug("kAFS: KEY: %s, VAL:%s", key, value ?: "-"); | ||
165 | 152 | ||
166 | if (strcmp(key, "rwpath") == 0) { | 153 | token = match_token(p, afs_options_list, args); |
167 | if (!want_no_value(&value, "rwpath")) | 154 | switch (token) { |
168 | return -EINVAL; | 155 | case afs_opt_cell: |
169 | params->rwpath = 1; | 156 | cell = afs_cell_lookup(args[0].from, |
170 | } else if (strcmp(key, "vol") == 0) { | 157 | args[0].to - args[0].from); |
171 | if (!want_arg(&value, "vol")) | ||
172 | return -EINVAL; | ||
173 | *devname = value; | ||
174 | } else if (strcmp(key, "cell") == 0) { | ||
175 | if (!want_arg(&value, "cell")) | ||
176 | return -EINVAL; | ||
177 | cell = afs_cell_lookup(value, strlen(value)); | ||
178 | if (IS_ERR(cell)) | 158 | if (IS_ERR(cell)) |
179 | return PTR_ERR(cell); | 159 | return PTR_ERR(cell); |
180 | afs_put_cell(params->cell); | 160 | afs_put_cell(params->cell); |
181 | params->cell = cell; | 161 | params->cell = cell; |
182 | } else { | 162 | break; |
183 | printk("kAFS: Unknown mount option: '%s'\n", key); | 163 | |
184 | ret = -EINVAL; | 164 | case afs_opt_rwpath: |
185 | goto error; | 165 | params->rwpath = 1; |
166 | break; | ||
167 | |||
168 | case afs_opt_vol: | ||
169 | *devname = args[0].from; | ||
170 | break; | ||
171 | |||
172 | default: | ||
173 | printk(KERN_ERR "kAFS:" | ||
174 | " Unknown or invalid mount option: '%s'\n", p); | ||
175 | return -EINVAL; | ||
186 | } | 176 | } |
187 | } | 177 | } |
188 | 178 | ||
189 | ret = 0; | 179 | _leave(" = 0"); |
190 | error: | 180 | return 0; |
191 | _leave(" = %d", ret); | ||
192 | return ret; | ||
193 | } | 181 | } |
194 | 182 | ||
195 | /* | 183 | /* |
@@ -361,7 +349,6 @@ error: | |||
361 | 349 | ||
362 | /* | 350 | /* |
363 | * get an AFS superblock | 351 | * get an AFS superblock |
364 | * - TODO: don't use get_sb_nodev(), but rather call sget() directly | ||
365 | */ | 352 | */ |
366 | static int afs_get_sb(struct file_system_type *fs_type, | 353 | static int afs_get_sb(struct file_system_type *fs_type, |
367 | int flags, | 354 | int flags, |
@@ -386,7 +373,6 @@ static int afs_get_sb(struct file_system_type *fs_type, | |||
386 | goto error; | 373 | goto error; |
387 | } | 374 | } |
388 | 375 | ||
389 | |||
390 | ret = afs_parse_device_name(¶ms, dev_name); | 376 | ret = afs_parse_device_name(¶ms, dev_name); |
391 | if (ret < 0) | 377 | if (ret < 0) |
392 | goto error; | 378 | goto error; |