aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@parallels.com>2010-09-27 06:02:29 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-09-27 10:16:12 -0400
commit90d51b02fd702d969eb05bd9d4ecc954759fbe23 (patch)
treefb5409d3ed5844be89a284097a930e1ff5ea37de /net/sunrpc
parent4f42d0d53ca4737f82937edb0efc83564c124853 (diff)
sunrpc: Make the ip_map_cache be per-net
Everything that is required for that already exists: * the per-net cache registration with respective proc entries * the context (struct net) is available in all the users Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/netns.h6
-rw-r--r--net/sunrpc/sunrpc_syms.c11
-rw-r--r--net/sunrpc/svcauth_unix.c122
3 files changed, 108 insertions, 31 deletions
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index e52ce897dde5..d013bf211cae 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -4,10 +4,16 @@
4#include <net/net_namespace.h> 4#include <net/net_namespace.h>
5#include <net/netns/generic.h> 5#include <net/netns/generic.h>
6 6
7struct cache_detail;
8
7struct sunrpc_net { 9struct sunrpc_net {
8 struct proc_dir_entry *proc_net_rpc; 10 struct proc_dir_entry *proc_net_rpc;
11 struct cache_detail *ip_map_cache;
9}; 12};
10 13
11extern int sunrpc_net_id; 14extern int sunrpc_net_id;
12 15
16int ip_map_cache_create(struct net *);
17void ip_map_cache_destroy(struct net *);
18
13#endif 19#endif
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index c076af8535db..9d0809160994 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -34,14 +34,21 @@ static __net_init int sunrpc_init_net(struct net *net)
34 if (err) 34 if (err)
35 goto err_proc; 35 goto err_proc;
36 36
37 err = ip_map_cache_create(net);
38 if (err)
39 goto err_ipmap;
40
37 return 0; 41 return 0;
38 42
43err_ipmap:
44 rpc_proc_exit(net);
39err_proc: 45err_proc:
40 return err; 46 return err;
41} 47}
42 48
43static __net_exit void sunrpc_exit_net(struct net *net) 49static __net_exit void sunrpc_exit_net(struct net *net)
44{ 50{
51 ip_map_cache_destroy(net);
45 rpc_proc_exit(net); 52 rpc_proc_exit(net);
46} 53}
47 54
@@ -52,7 +59,7 @@ static struct pernet_operations sunrpc_net_ops = {
52 .size = sizeof(struct sunrpc_net), 59 .size = sizeof(struct sunrpc_net),
53}; 60};
54 61
55extern struct cache_detail ip_map_cache, unix_gid_cache; 62extern struct cache_detail unix_gid_cache;
56 63
57extern void cleanup_rpcb_clnt(void); 64extern void cleanup_rpcb_clnt(void);
58 65
@@ -77,7 +84,6 @@ init_sunrpc(void)
77#ifdef RPC_DEBUG 84#ifdef RPC_DEBUG
78 rpc_register_sysctl(); 85 rpc_register_sysctl();
79#endif 86#endif
80 cache_register(&ip_map_cache);
81 cache_register(&unix_gid_cache); 87 cache_register(&unix_gid_cache);
82 svc_init_xprt_sock(); /* svc sock transport */ 88 svc_init_xprt_sock(); /* svc sock transport */
83 init_socket_xprt(); /* clnt sock transport */ 89 init_socket_xprt(); /* clnt sock transport */
@@ -102,7 +108,6 @@ cleanup_sunrpc(void)
102 svc_cleanup_xprt_sock(); 108 svc_cleanup_xprt_sock();
103 unregister_rpc_pipefs(); 109 unregister_rpc_pipefs();
104 rpc_destroy_mempool(); 110 rpc_destroy_mempool();
105 cache_unregister(&ip_map_cache);
106 cache_unregister(&unix_gid_cache); 111 cache_unregister(&unix_gid_cache);
107 unregister_pernet_subsys(&sunrpc_net_ops); 112 unregister_pernet_subsys(&sunrpc_net_ops);
108#ifdef RPC_DEBUG 113#ifdef RPC_DEBUG
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 2a76c7cf603e..8b378f91f255 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -18,6 +18,8 @@
18 18
19#include <linux/sunrpc/clnt.h> 19#include <linux/sunrpc/clnt.h>
20 20
21#include "netns.h"
22
21/* 23/*
22 * AUTHUNIX and AUTHNULL credentials are both handled here. 24 * AUTHUNIX and AUTHNULL credentials are both handled here.
23 * AUTHNULL is treated just like AUTHUNIX except that the uid/gid 25 * AUTHNULL is treated just like AUTHUNIX except that the uid/gid
@@ -92,7 +94,6 @@ struct ip_map {
92 struct unix_domain *m_client; 94 struct unix_domain *m_client;
93 int m_add_change; 95 int m_add_change;
94}; 96};
95static struct cache_head *ip_table[IP_HASHMAX];
96 97
97static void ip_map_put(struct kref *kref) 98static void ip_map_put(struct kref *kref)
98{ 99{
@@ -294,21 +295,6 @@ static int ip_map_show(struct seq_file *m,
294} 295}
295 296
296 297
297struct cache_detail ip_map_cache = {
298 .owner = THIS_MODULE,
299 .hash_size = IP_HASHMAX,
300 .hash_table = ip_table,
301 .name = "auth.unix.ip",
302 .cache_put = ip_map_put,
303 .cache_upcall = ip_map_upcall,
304 .cache_parse = ip_map_parse,
305 .cache_show = ip_map_show,
306 .match = ip_map_match,
307 .init = ip_map_init,
308 .update = update,
309 .alloc = ip_map_alloc,
310};
311
312static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, 298static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
313 struct in6_addr *addr) 299 struct in6_addr *addr)
314{ 300{
@@ -330,7 +316,10 @@ static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
330static inline struct ip_map *ip_map_lookup(struct net *net, char *class, 316static inline struct ip_map *ip_map_lookup(struct net *net, char *class,
331 struct in6_addr *addr) 317 struct in6_addr *addr)
332{ 318{
333 return __ip_map_lookup(&ip_map_cache, class, addr); 319 struct sunrpc_net *sn;
320
321 sn = net_generic(net, sunrpc_net_id);
322 return __ip_map_lookup(sn->ip_map_cache, class, addr);
334} 323}
335 324
336static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, 325static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
@@ -364,7 +353,10 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
364static inline int ip_map_update(struct net *net, struct ip_map *ipm, 353static inline int ip_map_update(struct net *net, struct ip_map *ipm,
365 struct unix_domain *udom, time_t expiry) 354 struct unix_domain *udom, time_t expiry)
366{ 355{
367 return __ip_map_update(&ip_map_cache, ipm, udom, expiry); 356 struct sunrpc_net *sn;
357
358 sn = net_generic(net, sunrpc_net_id);
359 return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry);
368} 360}
369 361
370int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) 362int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom)
@@ -400,12 +392,14 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
400{ 392{
401 struct ip_map *ipm; 393 struct ip_map *ipm;
402 struct auth_domain *rv; 394 struct auth_domain *rv;
395 struct sunrpc_net *sn;
403 396
397 sn = net_generic(net, sunrpc_net_id);
404 ipm = ip_map_lookup(net, "nfsd", addr); 398 ipm = ip_map_lookup(net, "nfsd", addr);
405 399
406 if (!ipm) 400 if (!ipm)
407 return NULL; 401 return NULL;
408 if (cache_check(&ip_map_cache, &ipm->h, NULL)) 402 if (cache_check(sn->ip_map_cache, &ipm->h, NULL))
409 return NULL; 403 return NULL;
410 404
411 if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { 405 if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) {
@@ -416,14 +410,21 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
416 rv = &ipm->m_client->h; 410 rv = &ipm->m_client->h;
417 kref_get(&rv->ref); 411 kref_get(&rv->ref);
418 } 412 }
419 cache_put(&ipm->h, &ip_map_cache); 413 cache_put(&ipm->h, sn->ip_map_cache);
420 return rv; 414 return rv;
421} 415}
422EXPORT_SYMBOL_GPL(auth_unix_lookup); 416EXPORT_SYMBOL_GPL(auth_unix_lookup);
423 417
424void svcauth_unix_purge(void) 418void svcauth_unix_purge(void)
425{ 419{
426 cache_purge(&ip_map_cache); 420 struct net *net;
421
422 for_each_net(net) {
423 struct sunrpc_net *sn;
424
425 sn = net_generic(net, sunrpc_net_id);
426 cache_purge(sn->ip_map_cache);
427 }
427} 428}
428EXPORT_SYMBOL_GPL(svcauth_unix_purge); 429EXPORT_SYMBOL_GPL(svcauth_unix_purge);
429 430
@@ -431,6 +432,7 @@ static inline struct ip_map *
431ip_map_cached_get(struct svc_xprt *xprt) 432ip_map_cached_get(struct svc_xprt *xprt)
432{ 433{
433 struct ip_map *ipm = NULL; 434 struct ip_map *ipm = NULL;
435 struct sunrpc_net *sn;
434 436
435 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { 437 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) {
436 spin_lock(&xprt->xpt_lock); 438 spin_lock(&xprt->xpt_lock);
@@ -442,9 +444,10 @@ ip_map_cached_get(struct svc_xprt *xprt)
442 * remembered, e.g. by a second mount from the 444 * remembered, e.g. by a second mount from the
443 * same IP address. 445 * same IP address.
444 */ 446 */
447 sn = net_generic(xprt->xpt_net, sunrpc_net_id);
445 xprt->xpt_auth_cache = NULL; 448 xprt->xpt_auth_cache = NULL;
446 spin_unlock(&xprt->xpt_lock); 449 spin_unlock(&xprt->xpt_lock);
447 cache_put(&ipm->h, &ip_map_cache); 450 cache_put(&ipm->h, sn->ip_map_cache);
448 return NULL; 451 return NULL;
449 } 452 }
450 cache_get(&ipm->h); 453 cache_get(&ipm->h);
@@ -466,8 +469,12 @@ ip_map_cached_put(struct svc_xprt *xprt, struct ip_map *ipm)
466 } 469 }
467 spin_unlock(&xprt->xpt_lock); 470 spin_unlock(&xprt->xpt_lock);
468 } 471 }
469 if (ipm) 472 if (ipm) {
470 cache_put(&ipm->h, &ip_map_cache); 473 struct sunrpc_net *sn;
474
475 sn = net_generic(xprt->xpt_net, sunrpc_net_id);
476 cache_put(&ipm->h, sn->ip_map_cache);
477 }
471} 478}
472 479
473void 480void
@@ -476,8 +483,12 @@ svcauth_unix_info_release(struct svc_xprt *xpt)
476 struct ip_map *ipm; 483 struct ip_map *ipm;
477 484
478 ipm = xpt->xpt_auth_cache; 485 ipm = xpt->xpt_auth_cache;
479 if (ipm != NULL) 486 if (ipm != NULL) {
480 cache_put(&ipm->h, &ip_map_cache); 487 struct sunrpc_net *sn;
488
489 sn = net_generic(xpt->xpt_net, sunrpc_net_id);
490 cache_put(&ipm->h, sn->ip_map_cache);
491 }
481} 492}
482 493
483/**************************************************************************** 494/****************************************************************************
@@ -707,6 +718,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
707 struct group_info *gi; 718 struct group_info *gi;
708 struct svc_cred *cred = &rqstp->rq_cred; 719 struct svc_cred *cred = &rqstp->rq_cred;
709 struct svc_xprt *xprt = rqstp->rq_xprt; 720 struct svc_xprt *xprt = rqstp->rq_xprt;
721 struct net *net = xprt->xpt_net;
722 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
710 723
711 switch (rqstp->rq_addr.ss_family) { 724 switch (rqstp->rq_addr.ss_family) {
712 case AF_INET: 725 case AF_INET:
@@ -727,13 +740,13 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
727 740
728 ipm = ip_map_cached_get(xprt); 741 ipm = ip_map_cached_get(xprt);
729 if (ipm == NULL) 742 if (ipm == NULL)
730 ipm = ip_map_lookup(&init_net, rqstp->rq_server->sv_program->pg_class, 743 ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class,
731 &sin6->sin6_addr); 744 &sin6->sin6_addr);
732 745
733 if (ipm == NULL) 746 if (ipm == NULL)
734 return SVC_DENIED; 747 return SVC_DENIED;
735 748
736 switch (cache_check(&ip_map_cache, &ipm->h, &rqstp->rq_chandle)) { 749 switch (cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
737 default: 750 default:
738 BUG(); 751 BUG();
739 case -ETIMEDOUT: 752 case -ETIMEDOUT:
@@ -905,3 +918,56 @@ struct auth_ops svcauth_unix = {
905 .set_client = svcauth_unix_set_client, 918 .set_client = svcauth_unix_set_client,
906}; 919};
907 920
921int ip_map_cache_create(struct net *net)
922{
923 int err = -ENOMEM;
924 struct cache_detail *cd;
925 struct cache_head **tbl;
926 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
927
928 cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL);
929 if (cd == NULL)
930 goto err_cd;
931
932 tbl = kzalloc(IP_HASHMAX * sizeof(struct cache_head *), GFP_KERNEL);
933 if (tbl == NULL)
934 goto err_tbl;
935
936 cd->owner = THIS_MODULE,
937 cd->hash_size = IP_HASHMAX,
938 cd->hash_table = tbl,
939 cd->name = "auth.unix.ip",
940 cd->cache_put = ip_map_put,
941 cd->cache_upcall = ip_map_upcall,
942 cd->cache_parse = ip_map_parse,
943 cd->cache_show = ip_map_show,
944 cd->match = ip_map_match,
945 cd->init = ip_map_init,
946 cd->update = update,
947 cd->alloc = ip_map_alloc,
948
949 err = cache_register_net(cd, net);
950 if (err)
951 goto err_reg;
952
953 sn->ip_map_cache = cd;
954 return 0;
955
956err_reg:
957 kfree(tbl);
958err_tbl:
959 kfree(cd);
960err_cd:
961 return err;
962}
963
964void ip_map_cache_destroy(struct net *net)
965{
966 struct sunrpc_net *sn;
967
968 sn = net_generic(net, sunrpc_net_id);
969 cache_purge(sn->ip_map_cache);
970 cache_unregister_net(sn->ip_map_cache, net);
971 kfree(sn->ip_map_cache->hash_table);
972 kfree(sn->ip_map_cache);
973}