diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 18:05:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-17 18:05:58 -0400 |
commit | 9d8190f87b5458160ba75d05e8ad6abefbe48a26 (patch) | |
tree | 7abeb91aa2a40b91004f53520b7bf1f2c80aab7e /fs/9p/v9fs.c | |
parent | c2f73fd07d2ce4605b404f34395eb734a7ba9967 (diff) | |
parent | 982c37cfb6e61c0e64634abc2e305d757c1405b2 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
9p: remove sysctl
9p: fix bad kconfig cross-dependency
9p: soften invalidation in loose_mode
9p: attach-per-user
9p: rename uid and gid parameters
9p: define session flags
9p: Make transports dynamic
Diffstat (limited to 'fs/9p/v9fs.c')
-rw-r--r-- | fs/9p/v9fs.c | 189 |
1 files changed, 89 insertions, 100 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 0a7068e30ecb..873802de21cd 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -38,56 +38,41 @@ | |||
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Option Parsing (code inspired by NFS code) | 40 | * Option Parsing (code inspired by NFS code) |
41 | * | 41 | * NOTE: each transport will parse its own options |
42 | */ | 42 | */ |
43 | 43 | ||
44 | enum { | 44 | enum { |
45 | /* Options that take integer arguments */ | 45 | /* Options that take integer arguments */ |
46 | Opt_debug, Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, | 46 | Opt_debug, Opt_msize, Opt_dfltuid, Opt_dfltgid, Opt_afid, |
47 | Opt_rfdno, Opt_wfdno, | ||
48 | /* String options */ | 47 | /* String options */ |
49 | Opt_uname, Opt_remotename, | 48 | Opt_uname, Opt_remotename, Opt_trans, |
50 | /* Options that take no arguments */ | 49 | /* Options that take no arguments */ |
51 | Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, Opt_pci, | 50 | Opt_legacy, Opt_nodevmap, |
52 | /* Cache options */ | 51 | /* Cache options */ |
53 | Opt_cache_loose, | 52 | Opt_cache_loose, |
53 | /* Access options */ | ||
54 | Opt_access, | ||
54 | /* Error token */ | 55 | /* Error token */ |
55 | Opt_err | 56 | Opt_err |
56 | }; | 57 | }; |
57 | 58 | ||
58 | static match_table_t tokens = { | 59 | static match_table_t tokens = { |
59 | {Opt_debug, "debug=%x"}, | 60 | {Opt_debug, "debug=%x"}, |
60 | {Opt_port, "port=%u"}, | ||
61 | {Opt_msize, "msize=%u"}, | 61 | {Opt_msize, "msize=%u"}, |
62 | {Opt_uid, "uid=%u"}, | 62 | {Opt_dfltuid, "dfltuid=%u"}, |
63 | {Opt_gid, "gid=%u"}, | 63 | {Opt_dfltgid, "dfltgid=%u"}, |
64 | {Opt_afid, "afid=%u"}, | 64 | {Opt_afid, "afid=%u"}, |
65 | {Opt_rfdno, "rfdno=%u"}, | ||
66 | {Opt_wfdno, "wfdno=%u"}, | ||
67 | {Opt_uname, "uname=%s"}, | 65 | {Opt_uname, "uname=%s"}, |
68 | {Opt_remotename, "aname=%s"}, | 66 | {Opt_remotename, "aname=%s"}, |
69 | {Opt_unix, "proto=unix"}, | 67 | {Opt_trans, "trans=%s"}, |
70 | {Opt_tcp, "proto=tcp"}, | ||
71 | {Opt_fd, "proto=fd"}, | ||
72 | #ifdef CONFIG_PCI_9P | ||
73 | {Opt_pci, "proto=pci"}, | ||
74 | #endif | ||
75 | {Opt_tcp, "tcp"}, | ||
76 | {Opt_unix, "unix"}, | ||
77 | {Opt_fd, "fd"}, | ||
78 | {Opt_legacy, "noextend"}, | 68 | {Opt_legacy, "noextend"}, |
79 | {Opt_nodevmap, "nodevmap"}, | 69 | {Opt_nodevmap, "nodevmap"}, |
80 | {Opt_cache_loose, "cache=loose"}, | 70 | {Opt_cache_loose, "cache=loose"}, |
81 | {Opt_cache_loose, "loose"}, | 71 | {Opt_cache_loose, "loose"}, |
72 | {Opt_access, "access=%s"}, | ||
82 | {Opt_err, NULL} | 73 | {Opt_err, NULL} |
83 | }; | 74 | }; |
84 | 75 | ||
85 | extern struct p9_transport *p9pci_trans_create(void); | ||
86 | |||
87 | /* | ||
88 | * Parse option string. | ||
89 | */ | ||
90 | |||
91 | /** | 76 | /** |
92 | * v9fs_parse_options - parse mount options into session structure | 77 | * v9fs_parse_options - parse mount options into session structure |
93 | * @options: options string passed from mount | 78 | * @options: options string passed from mount |
@@ -95,23 +80,21 @@ extern struct p9_transport *p9pci_trans_create(void); | |||
95 | * | 80 | * |
96 | */ | 81 | */ |
97 | 82 | ||
98 | static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | 83 | static void v9fs_parse_options(struct v9fs_session_info *v9ses) |
99 | { | 84 | { |
100 | char *p; | 85 | char *options = v9ses->options; |
101 | substring_t args[MAX_OPT_ARGS]; | 86 | substring_t args[MAX_OPT_ARGS]; |
87 | char *p; | ||
102 | int option; | 88 | int option; |
103 | int ret; | 89 | int ret; |
90 | char *s, *e; | ||
104 | 91 | ||
105 | /* setup defaults */ | 92 | /* setup defaults */ |
106 | v9ses->port = V9FS_PORT; | 93 | v9ses->maxdata = 8192; |
107 | v9ses->maxdata = 9000; | ||
108 | v9ses->proto = PROTO_TCP; | ||
109 | v9ses->extended = 1; | ||
110 | v9ses->afid = ~0; | 94 | v9ses->afid = ~0; |
111 | v9ses->debug = 0; | 95 | v9ses->debug = 0; |
112 | v9ses->rfdno = ~0; | ||
113 | v9ses->wfdno = ~0; | ||
114 | v9ses->cache = 0; | 96 | v9ses->cache = 0; |
97 | v9ses->trans = v9fs_default_trans(); | ||
115 | 98 | ||
116 | if (!options) | 99 | if (!options) |
117 | return; | 100 | return; |
@@ -135,47 +118,29 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
135 | p9_debug_level = option; | 118 | p9_debug_level = option; |
136 | #endif | 119 | #endif |
137 | break; | 120 | break; |
138 | case Opt_port: | ||
139 | v9ses->port = option; | ||
140 | break; | ||
141 | case Opt_msize: | 121 | case Opt_msize: |
142 | v9ses->maxdata = option; | 122 | v9ses->maxdata = option; |
143 | break; | 123 | break; |
144 | case Opt_uid: | 124 | case Opt_dfltuid: |
145 | v9ses->uid = option; | 125 | v9ses->dfltuid = option; |
146 | break; | 126 | break; |
147 | case Opt_gid: | 127 | case Opt_dfltgid: |
148 | v9ses->gid = option; | 128 | v9ses->dfltgid = option; |
149 | break; | 129 | break; |
150 | case Opt_afid: | 130 | case Opt_afid: |
151 | v9ses->afid = option; | 131 | v9ses->afid = option; |
152 | break; | 132 | break; |
153 | case Opt_rfdno: | 133 | case Opt_trans: |
154 | v9ses->rfdno = option; | 134 | v9ses->trans = v9fs_match_trans(&args[0]); |
155 | break; | ||
156 | case Opt_wfdno: | ||
157 | v9ses->wfdno = option; | ||
158 | break; | ||
159 | case Opt_tcp: | ||
160 | v9ses->proto = PROTO_TCP; | ||
161 | break; | ||
162 | case Opt_unix: | ||
163 | v9ses->proto = PROTO_UNIX; | ||
164 | break; | ||
165 | case Opt_pci: | ||
166 | v9ses->proto = PROTO_PCI; | ||
167 | break; | ||
168 | case Opt_fd: | ||
169 | v9ses->proto = PROTO_FD; | ||
170 | break; | 135 | break; |
171 | case Opt_uname: | 136 | case Opt_uname: |
172 | match_strcpy(v9ses->name, &args[0]); | 137 | match_strcpy(v9ses->uname, &args[0]); |
173 | break; | 138 | break; |
174 | case Opt_remotename: | 139 | case Opt_remotename: |
175 | match_strcpy(v9ses->remotename, &args[0]); | 140 | match_strcpy(v9ses->aname, &args[0]); |
176 | break; | 141 | break; |
177 | case Opt_legacy: | 142 | case Opt_legacy: |
178 | v9ses->extended = 0; | 143 | v9ses->flags &= ~V9FS_EXTENDED; |
179 | break; | 144 | break; |
180 | case Opt_nodevmap: | 145 | case Opt_nodevmap: |
181 | v9ses->nodev = 1; | 146 | v9ses->nodev = 1; |
@@ -183,6 +148,22 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
183 | case Opt_cache_loose: | 148 | case Opt_cache_loose: |
184 | v9ses->cache = CACHE_LOOSE; | 149 | v9ses->cache = CACHE_LOOSE; |
185 | break; | 150 | break; |
151 | |||
152 | case Opt_access: | ||
153 | s = match_strdup(&args[0]); | ||
154 | v9ses->flags &= ~V9FS_ACCESS_MASK; | ||
155 | if (strcmp(s, "user") == 0) | ||
156 | v9ses->flags |= V9FS_ACCESS_USER; | ||
157 | else if (strcmp(s, "any") == 0) | ||
158 | v9ses->flags |= V9FS_ACCESS_ANY; | ||
159 | else { | ||
160 | v9ses->flags |= V9FS_ACCESS_SINGLE; | ||
161 | v9ses->uid = simple_strtol(s, &e, 10); | ||
162 | if (*e != '\0') | ||
163 | v9ses->uid = ~0; | ||
164 | } | ||
165 | break; | ||
166 | |||
186 | default: | 167 | default: |
187 | continue; | 168 | continue; |
188 | } | 169 | } |
@@ -201,56 +182,46 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
201 | const char *dev_name, char *data) | 182 | const char *dev_name, char *data) |
202 | { | 183 | { |
203 | int retval = -EINVAL; | 184 | int retval = -EINVAL; |
204 | struct p9_transport *trans; | 185 | struct p9_trans *trans = NULL; |
205 | struct p9_fid *fid; | 186 | struct p9_fid *fid; |
206 | 187 | ||
207 | v9ses->name = __getname(); | 188 | v9ses->uname = __getname(); |
208 | if (!v9ses->name) | 189 | if (!v9ses->uname) |
209 | return ERR_PTR(-ENOMEM); | 190 | return ERR_PTR(-ENOMEM); |
210 | 191 | ||
211 | v9ses->remotename = __getname(); | 192 | v9ses->aname = __getname(); |
212 | if (!v9ses->remotename) { | 193 | if (!v9ses->aname) { |
213 | __putname(v9ses->name); | 194 | __putname(v9ses->uname); |
214 | return ERR_PTR(-ENOMEM); | 195 | return ERR_PTR(-ENOMEM); |
215 | } | 196 | } |
216 | 197 | ||
217 | strcpy(v9ses->name, V9FS_DEFUSER); | 198 | v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER; |
218 | strcpy(v9ses->remotename, V9FS_DEFANAME); | 199 | strcpy(v9ses->uname, V9FS_DEFUSER); |
219 | 200 | strcpy(v9ses->aname, V9FS_DEFANAME); | |
220 | v9fs_parse_options(data, v9ses); | 201 | v9ses->uid = ~0; |
221 | 202 | v9ses->dfltuid = V9FS_DEFUID; | |
222 | switch (v9ses->proto) { | 203 | v9ses->dfltgid = V9FS_DEFGID; |
223 | case PROTO_TCP: | 204 | v9ses->options = kstrdup(data, GFP_KERNEL); |
224 | trans = p9_trans_create_tcp(dev_name, v9ses->port); | 205 | v9fs_parse_options(v9ses); |
225 | break; | 206 | |
226 | case PROTO_UNIX: | 207 | if (v9ses->trans == NULL) { |
227 | trans = p9_trans_create_unix(dev_name); | 208 | retval = -EPROTONOSUPPORT; |
228 | *v9ses->remotename = 0; | 209 | P9_DPRINTK(P9_DEBUG_ERROR, |
229 | break; | 210 | "No transport defined or default transport\n"); |
230 | case PROTO_FD: | ||
231 | trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno); | ||
232 | *v9ses->remotename = 0; | ||
233 | break; | ||
234 | #ifdef CONFIG_PCI_9P | ||
235 | case PROTO_PCI: | ||
236 | trans = p9pci_trans_create(); | ||
237 | *v9ses->remotename = 0; | ||
238 | break; | ||
239 | #endif | ||
240 | default: | ||
241 | printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); | ||
242 | retval = -ENOPROTOOPT; | ||
243 | goto error; | 211 | goto error; |
244 | }; | 212 | } |
245 | 213 | ||
214 | trans = v9ses->trans->create(dev_name, v9ses->options); | ||
246 | if (IS_ERR(trans)) { | 215 | if (IS_ERR(trans)) { |
247 | retval = PTR_ERR(trans); | 216 | retval = PTR_ERR(trans); |
248 | trans = NULL; | 217 | trans = NULL; |
249 | goto error; | 218 | goto error; |
250 | } | 219 | } |
220 | if ((v9ses->maxdata+P9_IOHDRSZ) > v9ses->trans->maxsize) | ||
221 | v9ses->maxdata = v9ses->trans->maxsize-P9_IOHDRSZ; | ||
251 | 222 | ||
252 | v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ, | 223 | v9ses->clnt = p9_client_create(trans, v9ses->maxdata+P9_IOHDRSZ, |
253 | v9ses->extended); | 224 | v9fs_extended(v9ses)); |
254 | 225 | ||
255 | if (IS_ERR(v9ses->clnt)) { | 226 | if (IS_ERR(v9ses->clnt)) { |
256 | retval = PTR_ERR(v9ses->clnt); | 227 | retval = PTR_ERR(v9ses->clnt); |
@@ -259,8 +230,20 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
259 | goto error; | 230 | goto error; |
260 | } | 231 | } |
261 | 232 | ||
262 | fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name, | 233 | if (!v9ses->clnt->dotu) |
263 | v9ses->remotename); | 234 | v9ses->flags &= ~V9FS_EXTENDED; |
235 | |||
236 | /* for legacy mode, fall back to V9FS_ACCESS_ANY */ | ||
237 | if (!v9fs_extended(v9ses) && | ||
238 | ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) { | ||
239 | |||
240 | v9ses->flags &= ~V9FS_ACCESS_MASK; | ||
241 | v9ses->flags |= V9FS_ACCESS_ANY; | ||
242 | v9ses->uid = ~0; | ||
243 | } | ||
244 | |||
245 | fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0, | ||
246 | v9ses->aname); | ||
264 | if (IS_ERR(fid)) { | 247 | if (IS_ERR(fid)) { |
265 | retval = PTR_ERR(fid); | 248 | retval = PTR_ERR(fid); |
266 | fid = NULL; | 249 | fid = NULL; |
@@ -268,6 +251,11 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
268 | goto error; | 251 | goto error; |
269 | } | 252 | } |
270 | 253 | ||
254 | if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE) | ||
255 | fid->uid = v9ses->uid; | ||
256 | else | ||
257 | fid->uid = ~0; | ||
258 | |||
271 | return fid; | 259 | return fid; |
272 | 260 | ||
273 | error: | 261 | error: |
@@ -288,8 +276,9 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
288 | v9ses->clnt = NULL; | 276 | v9ses->clnt = NULL; |
289 | } | 277 | } |
290 | 278 | ||
291 | __putname(v9ses->name); | 279 | __putname(v9ses->uname); |
292 | __putname(v9ses->remotename); | 280 | __putname(v9ses->aname); |
281 | kfree(v9ses->options); | ||
293 | } | 282 | } |
294 | 283 | ||
295 | /** | 284 | /** |
@@ -311,7 +300,7 @@ extern int v9fs_error_init(void); | |||
311 | static int __init init_v9fs(void) | 300 | static int __init init_v9fs(void) |
312 | { | 301 | { |
313 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); | 302 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); |
314 | 303 | /* TODO: Setup list of registered trasnport modules */ | |
315 | return register_filesystem(&v9fs_fs_type); | 304 | return register_filesystem(&v9fs_fs_type); |
316 | } | 305 | } |
317 | 306 | ||