aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-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)