diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-01-19 12:42:29 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-31 19:28:15 -0500 |
commit | 73393232d6a425b6bb4cee590e3e66fc52532a15 (patch) | |
tree | e0df6bd41e665a307856b29c216473969fe88575 /net/sunrpc | |
parent | 0a402d5a653ee2b613aaba3092a87b1e964622ce (diff) |
SUNRPC: create unix gid cache per network namespace
v2:
1) fixed silly usage of template cache as a real one (this code left from
static global cache for all)
This patch makes unix_gid_cache cache detail allocated and registered per
network namespace context.
Thus with this patch unix_gid_cache contents for network namespace "X" are
controlled from proc file system mount for the same network namespace "X".
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Acked-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/netns.h | 1 | ||||
-rw-r--r-- | net/sunrpc/sunrpc_syms.c | 14 | ||||
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 55 |
3 files changed, 52 insertions, 18 deletions
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h index 1fdeb1ba84bd..309f88ddb060 100644 --- a/net/sunrpc/netns.h +++ b/net/sunrpc/netns.h | |||
@@ -9,6 +9,7 @@ struct cache_detail; | |||
9 | struct sunrpc_net { | 9 | struct sunrpc_net { |
10 | struct proc_dir_entry *proc_net_rpc; | 10 | struct proc_dir_entry *proc_net_rpc; |
11 | struct cache_detail *ip_map_cache; | 11 | struct cache_detail *ip_map_cache; |
12 | struct cache_detail *unix_gid_cache; | ||
12 | 13 | ||
13 | struct super_block *pipefs_sb; | 14 | struct super_block *pipefs_sb; |
14 | struct mutex pipefs_sb_lock; | 15 | struct mutex pipefs_sb_lock; |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index b4217dc8599c..38a72a1b465b 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
@@ -26,6 +26,9 @@ | |||
26 | 26 | ||
27 | int sunrpc_net_id; | 27 | int sunrpc_net_id; |
28 | 28 | ||
29 | extern int unix_gid_cache_create(struct net *net); | ||
30 | extern int unix_gid_cache_destroy(struct net *net); | ||
31 | |||
29 | static __net_init int sunrpc_init_net(struct net *net) | 32 | static __net_init int sunrpc_init_net(struct net *net) |
30 | { | 33 | { |
31 | int err; | 34 | int err; |
@@ -39,11 +42,17 @@ static __net_init int sunrpc_init_net(struct net *net) | |||
39 | if (err) | 42 | if (err) |
40 | goto err_ipmap; | 43 | goto err_ipmap; |
41 | 44 | ||
45 | err = unix_gid_cache_create(net); | ||
46 | if (err) | ||
47 | goto err_unixgid; | ||
48 | |||
42 | rpc_pipefs_init_net(net); | 49 | rpc_pipefs_init_net(net); |
43 | INIT_LIST_HEAD(&sn->all_clients); | 50 | INIT_LIST_HEAD(&sn->all_clients); |
44 | spin_lock_init(&sn->rpc_client_lock); | 51 | spin_lock_init(&sn->rpc_client_lock); |
45 | return 0; | 52 | return 0; |
46 | 53 | ||
54 | err_unixgid: | ||
55 | ip_map_cache_destroy(net); | ||
47 | err_ipmap: | 56 | err_ipmap: |
48 | rpc_proc_exit(net); | 57 | rpc_proc_exit(net); |
49 | err_proc: | 58 | err_proc: |
@@ -52,6 +61,7 @@ err_proc: | |||
52 | 61 | ||
53 | static __net_exit void sunrpc_exit_net(struct net *net) | 62 | static __net_exit void sunrpc_exit_net(struct net *net) |
54 | { | 63 | { |
64 | unix_gid_cache_destroy(net); | ||
55 | ip_map_cache_destroy(net); | 65 | ip_map_cache_destroy(net); |
56 | rpc_proc_exit(net); | 66 | rpc_proc_exit(net); |
57 | } | 67 | } |
@@ -63,8 +73,6 @@ static struct pernet_operations sunrpc_net_ops = { | |||
63 | .size = sizeof(struct sunrpc_net), | 73 | .size = sizeof(struct sunrpc_net), |
64 | }; | 74 | }; |
65 | 75 | ||
66 | extern struct cache_detail unix_gid_cache; | ||
67 | |||
68 | static int __init | 76 | static int __init |
69 | init_sunrpc(void) | 77 | init_sunrpc(void) |
70 | { | 78 | { |
@@ -86,7 +94,6 @@ init_sunrpc(void) | |||
86 | #ifdef RPC_DEBUG | 94 | #ifdef RPC_DEBUG |
87 | rpc_register_sysctl(); | 95 | rpc_register_sysctl(); |
88 | #endif | 96 | #endif |
89 | cache_register(&unix_gid_cache); | ||
90 | svc_init_xprt_sock(); /* svc sock transport */ | 97 | svc_init_xprt_sock(); /* svc sock transport */ |
91 | init_socket_xprt(); /* clnt sock transport */ | 98 | init_socket_xprt(); /* clnt sock transport */ |
92 | return 0; | 99 | return 0; |
@@ -109,7 +116,6 @@ cleanup_sunrpc(void) | |||
109 | svc_cleanup_xprt_sock(); | 116 | svc_cleanup_xprt_sock(); |
110 | unregister_rpc_pipefs(); | 117 | unregister_rpc_pipefs(); |
111 | rpc_destroy_mempool(); | 118 | rpc_destroy_mempool(); |
112 | cache_unregister(&unix_gid_cache); | ||
113 | unregister_pernet_subsys(&sunrpc_net_ops); | 119 | unregister_pernet_subsys(&sunrpc_net_ops); |
114 | #ifdef RPC_DEBUG | 120 | #ifdef RPC_DEBUG |
115 | rpc_unregister_sysctl(); | 121 | rpc_unregister_sysctl(); |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 2f8c426c1384..a6eef38fb35c 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -436,7 +436,6 @@ struct unix_gid { | |||
436 | uid_t uid; | 436 | uid_t uid; |
437 | struct group_info *gi; | 437 | struct group_info *gi; |
438 | }; | 438 | }; |
439 | static struct cache_head *gid_table[GID_HASHMAX]; | ||
440 | 439 | ||
441 | static void unix_gid_put(struct kref *kref) | 440 | static void unix_gid_put(struct kref *kref) |
442 | { | 441 | { |
@@ -494,8 +493,7 @@ static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h) | |||
494 | return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); | 493 | return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); |
495 | } | 494 | } |
496 | 495 | ||
497 | static struct unix_gid *unix_gid_lookup(uid_t uid); | 496 | static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid); |
498 | extern struct cache_detail unix_gid_cache; | ||
499 | 497 | ||
500 | static int unix_gid_parse(struct cache_detail *cd, | 498 | static int unix_gid_parse(struct cache_detail *cd, |
501 | char *mesg, int mlen) | 499 | char *mesg, int mlen) |
@@ -539,19 +537,19 @@ static int unix_gid_parse(struct cache_detail *cd, | |||
539 | GROUP_AT(ug.gi, i) = gid; | 537 | GROUP_AT(ug.gi, i) = gid; |
540 | } | 538 | } |
541 | 539 | ||
542 | ugp = unix_gid_lookup(uid); | 540 | ugp = unix_gid_lookup(cd, uid); |
543 | if (ugp) { | 541 | if (ugp) { |
544 | struct cache_head *ch; | 542 | struct cache_head *ch; |
545 | ug.h.flags = 0; | 543 | ug.h.flags = 0; |
546 | ug.h.expiry_time = expiry; | 544 | ug.h.expiry_time = expiry; |
547 | ch = sunrpc_cache_update(&unix_gid_cache, | 545 | ch = sunrpc_cache_update(cd, |
548 | &ug.h, &ugp->h, | 546 | &ug.h, &ugp->h, |
549 | hash_long(uid, GID_HASHBITS)); | 547 | hash_long(uid, GID_HASHBITS)); |
550 | if (!ch) | 548 | if (!ch) |
551 | err = -ENOMEM; | 549 | err = -ENOMEM; |
552 | else { | 550 | else { |
553 | err = 0; | 551 | err = 0; |
554 | cache_put(ch, &unix_gid_cache); | 552 | cache_put(ch, cd); |
555 | } | 553 | } |
556 | } else | 554 | } else |
557 | err = -ENOMEM; | 555 | err = -ENOMEM; |
@@ -587,10 +585,9 @@ static int unix_gid_show(struct seq_file *m, | |||
587 | return 0; | 585 | return 0; |
588 | } | 586 | } |
589 | 587 | ||
590 | struct cache_detail unix_gid_cache = { | 588 | static struct cache_detail unix_gid_cache_template = { |
591 | .owner = THIS_MODULE, | 589 | .owner = THIS_MODULE, |
592 | .hash_size = GID_HASHMAX, | 590 | .hash_size = GID_HASHMAX, |
593 | .hash_table = gid_table, | ||
594 | .name = "auth.unix.gid", | 591 | .name = "auth.unix.gid", |
595 | .cache_put = unix_gid_put, | 592 | .cache_put = unix_gid_put, |
596 | .cache_upcall = unix_gid_upcall, | 593 | .cache_upcall = unix_gid_upcall, |
@@ -602,14 +599,42 @@ struct cache_detail unix_gid_cache = { | |||
602 | .alloc = unix_gid_alloc, | 599 | .alloc = unix_gid_alloc, |
603 | }; | 600 | }; |
604 | 601 | ||
605 | static struct unix_gid *unix_gid_lookup(uid_t uid) | 602 | int unix_gid_cache_create(struct net *net) |
603 | { | ||
604 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
605 | struct cache_detail *cd; | ||
606 | int err; | ||
607 | |||
608 | cd = cache_create_net(&unix_gid_cache_template, net); | ||
609 | if (IS_ERR(cd)) | ||
610 | return PTR_ERR(cd); | ||
611 | err = cache_register_net(cd, net); | ||
612 | if (err) { | ||
613 | cache_destroy_net(cd, net); | ||
614 | return err; | ||
615 | } | ||
616 | sn->unix_gid_cache = cd; | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | void unix_gid_cache_destroy(struct net *net) | ||
621 | { | ||
622 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
623 | struct cache_detail *cd = sn->unix_gid_cache; | ||
624 | |||
625 | sn->unix_gid_cache = NULL; | ||
626 | cache_purge(cd); | ||
627 | cache_unregister_net(cd, net); | ||
628 | cache_destroy_net(cd, net); | ||
629 | } | ||
630 | |||
631 | static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid) | ||
606 | { | 632 | { |
607 | struct unix_gid ug; | 633 | struct unix_gid ug; |
608 | struct cache_head *ch; | 634 | struct cache_head *ch; |
609 | 635 | ||
610 | ug.uid = uid; | 636 | ug.uid = uid; |
611 | ch = sunrpc_cache_lookup(&unix_gid_cache, &ug.h, | 637 | ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS)); |
612 | hash_long(uid, GID_HASHBITS)); | ||
613 | if (ch) | 638 | if (ch) |
614 | return container_of(ch, struct unix_gid, h); | 639 | return container_of(ch, struct unix_gid, h); |
615 | else | 640 | else |
@@ -621,11 +646,13 @@ static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) | |||
621 | struct unix_gid *ug; | 646 | struct unix_gid *ug; |
622 | struct group_info *gi; | 647 | struct group_info *gi; |
623 | int ret; | 648 | int ret; |
649 | struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, | ||
650 | sunrpc_net_id); | ||
624 | 651 | ||
625 | ug = unix_gid_lookup(uid); | 652 | ug = unix_gid_lookup(sn->unix_gid_cache, uid); |
626 | if (!ug) | 653 | if (!ug) |
627 | return ERR_PTR(-EAGAIN); | 654 | return ERR_PTR(-EAGAIN); |
628 | ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle); | 655 | ret = cache_check(sn->unix_gid_cache, &ug->h, &rqstp->rq_chandle); |
629 | switch (ret) { | 656 | switch (ret) { |
630 | case -ENOENT: | 657 | case -ENOENT: |
631 | return ERR_PTR(-ENOENT); | 658 | return ERR_PTR(-ENOENT); |
@@ -633,7 +660,7 @@ static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) | |||
633 | return ERR_PTR(-ESHUTDOWN); | 660 | return ERR_PTR(-ESHUTDOWN); |
634 | case 0: | 661 | case 0: |
635 | gi = get_group_info(ug->gi); | 662 | gi = get_group_info(ug->gi); |
636 | cache_put(&ug->h, &unix_gid_cache); | 663 | cache_put(&ug->h, sn->unix_gid_cache); |
637 | return gi; | 664 | return gi; |
638 | default: | 665 | default: |
639 | return ERR_PTR(-EAGAIN); | 666 | return ERR_PTR(-EAGAIN); |