aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/super.c')
-rw-r--r--fs/afs/super.c100
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
48static const struct super_operations afs_super_ops = { 49static const struct super_operations afs_super_ops = {
@@ -58,6 +59,20 @@ static const struct super_operations afs_super_ops = {
58static struct kmem_cache *afs_inode_cachep; 59static struct kmem_cache *afs_inode_cachep;
59static atomic_t afs_count_active_inodes; 60static atomic_t afs_count_active_inodes;
60 61
62enum {
63 afs_no_opt,
64 afs_opt_cell,
65 afs_opt_rwpath,
66 afs_opt_vol,
67};
68
69static 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 */
120static 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 */
132static 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");
190error: 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 */
366static int afs_get_sb(struct file_system_type *fs_type, 353static 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(&params, dev_name); 376 ret = afs_parse_device_name(&params, dev_name);
391 if (ret < 0) 377 if (ret < 0)
392 goto error; 378 goto error;