diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/netns.h | 5 | ||||
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 64 |
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 | ||
20 | extern int sunrpc_net_id; | 25 | extern 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 *); | |||
111 | static void rpcb_map_release(void *data); | 114 | static void rpcb_map_release(void *data); |
112 | static struct rpc_program rpcb_program; | 115 | static struct rpc_program rpcb_program; |
113 | 116 | ||
114 | static struct rpc_clnt * rpcb_local_clnt; | ||
115 | static struct rpc_clnt * rpcb_local_clnt4; | ||
116 | |||
117 | DEFINE_SPINLOCK(rpcb_clnt_lock); | ||
118 | unsigned int rpcb_users; | ||
119 | |||
120 | struct rpcbind_args { | 117 | struct 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) | |||
167 | static int rpcb_get_local(void) | 164 | static 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 | ||
180 | void rpcb_put_local(void) | 178 | void 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 | ||
205 | static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4) | 204 | static 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, | |||
500 | static int rpcb_unregister_all_protofamilies(struct rpc_message *msg) | 504 | static 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) |