aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-01-13 03:52:10 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-01-31 19:28:09 -0500
commitdff02d499c067bdde589b764321b35fe763569f6 (patch)
treea0a9c1259f7dad55c5ad2be8ae6d33a8417d64fb
parent961a828df64979d2a9faeeeee043391670a193b9 (diff)
SUNRPC: move rpcbind internals to sunrpc part of network namespace context
This patch makes rpcbind logic works in network namespace context. IOW each network namespace will have it's own unique rpcbind internals (clients and friends) required for registering svc services per network namespace. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--net/sunrpc/netns.h5
-rw-r--r--net/sunrpc/rpcb_clnt.c64
2 files changed, 40 insertions, 29 deletions
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 0f3af34fa502..1fdeb1ba84bd 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -15,6 +15,11 @@ struct sunrpc_net {
15 15
16 struct list_head all_clients; 16 struct list_head all_clients;
17 spinlock_t rpc_client_lock; 17 spinlock_t rpc_client_lock;
18
19 struct rpc_clnt *rpcb_local_clnt;
20 struct rpc_clnt *rpcb_local_clnt4;
21 spinlock_t rpcb_clnt_lock;
22 unsigned int rpcb_users;
18}; 23};
19 24
20extern int sunrpc_net_id; 25extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 8761bf8e36fc..7d32f19ba868 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -23,12 +23,15 @@
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/nsproxy.h>
26#include <net/ipv6.h> 27#include <net/ipv6.h>
27 28
28#include <linux/sunrpc/clnt.h> 29#include <linux/sunrpc/clnt.h>
29#include <linux/sunrpc/sched.h> 30#include <linux/sunrpc/sched.h>
30#include <linux/sunrpc/xprtsock.h> 31#include <linux/sunrpc/xprtsock.h>
31 32
33#include "netns.h"
34
32#ifdef RPC_DEBUG 35#ifdef RPC_DEBUG
33# define RPCDBG_FACILITY RPCDBG_BIND 36# define RPCDBG_FACILITY RPCDBG_BIND
34#endif 37#endif
@@ -111,12 +114,6 @@ static void rpcb_getport_done(struct rpc_task *, void *);
111static void rpcb_map_release(void *data); 114static void rpcb_map_release(void *data);
112static struct rpc_program rpcb_program; 115static struct rpc_program rpcb_program;
113 116
114static struct rpc_clnt * rpcb_local_clnt;
115static struct rpc_clnt * rpcb_local_clnt4;
116
117DEFINE_SPINLOCK(rpcb_clnt_lock);
118unsigned int rpcb_users;
119
120struct rpcbind_args { 117struct rpcbind_args {
121 struct rpc_xprt * r_xprt; 118 struct rpc_xprt * r_xprt;
122 119
@@ -167,29 +164,31 @@ static void rpcb_map_release(void *data)
167static int rpcb_get_local(void) 164static int rpcb_get_local(void)
168{ 165{
169 int cnt; 166 int cnt;
167 struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
170 168
171 spin_lock(&rpcb_clnt_lock); 169 spin_lock(&sn->rpcb_clnt_lock);
172 if (rpcb_users) 170 if (sn->rpcb_users)
173 rpcb_users++; 171 sn->rpcb_users++;
174 cnt = rpcb_users; 172 cnt = sn->rpcb_users;
175 spin_unlock(&rpcb_clnt_lock); 173 spin_unlock(&sn->rpcb_clnt_lock);
176 174
177 return cnt; 175 return cnt;
178} 176}
179 177
180void rpcb_put_local(void) 178void rpcb_put_local(void)
181{ 179{
182 struct rpc_clnt *clnt = rpcb_local_clnt; 180 struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
183 struct rpc_clnt *clnt4 = rpcb_local_clnt4; 181 struct rpc_clnt *clnt = sn->rpcb_local_clnt;
182 struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
184 int shutdown; 183 int shutdown;
185 184
186 spin_lock(&rpcb_clnt_lock); 185 spin_lock(&sn->rpcb_clnt_lock);
187 if (--rpcb_users == 0) { 186 if (--sn->rpcb_users == 0) {
188 rpcb_local_clnt = NULL; 187 sn->rpcb_local_clnt = NULL;
189 rpcb_local_clnt4 = NULL; 188 sn->rpcb_local_clnt4 = NULL;
190 } 189 }
191 shutdown = !rpcb_users; 190 shutdown = !sn->rpcb_users;
192 spin_unlock(&rpcb_clnt_lock); 191 spin_unlock(&sn->rpcb_clnt_lock);
193 192
194 if (shutdown) { 193 if (shutdown) {
195 /* 194 /*
@@ -204,14 +203,16 @@ void rpcb_put_local(void)
204 203
205static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4) 204static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
206{ 205{
206 struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
207
207 /* Protected by rpcb_create_local_mutex */ 208 /* Protected by rpcb_create_local_mutex */
208 rpcb_local_clnt = clnt; 209 sn->rpcb_local_clnt = clnt;
209 rpcb_local_clnt4 = clnt4; 210 sn->rpcb_local_clnt4 = clnt4;
210 smp_wmb(); 211 smp_wmb();
211 rpcb_users = 1; 212 sn->rpcb_users = 1;
212 dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: " 213 dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
213 "%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt, 214 "%p, rpcb_local_clnt4: %p)\n", sn->rpcb_local_clnt,
214 rpcb_local_clnt4); 215 sn->rpcb_local_clnt4);
215} 216}
216 217
217/* 218/*
@@ -431,6 +432,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
431 struct rpc_message msg = { 432 struct rpc_message msg = {
432 .rpc_argp = &map, 433 .rpc_argp = &map,
433 }; 434 };
435 struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
434 436
435 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " 437 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
436 "rpcbind\n", (port ? "" : "un"), 438 "rpcbind\n", (port ? "" : "un"),
@@ -440,7 +442,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
440 if (port) 442 if (port)
441 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET]; 443 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
442 444
443 return rpcb_register_call(rpcb_local_clnt, &msg); 445 return rpcb_register_call(sn->rpcb_local_clnt, &msg);
444} 446}
445 447
446/* 448/*
@@ -453,6 +455,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
453 struct rpcbind_args *map = msg->rpc_argp; 455 struct rpcbind_args *map = msg->rpc_argp;
454 unsigned short port = ntohs(sin->sin_port); 456 unsigned short port = ntohs(sin->sin_port);
455 int result; 457 int result;
458 struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
456 459
457 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL); 460 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
458 461
@@ -465,7 +468,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
465 if (port) 468 if (port)
466 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; 469 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
467 470
468 result = rpcb_register_call(rpcb_local_clnt4, msg); 471 result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
469 kfree(map->r_addr); 472 kfree(map->r_addr);
470 return result; 473 return result;
471} 474}
@@ -480,6 +483,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
480 struct rpcbind_args *map = msg->rpc_argp; 483 struct rpcbind_args *map = msg->rpc_argp;
481 unsigned short port = ntohs(sin6->sin6_port); 484 unsigned short port = ntohs(sin6->sin6_port);
482 int result; 485 int result;
486 struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
483 487
484 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL); 488 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
485 489
@@ -492,7 +496,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
492 if (port) 496 if (port)
493 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; 497 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
494 498
495 result = rpcb_register_call(rpcb_local_clnt4, msg); 499 result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
496 kfree(map->r_addr); 500 kfree(map->r_addr);
497 return result; 501 return result;
498} 502}
@@ -500,6 +504,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
500static int rpcb_unregister_all_protofamilies(struct rpc_message *msg) 504static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
501{ 505{
502 struct rpcbind_args *map = msg->rpc_argp; 506 struct rpcbind_args *map = msg->rpc_argp;
507 struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
503 508
504 dprintk("RPC: unregistering [%u, %u, '%s'] with " 509 dprintk("RPC: unregistering [%u, %u, '%s'] with "
505 "local rpcbind\n", 510 "local rpcbind\n",
@@ -508,7 +513,7 @@ static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
508 map->r_addr = ""; 513 map->r_addr = "";
509 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; 514 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
510 515
511 return rpcb_register_call(rpcb_local_clnt4, msg); 516 return rpcb_register_call(sn->rpcb_local_clnt4, msg);
512} 517}
513 518
514/** 519/**
@@ -566,8 +571,9 @@ int rpcb_v4_register(const u32 program, const u32 version,
566 struct rpc_message msg = { 571 struct rpc_message msg = {
567 .rpc_argp = &map, 572 .rpc_argp = &map,
568 }; 573 };
574 struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
569 575
570 if (rpcb_local_clnt4 == NULL) 576 if (sn->rpcb_local_clnt4 == NULL)
571 return -EPROTONOSUPPORT; 577 return -EPROTONOSUPPORT;
572 578
573 if (address == NULL) 579 if (address == NULL)