diff options
Diffstat (limited to 'fs/lockd/host.c')
-rw-r--r-- | fs/lockd/host.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 6f29836ec0cb..eb75ca7c2d6e 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/lockd/lockd.h> | 17 | #include <linux/lockd/lockd.h> |
18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
19 | 19 | ||
20 | #include <linux/sunrpc/svc_xprt.h> | ||
21 | |||
20 | #include <net/ipv6.h> | 22 | #include <net/ipv6.h> |
21 | 23 | ||
22 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE | 24 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE |
@@ -54,6 +56,7 @@ struct nlm_lookup_host_info { | |||
54 | const char *hostname; /* remote's hostname */ | 56 | const char *hostname; /* remote's hostname */ |
55 | const size_t hostname_len; /* it's length */ | 57 | const size_t hostname_len; /* it's length */ |
56 | const int noresvport; /* use non-priv port */ | 58 | const int noresvport; /* use non-priv port */ |
59 | struct net *net; /* network namespace to bind */ | ||
57 | }; | 60 | }; |
58 | 61 | ||
59 | /* | 62 | /* |
@@ -155,6 +158,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, | |||
155 | INIT_LIST_HEAD(&host->h_reclaim); | 158 | INIT_LIST_HEAD(&host->h_reclaim); |
156 | host->h_nsmhandle = nsm; | 159 | host->h_nsmhandle = nsm; |
157 | host->h_addrbuf = nsm->sm_addrbuf; | 160 | host->h_addrbuf = nsm->sm_addrbuf; |
161 | host->net = ni->net; | ||
158 | 162 | ||
159 | out: | 163 | out: |
160 | return host; | 164 | return host; |
@@ -206,7 +210,8 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
206 | const unsigned short protocol, | 210 | const unsigned short protocol, |
207 | const u32 version, | 211 | const u32 version, |
208 | const char *hostname, | 212 | const char *hostname, |
209 | int noresvport) | 213 | int noresvport, |
214 | struct net *net) | ||
210 | { | 215 | { |
211 | struct nlm_lookup_host_info ni = { | 216 | struct nlm_lookup_host_info ni = { |
212 | .server = 0, | 217 | .server = 0, |
@@ -217,6 +222,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
217 | .hostname = hostname, | 222 | .hostname = hostname, |
218 | .hostname_len = strlen(hostname), | 223 | .hostname_len = strlen(hostname), |
219 | .noresvport = noresvport, | 224 | .noresvport = noresvport, |
225 | .net = net, | ||
220 | }; | 226 | }; |
221 | struct hlist_head *chain; | 227 | struct hlist_head *chain; |
222 | struct hlist_node *pos; | 228 | struct hlist_node *pos; |
@@ -231,6 +237,8 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
231 | 237 | ||
232 | chain = &nlm_client_hosts[nlm_hash_address(sap)]; | 238 | chain = &nlm_client_hosts[nlm_hash_address(sap)]; |
233 | hlist_for_each_entry(host, pos, chain, h_hash) { | 239 | hlist_for_each_entry(host, pos, chain, h_hash) { |
240 | if (host->net != net) | ||
241 | continue; | ||
234 | if (!rpc_cmp_addr(nlm_addr(host), sap)) | 242 | if (!rpc_cmp_addr(nlm_addr(host), sap)) |
235 | continue; | 243 | continue; |
236 | 244 | ||
@@ -318,6 +326,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
318 | struct nsm_handle *nsm = NULL; | 326 | struct nsm_handle *nsm = NULL; |
319 | struct sockaddr *src_sap = svc_daddr(rqstp); | 327 | struct sockaddr *src_sap = svc_daddr(rqstp); |
320 | size_t src_len = rqstp->rq_daddrlen; | 328 | size_t src_len = rqstp->rq_daddrlen; |
329 | struct net *net = rqstp->rq_xprt->xpt_net; | ||
321 | struct nlm_lookup_host_info ni = { | 330 | struct nlm_lookup_host_info ni = { |
322 | .server = 1, | 331 | .server = 1, |
323 | .sap = svc_addr(rqstp), | 332 | .sap = svc_addr(rqstp), |
@@ -326,6 +335,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
326 | .version = rqstp->rq_vers, | 335 | .version = rqstp->rq_vers, |
327 | .hostname = hostname, | 336 | .hostname = hostname, |
328 | .hostname_len = hostname_len, | 337 | .hostname_len = hostname_len, |
338 | .net = net, | ||
329 | }; | 339 | }; |
330 | 340 | ||
331 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, | 341 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, |
@@ -339,6 +349,8 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
339 | 349 | ||
340 | chain = &nlm_server_hosts[nlm_hash_address(ni.sap)]; | 350 | chain = &nlm_server_hosts[nlm_hash_address(ni.sap)]; |
341 | hlist_for_each_entry(host, pos, chain, h_hash) { | 351 | hlist_for_each_entry(host, pos, chain, h_hash) { |
352 | if (host->net != net) | ||
353 | continue; | ||
342 | if (!rpc_cmp_addr(nlm_addr(host), ni.sap)) | 354 | if (!rpc_cmp_addr(nlm_addr(host), ni.sap)) |
343 | continue; | 355 | continue; |
344 | 356 | ||
@@ -431,7 +443,7 @@ nlm_bind_host(struct nlm_host *host) | |||
431 | .to_retries = 5U, | 443 | .to_retries = 5U, |
432 | }; | 444 | }; |
433 | struct rpc_create_args args = { | 445 | struct rpc_create_args args = { |
434 | .net = &init_net, | 446 | .net = host->net, |
435 | .protocol = host->h_proto, | 447 | .protocol = host->h_proto, |
436 | .address = nlm_addr(host), | 448 | .address = nlm_addr(host), |
437 | .addrsize = host->h_addrlen, | 449 | .addrsize = host->h_addrlen, |
@@ -553,12 +565,8 @@ void nlm_host_rebooted(const struct nlm_reboot *info) | |||
553 | nsm_release(nsm); | 565 | nsm_release(nsm); |
554 | } | 566 | } |
555 | 567 | ||
556 | /* | ||
557 | * Shut down the hosts module. | ||
558 | * Note that this routine is called only at server shutdown time. | ||
559 | */ | ||
560 | void | 568 | void |
561 | nlm_shutdown_hosts(void) | 569 | nlm_shutdown_hosts_net(struct net *net) |
562 | { | 570 | { |
563 | struct hlist_head *chain; | 571 | struct hlist_head *chain; |
564 | struct hlist_node *pos; | 572 | struct hlist_node *pos; |
@@ -570,6 +578,8 @@ nlm_shutdown_hosts(void) | |||
570 | /* First, make all hosts eligible for gc */ | 578 | /* First, make all hosts eligible for gc */ |
571 | dprintk("lockd: nuking all hosts...\n"); | 579 | dprintk("lockd: nuking all hosts...\n"); |
572 | for_each_host(host, pos, chain, nlm_server_hosts) { | 580 | for_each_host(host, pos, chain, nlm_server_hosts) { |
581 | if (net && host->net != net) | ||
582 | continue; | ||
573 | host->h_expires = jiffies - 1; | 583 | host->h_expires = jiffies - 1; |
574 | if (host->h_rpcclnt) { | 584 | if (host->h_rpcclnt) { |
575 | rpc_shutdown_client(host->h_rpcclnt); | 585 | rpc_shutdown_client(host->h_rpcclnt); |
@@ -580,15 +590,29 @@ nlm_shutdown_hosts(void) | |||
580 | /* Then, perform a garbage collection pass */ | 590 | /* Then, perform a garbage collection pass */ |
581 | nlm_gc_hosts(); | 591 | nlm_gc_hosts(); |
582 | mutex_unlock(&nlm_host_mutex); | 592 | mutex_unlock(&nlm_host_mutex); |
593 | } | ||
594 | |||
595 | /* | ||
596 | * Shut down the hosts module. | ||
597 | * Note that this routine is called only at server shutdown time. | ||
598 | */ | ||
599 | void | ||
600 | nlm_shutdown_hosts(void) | ||
601 | { | ||
602 | struct hlist_head *chain; | ||
603 | struct hlist_node *pos; | ||
604 | struct nlm_host *host; | ||
605 | |||
606 | nlm_shutdown_hosts_net(NULL); | ||
583 | 607 | ||
584 | /* complain if any hosts are left */ | 608 | /* complain if any hosts are left */ |
585 | if (nrhosts != 0) { | 609 | if (nrhosts != 0) { |
586 | printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); | 610 | printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); |
587 | dprintk("lockd: %lu hosts left:\n", nrhosts); | 611 | dprintk("lockd: %lu hosts left:\n", nrhosts); |
588 | for_each_host(host, pos, chain, nlm_server_hosts) { | 612 | for_each_host(host, pos, chain, nlm_server_hosts) { |
589 | dprintk(" %s (cnt %d use %d exp %ld)\n", | 613 | dprintk(" %s (cnt %d use %d exp %ld net %p)\n", |
590 | host->h_name, atomic_read(&host->h_count), | 614 | host->h_name, atomic_read(&host->h_count), |
591 | host->h_inuse, host->h_expires); | 615 | host->h_inuse, host->h_expires, host->net); |
592 | } | 616 | } |
593 | } | 617 | } |
594 | } | 618 | } |