diff options
Diffstat (limited to 'fs/9p/v9fs.c')
-rw-r--r-- | fs/9p/v9fs.c | 108 |
1 files changed, 90 insertions, 18 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 2f77cd33ba8..c82b017f51f 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -39,6 +39,7 @@ | |||
39 | 39 | ||
40 | static DEFINE_SPINLOCK(v9fs_sessionlist_lock); | 40 | static DEFINE_SPINLOCK(v9fs_sessionlist_lock); |
41 | static LIST_HEAD(v9fs_sessionlist); | 41 | static LIST_HEAD(v9fs_sessionlist); |
42 | struct kmem_cache *v9fs_inode_cache; | ||
42 | 43 | ||
43 | /* | 44 | /* |
44 | * Option Parsing (code inspired by NFS code) | 45 | * Option Parsing (code inspired by NFS code) |
@@ -55,7 +56,7 @@ enum { | |||
55 | /* Cache options */ | 56 | /* Cache options */ |
56 | Opt_cache_loose, Opt_fscache, | 57 | Opt_cache_loose, Opt_fscache, |
57 | /* Access options */ | 58 | /* Access options */ |
58 | Opt_access, | 59 | Opt_access, Opt_posixacl, |
59 | /* Error token */ | 60 | /* Error token */ |
60 | Opt_err | 61 | Opt_err |
61 | }; | 62 | }; |
@@ -73,6 +74,7 @@ static const match_table_t tokens = { | |||
73 | {Opt_fscache, "fscache"}, | 74 | {Opt_fscache, "fscache"}, |
74 | {Opt_cachetag, "cachetag=%s"}, | 75 | {Opt_cachetag, "cachetag=%s"}, |
75 | {Opt_access, "access=%s"}, | 76 | {Opt_access, "access=%s"}, |
77 | {Opt_posixacl, "posixacl"}, | ||
76 | {Opt_err, NULL} | 78 | {Opt_err, NULL} |
77 | }; | 79 | }; |
78 | 80 | ||
@@ -194,15 +196,7 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
194 | else if (strcmp(s, "any") == 0) | 196 | else if (strcmp(s, "any") == 0) |
195 | v9ses->flags |= V9FS_ACCESS_ANY; | 197 | v9ses->flags |= V9FS_ACCESS_ANY; |
196 | else if (strcmp(s, "client") == 0) { | 198 | else if (strcmp(s, "client") == 0) { |
197 | #ifdef CONFIG_9P_FS_POSIX_ACL | ||
198 | v9ses->flags |= V9FS_ACCESS_CLIENT; | 199 | v9ses->flags |= V9FS_ACCESS_CLIENT; |
199 | #else | ||
200 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
201 | "access=client option not supported\n"); | ||
202 | kfree(s); | ||
203 | ret = -EINVAL; | ||
204 | goto free_and_return; | ||
205 | #endif | ||
206 | } else { | 200 | } else { |
207 | v9ses->flags |= V9FS_ACCESS_SINGLE; | 201 | v9ses->flags |= V9FS_ACCESS_SINGLE; |
208 | v9ses->uid = simple_strtoul(s, &e, 10); | 202 | v9ses->uid = simple_strtoul(s, &e, 10); |
@@ -212,6 +206,16 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts) | |||
212 | kfree(s); | 206 | kfree(s); |
213 | break; | 207 | break; |
214 | 208 | ||
209 | case Opt_posixacl: | ||
210 | #ifdef CONFIG_9P_FS_POSIX_ACL | ||
211 | v9ses->flags |= V9FS_POSIX_ACL; | ||
212 | #else | ||
213 | P9_DPRINTK(P9_DEBUG_ERROR, | ||
214 | "Not defined CONFIG_9P_FS_POSIX_ACL. " | ||
215 | "Ignoring posixacl option\n"); | ||
216 | #endif | ||
217 | break; | ||
218 | |||
215 | default: | 219 | default: |
216 | continue; | 220 | continue; |
217 | } | 221 | } |
@@ -260,19 +264,12 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
260 | list_add(&v9ses->slist, &v9fs_sessionlist); | 264 | list_add(&v9ses->slist, &v9fs_sessionlist); |
261 | spin_unlock(&v9fs_sessionlist_lock); | 265 | spin_unlock(&v9fs_sessionlist_lock); |
262 | 266 | ||
263 | v9ses->flags = V9FS_ACCESS_USER; | ||
264 | strcpy(v9ses->uname, V9FS_DEFUSER); | 267 | strcpy(v9ses->uname, V9FS_DEFUSER); |
265 | strcpy(v9ses->aname, V9FS_DEFANAME); | 268 | strcpy(v9ses->aname, V9FS_DEFANAME); |
266 | v9ses->uid = ~0; | 269 | v9ses->uid = ~0; |
267 | v9ses->dfltuid = V9FS_DEFUID; | 270 | v9ses->dfltuid = V9FS_DEFUID; |
268 | v9ses->dfltgid = V9FS_DEFGID; | 271 | v9ses->dfltgid = V9FS_DEFGID; |
269 | 272 | ||
270 | rc = v9fs_parse_options(v9ses, data); | ||
271 | if (rc < 0) { | ||
272 | retval = rc; | ||
273 | goto error; | ||
274 | } | ||
275 | |||
276 | v9ses->clnt = p9_client_create(dev_name, data); | 273 | v9ses->clnt = p9_client_create(dev_name, data); |
277 | if (IS_ERR(v9ses->clnt)) { | 274 | if (IS_ERR(v9ses->clnt)) { |
278 | retval = PTR_ERR(v9ses->clnt); | 275 | retval = PTR_ERR(v9ses->clnt); |
@@ -281,10 +278,20 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
281 | goto error; | 278 | goto error; |
282 | } | 279 | } |
283 | 280 | ||
284 | if (p9_is_proto_dotl(v9ses->clnt)) | 281 | v9ses->flags = V9FS_ACCESS_USER; |
282 | |||
283 | if (p9_is_proto_dotl(v9ses->clnt)) { | ||
284 | v9ses->flags = V9FS_ACCESS_CLIENT; | ||
285 | v9ses->flags |= V9FS_PROTO_2000L; | 285 | v9ses->flags |= V9FS_PROTO_2000L; |
286 | else if (p9_is_proto_dotu(v9ses->clnt)) | 286 | } else if (p9_is_proto_dotu(v9ses->clnt)) { |
287 | v9ses->flags |= V9FS_PROTO_2000U; | 287 | v9ses->flags |= V9FS_PROTO_2000U; |
288 | } | ||
289 | |||
290 | rc = v9fs_parse_options(v9ses, data); | ||
291 | if (rc < 0) { | ||
292 | retval = rc; | ||
293 | goto error; | ||
294 | } | ||
288 | 295 | ||
289 | v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; | 296 | v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ; |
290 | 297 | ||
@@ -306,6 +313,14 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
306 | v9ses->flags |= V9FS_ACCESS_ANY; | 313 | v9ses->flags |= V9FS_ACCESS_ANY; |
307 | v9ses->uid = ~0; | 314 | v9ses->uid = ~0; |
308 | } | 315 | } |
316 | if (!v9fs_proto_dotl(v9ses) || | ||
317 | !((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) { | ||
318 | /* | ||
319 | * We support ACL checks on clinet only if the protocol is | ||
320 | * 9P2000.L and access is V9FS_ACCESS_CLIENT. | ||
321 | */ | ||
322 | v9ses->flags &= ~V9FS_ACL_MASK; | ||
323 | } | ||
309 | 324 | ||
310 | fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0, | 325 | fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0, |
311 | v9ses->aname); | 326 | v9ses->aname); |
@@ -467,6 +482,63 @@ static void v9fs_sysfs_cleanup(void) | |||
467 | kobject_put(v9fs_kobj); | 482 | kobject_put(v9fs_kobj); |
468 | } | 483 | } |
469 | 484 | ||
485 | static void v9fs_inode_init_once(void *foo) | ||
486 | { | ||
487 | struct v9fs_inode *v9inode = (struct v9fs_inode *)foo; | ||
488 | #ifdef CONFIG_9P_FSCACHE | ||
489 | v9inode->fscache = NULL; | ||
490 | v9inode->fscache_key = NULL; | ||
491 | #endif | ||
492 | inode_init_once(&v9inode->vfs_inode); | ||
493 | } | ||
494 | |||
495 | /** | ||
496 | * v9fs_init_inode_cache - initialize a cache for 9P | ||
497 | * Returns 0 on success. | ||
498 | */ | ||
499 | static int v9fs_init_inode_cache(void) | ||
500 | { | ||
501 | v9fs_inode_cache = kmem_cache_create("v9fs_inode_cache", | ||
502 | sizeof(struct v9fs_inode), | ||
503 | 0, (SLAB_RECLAIM_ACCOUNT| | ||
504 | SLAB_MEM_SPREAD), | ||
505 | v9fs_inode_init_once); | ||
506 | if (!v9fs_inode_cache) | ||
507 | return -ENOMEM; | ||
508 | |||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | /** | ||
513 | * v9fs_destroy_inode_cache - destroy the cache of 9P inode | ||
514 | * | ||
515 | */ | ||
516 | static void v9fs_destroy_inode_cache(void) | ||
517 | { | ||
518 | kmem_cache_destroy(v9fs_inode_cache); | ||
519 | } | ||
520 | |||
521 | static int v9fs_cache_register(void) | ||
522 | { | ||
523 | int ret; | ||
524 | ret = v9fs_init_inode_cache(); | ||
525 | if (ret < 0) | ||
526 | return ret; | ||
527 | #ifdef CONFIG_9P_FSCACHE | ||
528 | return fscache_register_netfs(&v9fs_cache_netfs); | ||
529 | #else | ||
530 | return ret; | ||
531 | #endif | ||
532 | } | ||
533 | |||
534 | static void v9fs_cache_unregister(void) | ||
535 | { | ||
536 | v9fs_destroy_inode_cache(); | ||
537 | #ifdef CONFIG_9P_FSCACHE | ||
538 | fscache_unregister_netfs(&v9fs_cache_netfs); | ||
539 | #endif | ||
540 | } | ||
541 | |||
470 | /** | 542 | /** |
471 | * init_v9fs - Initialize module | 543 | * init_v9fs - Initialize module |
472 | * | 544 | * |