diff options
author | J. Bruce Fields <bfields@redhat.com> | 2012-03-21 16:42:14 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-03-26 11:48:54 -0400 |
commit | 1df00640c9111c881633d9b219f18e66c52599ec (patch) | |
tree | e36d3924d84f47ec93f6650ff1fd5b8ea7d10d24 /fs/lockd | |
parent | ab4684d1560f8d77f6ce82bd3f1f82937070d397 (diff) | |
parent | 5a7c9eec9fde1da0e3adf0a4ddb64ff2a324a492 (diff) |
Merge nfs containerization work from Trond's tree
The nfs containerization work is a prerequisite for Jeff Layton's reboot
recovery rework.
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/clnt4xdr.c | 2 | ||||
-rw-r--r-- | fs/lockd/clntlock.c | 3 | ||||
-rw-r--r-- | fs/lockd/clntxdr.c | 8 | ||||
-rw-r--r-- | fs/lockd/host.c | 42 | ||||
-rw-r--r-- | fs/lockd/mon.c | 21 | ||||
-rw-r--r-- | fs/lockd/netns.h | 12 | ||||
-rw-r--r-- | fs/lockd/svc.c | 117 | ||||
-rw-r--r-- | fs/lockd/svclock.c | 59 |
8 files changed, 194 insertions, 70 deletions
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c index f848b52c67b1..3ddcbb1c0a43 100644 --- a/fs/lockd/clnt4xdr.c +++ b/fs/lockd/clnt4xdr.c | |||
@@ -598,7 +598,7 @@ static struct rpc_procinfo nlm4_procedures[] = { | |||
598 | PROC(GRANTED_RES, res, norep), | 598 | PROC(GRANTED_RES, res, norep), |
599 | }; | 599 | }; |
600 | 600 | ||
601 | struct rpc_version nlm_version4 = { | 601 | const struct rpc_version nlm_version4 = { |
602 | .number = 4, | 602 | .number = 4, |
603 | .nrprocs = ARRAY_SIZE(nlm4_procedures), | 603 | .nrprocs = ARRAY_SIZE(nlm4_procedures), |
604 | .procs = nlm4_procedures, | 604 | .procs = nlm4_procedures, |
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 8d4ea8351e3d..ba1dc2eebd1e 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -62,7 +62,8 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init) | |||
62 | 62 | ||
63 | host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, | 63 | host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, |
64 | nlm_init->protocol, nlm_version, | 64 | nlm_init->protocol, nlm_version, |
65 | nlm_init->hostname, nlm_init->noresvport); | 65 | nlm_init->hostname, nlm_init->noresvport, |
66 | nlm_init->net); | ||
66 | if (host == NULL) { | 67 | if (host == NULL) { |
67 | lockd_down(); | 68 | lockd_down(); |
68 | return ERR_PTR(-ENOLCK); | 69 | return ERR_PTR(-ENOLCK); |
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index 180ac34feb9a..3d35e3e80c1c 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c | |||
@@ -596,19 +596,19 @@ static struct rpc_procinfo nlm_procedures[] = { | |||
596 | PROC(GRANTED_RES, res, norep), | 596 | PROC(GRANTED_RES, res, norep), |
597 | }; | 597 | }; |
598 | 598 | ||
599 | static struct rpc_version nlm_version1 = { | 599 | static const struct rpc_version nlm_version1 = { |
600 | .number = 1, | 600 | .number = 1, |
601 | .nrprocs = ARRAY_SIZE(nlm_procedures), | 601 | .nrprocs = ARRAY_SIZE(nlm_procedures), |
602 | .procs = nlm_procedures, | 602 | .procs = nlm_procedures, |
603 | }; | 603 | }; |
604 | 604 | ||
605 | static struct rpc_version nlm_version3 = { | 605 | static const struct rpc_version nlm_version3 = { |
606 | .number = 3, | 606 | .number = 3, |
607 | .nrprocs = ARRAY_SIZE(nlm_procedures), | 607 | .nrprocs = ARRAY_SIZE(nlm_procedures), |
608 | .procs = nlm_procedures, | 608 | .procs = nlm_procedures, |
609 | }; | 609 | }; |
610 | 610 | ||
611 | static struct rpc_version *nlm_versions[] = { | 611 | static const struct rpc_version *nlm_versions[] = { |
612 | [1] = &nlm_version1, | 612 | [1] = &nlm_version1, |
613 | [3] = &nlm_version3, | 613 | [3] = &nlm_version3, |
614 | #ifdef CONFIG_LOCKD_V4 | 614 | #ifdef CONFIG_LOCKD_V4 |
@@ -618,7 +618,7 @@ static struct rpc_version *nlm_versions[] = { | |||
618 | 618 | ||
619 | static struct rpc_stat nlm_rpc_stats; | 619 | static struct rpc_stat nlm_rpc_stats; |
620 | 620 | ||
621 | struct rpc_program nlm_program = { | 621 | const struct rpc_program nlm_program = { |
622 | .name = "lockd", | 622 | .name = "lockd", |
623 | .number = NLM_PROGRAM, | 623 | .number = NLM_PROGRAM, |
624 | .nrvers = ARRAY_SIZE(nlm_versions), | 624 | .nrvers = ARRAY_SIZE(nlm_versions), |
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 | } |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 65ba36b80a9e..7ef14b3c5bee 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -47,7 +47,7 @@ struct nsm_res { | |||
47 | u32 state; | 47 | u32 state; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct rpc_program nsm_program; | 50 | static const struct rpc_program nsm_program; |
51 | static LIST_HEAD(nsm_handles); | 51 | static LIST_HEAD(nsm_handles); |
52 | static DEFINE_SPINLOCK(nsm_lock); | 52 | static DEFINE_SPINLOCK(nsm_lock); |
53 | 53 | ||
@@ -62,14 +62,14 @@ static inline struct sockaddr *nsm_addr(const struct nsm_handle *nsm) | |||
62 | return (struct sockaddr *)&nsm->sm_addr; | 62 | return (struct sockaddr *)&nsm->sm_addr; |
63 | } | 63 | } |
64 | 64 | ||
65 | static struct rpc_clnt *nsm_create(void) | 65 | static struct rpc_clnt *nsm_create(struct net *net) |
66 | { | 66 | { |
67 | struct sockaddr_in sin = { | 67 | struct sockaddr_in sin = { |
68 | .sin_family = AF_INET, | 68 | .sin_family = AF_INET, |
69 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | 69 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), |
70 | }; | 70 | }; |
71 | struct rpc_create_args args = { | 71 | struct rpc_create_args args = { |
72 | .net = &init_net, | 72 | .net = net, |
73 | .protocol = XPRT_TRANSPORT_UDP, | 73 | .protocol = XPRT_TRANSPORT_UDP, |
74 | .address = (struct sockaddr *)&sin, | 74 | .address = (struct sockaddr *)&sin, |
75 | .addrsize = sizeof(sin), | 75 | .addrsize = sizeof(sin), |
@@ -83,7 +83,8 @@ static struct rpc_clnt *nsm_create(void) | |||
83 | return rpc_create(&args); | 83 | return rpc_create(&args); |
84 | } | 84 | } |
85 | 85 | ||
86 | static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res) | 86 | static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, |
87 | struct net *net) | ||
87 | { | 88 | { |
88 | struct rpc_clnt *clnt; | 89 | struct rpc_clnt *clnt; |
89 | int status; | 90 | int status; |
@@ -99,7 +100,7 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res) | |||
99 | .rpc_resp = res, | 100 | .rpc_resp = res, |
100 | }; | 101 | }; |
101 | 102 | ||
102 | clnt = nsm_create(); | 103 | clnt = nsm_create(net); |
103 | if (IS_ERR(clnt)) { | 104 | if (IS_ERR(clnt)) { |
104 | status = PTR_ERR(clnt); | 105 | status = PTR_ERR(clnt); |
105 | dprintk("lockd: failed to create NSM upcall transport, " | 106 | dprintk("lockd: failed to create NSM upcall transport, " |
@@ -149,7 +150,7 @@ int nsm_monitor(const struct nlm_host *host) | |||
149 | */ | 150 | */ |
150 | nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; | 151 | nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; |
151 | 152 | ||
152 | status = nsm_mon_unmon(nsm, NSMPROC_MON, &res); | 153 | status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host->net); |
153 | if (unlikely(res.status != 0)) | 154 | if (unlikely(res.status != 0)) |
154 | status = -EIO; | 155 | status = -EIO; |
155 | if (unlikely(status < 0)) { | 156 | if (unlikely(status < 0)) { |
@@ -183,7 +184,7 @@ void nsm_unmonitor(const struct nlm_host *host) | |||
183 | && nsm->sm_monitored && !nsm->sm_sticky) { | 184 | && nsm->sm_monitored && !nsm->sm_sticky) { |
184 | dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); | 185 | dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); |
185 | 186 | ||
186 | status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res); | 187 | status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host->net); |
187 | if (res.status != 0) | 188 | if (res.status != 0) |
188 | status = -EIO; | 189 | status = -EIO; |
189 | if (status < 0) | 190 | if (status < 0) |
@@ -534,19 +535,19 @@ static struct rpc_procinfo nsm_procedures[] = { | |||
534 | }, | 535 | }, |
535 | }; | 536 | }; |
536 | 537 | ||
537 | static struct rpc_version nsm_version1 = { | 538 | static const struct rpc_version nsm_version1 = { |
538 | .number = 1, | 539 | .number = 1, |
539 | .nrprocs = ARRAY_SIZE(nsm_procedures), | 540 | .nrprocs = ARRAY_SIZE(nsm_procedures), |
540 | .procs = nsm_procedures | 541 | .procs = nsm_procedures |
541 | }; | 542 | }; |
542 | 543 | ||
543 | static struct rpc_version * nsm_version[] = { | 544 | static const struct rpc_version *nsm_version[] = { |
544 | [1] = &nsm_version1, | 545 | [1] = &nsm_version1, |
545 | }; | 546 | }; |
546 | 547 | ||
547 | static struct rpc_stat nsm_stats; | 548 | static struct rpc_stat nsm_stats; |
548 | 549 | ||
549 | static struct rpc_program nsm_program = { | 550 | static const struct rpc_program nsm_program = { |
550 | .name = "statd", | 551 | .name = "statd", |
551 | .number = NSM_PROGRAM, | 552 | .number = NSM_PROGRAM, |
552 | .nrvers = ARRAY_SIZE(nsm_version), | 553 | .nrvers = ARRAY_SIZE(nsm_version), |
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h new file mode 100644 index 000000000000..ce227e0fbc5c --- /dev/null +++ b/fs/lockd/netns.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef __LOCKD_NETNS_H__ | ||
2 | #define __LOCKD_NETNS_H__ | ||
3 | |||
4 | #include <net/netns/generic.h> | ||
5 | |||
6 | struct lockd_net { | ||
7 | unsigned int nlmsvc_users; | ||
8 | }; | ||
9 | |||
10 | extern int lockd_net_id; | ||
11 | |||
12 | #endif | ||
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 2444780f5cfa..f49b9afc4436 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include <linux/lockd/lockd.h> | 35 | #include <linux/lockd/lockd.h> |
36 | #include <linux/nfs.h> | 36 | #include <linux/nfs.h> |
37 | 37 | ||
38 | #include "netns.h" | ||
39 | |||
38 | #define NLMDBG_FACILITY NLMDBG_SVC | 40 | #define NLMDBG_FACILITY NLMDBG_SVC |
39 | #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE) | 41 | #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE) |
40 | #define ALLOWED_SIGS (sigmask(SIGKILL)) | 42 | #define ALLOWED_SIGS (sigmask(SIGKILL)) |
@@ -50,6 +52,8 @@ static struct task_struct *nlmsvc_task; | |||
50 | static struct svc_rqst *nlmsvc_rqst; | 52 | static struct svc_rqst *nlmsvc_rqst; |
51 | unsigned long nlmsvc_timeout; | 53 | unsigned long nlmsvc_timeout; |
52 | 54 | ||
55 | int lockd_net_id; | ||
56 | |||
53 | /* | 57 | /* |
54 | * These can be set at insmod time (useful for NFS as root filesystem), | 58 | * These can be set at insmod time (useful for NFS as root filesystem), |
55 | * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 | 59 | * and also changed through the sysctl interface. -- Jamie Lokier, Aug 2003 |
@@ -189,27 +193,29 @@ lockd(void *vrqstp) | |||
189 | } | 193 | } |
190 | 194 | ||
191 | static int create_lockd_listener(struct svc_serv *serv, const char *name, | 195 | static int create_lockd_listener(struct svc_serv *serv, const char *name, |
192 | const int family, const unsigned short port) | 196 | struct net *net, const int family, |
197 | const unsigned short port) | ||
193 | { | 198 | { |
194 | struct svc_xprt *xprt; | 199 | struct svc_xprt *xprt; |
195 | 200 | ||
196 | xprt = svc_find_xprt(serv, name, family, 0); | 201 | xprt = svc_find_xprt(serv, name, net, family, 0); |
197 | if (xprt == NULL) | 202 | if (xprt == NULL) |
198 | return svc_create_xprt(serv, name, &init_net, family, port, | 203 | return svc_create_xprt(serv, name, net, family, port, |
199 | SVC_SOCK_DEFAULTS); | 204 | SVC_SOCK_DEFAULTS); |
200 | svc_xprt_put(xprt); | 205 | svc_xprt_put(xprt); |
201 | return 0; | 206 | return 0; |
202 | } | 207 | } |
203 | 208 | ||
204 | static int create_lockd_family(struct svc_serv *serv, const int family) | 209 | static int create_lockd_family(struct svc_serv *serv, struct net *net, |
210 | const int family) | ||
205 | { | 211 | { |
206 | int err; | 212 | int err; |
207 | 213 | ||
208 | err = create_lockd_listener(serv, "udp", family, nlm_udpport); | 214 | err = create_lockd_listener(serv, "udp", net, family, nlm_udpport); |
209 | if (err < 0) | 215 | if (err < 0) |
210 | return err; | 216 | return err; |
211 | 217 | ||
212 | return create_lockd_listener(serv, "tcp", family, nlm_tcpport); | 218 | return create_lockd_listener(serv, "tcp", net, family, nlm_tcpport); |
213 | } | 219 | } |
214 | 220 | ||
215 | /* | 221 | /* |
@@ -222,16 +228,16 @@ static int create_lockd_family(struct svc_serv *serv, const int family) | |||
222 | * Returns zero if all listeners are available; otherwise a | 228 | * Returns zero if all listeners are available; otherwise a |
223 | * negative errno value is returned. | 229 | * negative errno value is returned. |
224 | */ | 230 | */ |
225 | static int make_socks(struct svc_serv *serv) | 231 | static int make_socks(struct svc_serv *serv, struct net *net) |
226 | { | 232 | { |
227 | static int warned; | 233 | static int warned; |
228 | int err; | 234 | int err; |
229 | 235 | ||
230 | err = create_lockd_family(serv, PF_INET); | 236 | err = create_lockd_family(serv, net, PF_INET); |
231 | if (err < 0) | 237 | if (err < 0) |
232 | goto out_err; | 238 | goto out_err; |
233 | 239 | ||
234 | err = create_lockd_family(serv, PF_INET6); | 240 | err = create_lockd_family(serv, net, PF_INET6); |
235 | if (err < 0 && err != -EAFNOSUPPORT) | 241 | if (err < 0 && err != -EAFNOSUPPORT) |
236 | goto out_err; | 242 | goto out_err; |
237 | 243 | ||
@@ -245,6 +251,47 @@ out_err: | |||
245 | return err; | 251 | return err; |
246 | } | 252 | } |
247 | 253 | ||
254 | static int lockd_up_net(struct net *net) | ||
255 | { | ||
256 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
257 | struct svc_serv *serv = nlmsvc_rqst->rq_server; | ||
258 | int error; | ||
259 | |||
260 | if (ln->nlmsvc_users) | ||
261 | return 0; | ||
262 | |||
263 | error = svc_rpcb_setup(serv, net); | ||
264 | if (error) | ||
265 | goto err_rpcb; | ||
266 | |||
267 | error = make_socks(serv, net); | ||
268 | if (error < 0) | ||
269 | goto err_socks; | ||
270 | return 0; | ||
271 | |||
272 | err_socks: | ||
273 | svc_rpcb_cleanup(serv, net); | ||
274 | err_rpcb: | ||
275 | return error; | ||
276 | } | ||
277 | |||
278 | static void lockd_down_net(struct net *net) | ||
279 | { | ||
280 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
281 | struct svc_serv *serv = nlmsvc_rqst->rq_server; | ||
282 | |||
283 | if (ln->nlmsvc_users) { | ||
284 | if (--ln->nlmsvc_users == 0) { | ||
285 | nlm_shutdown_hosts_net(net); | ||
286 | svc_shutdown_net(serv, net); | ||
287 | } | ||
288 | } else { | ||
289 | printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n", | ||
290 | nlmsvc_task, net); | ||
291 | BUG(); | ||
292 | } | ||
293 | } | ||
294 | |||
248 | /* | 295 | /* |
249 | * Bring up the lockd process if it's not already up. | 296 | * Bring up the lockd process if it's not already up. |
250 | */ | 297 | */ |
@@ -252,13 +299,16 @@ int lockd_up(void) | |||
252 | { | 299 | { |
253 | struct svc_serv *serv; | 300 | struct svc_serv *serv; |
254 | int error = 0; | 301 | int error = 0; |
302 | struct net *net = current->nsproxy->net_ns; | ||
255 | 303 | ||
256 | mutex_lock(&nlmsvc_mutex); | 304 | mutex_lock(&nlmsvc_mutex); |
257 | /* | 305 | /* |
258 | * Check whether we're already up and running. | 306 | * Check whether we're already up and running. |
259 | */ | 307 | */ |
260 | if (nlmsvc_rqst) | 308 | if (nlmsvc_rqst) { |
309 | error = lockd_up_net(net); | ||
261 | goto out; | 310 | goto out; |
311 | } | ||
262 | 312 | ||
263 | /* | 313 | /* |
264 | * Sanity check: if there's no pid, | 314 | * Sanity check: if there's no pid, |
@@ -275,7 +325,7 @@ int lockd_up(void) | |||
275 | goto out; | 325 | goto out; |
276 | } | 326 | } |
277 | 327 | ||
278 | error = make_socks(serv); | 328 | error = make_socks(serv, net); |
279 | if (error < 0) | 329 | if (error < 0) |
280 | goto destroy_and_out; | 330 | goto destroy_and_out; |
281 | 331 | ||
@@ -313,8 +363,12 @@ int lockd_up(void) | |||
313 | destroy_and_out: | 363 | destroy_and_out: |
314 | svc_destroy(serv); | 364 | svc_destroy(serv); |
315 | out: | 365 | out: |
316 | if (!error) | 366 | if (!error) { |
367 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
368 | |||
369 | ln->nlmsvc_users++; | ||
317 | nlmsvc_users++; | 370 | nlmsvc_users++; |
371 | } | ||
318 | mutex_unlock(&nlmsvc_mutex); | 372 | mutex_unlock(&nlmsvc_mutex); |
319 | return error; | 373 | return error; |
320 | } | 374 | } |
@@ -328,8 +382,10 @@ lockd_down(void) | |||
328 | { | 382 | { |
329 | mutex_lock(&nlmsvc_mutex); | 383 | mutex_lock(&nlmsvc_mutex); |
330 | if (nlmsvc_users) { | 384 | if (nlmsvc_users) { |
331 | if (--nlmsvc_users) | 385 | if (--nlmsvc_users) { |
386 | lockd_down_net(current->nsproxy->net_ns); | ||
332 | goto out; | 387 | goto out; |
388 | } | ||
333 | } else { | 389 | } else { |
334 | printk(KERN_ERR "lockd_down: no users! task=%p\n", | 390 | printk(KERN_ERR "lockd_down: no users! task=%p\n", |
335 | nlmsvc_task); | 391 | nlmsvc_task); |
@@ -497,24 +553,55 @@ module_param_call(nlm_tcpport, param_set_port, param_get_int, | |||
497 | module_param(nsm_use_hostnames, bool, 0644); | 553 | module_param(nsm_use_hostnames, bool, 0644); |
498 | module_param(nlm_max_connections, uint, 0644); | 554 | module_param(nlm_max_connections, uint, 0644); |
499 | 555 | ||
556 | static int lockd_init_net(struct net *net) | ||
557 | { | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static void lockd_exit_net(struct net *net) | ||
562 | { | ||
563 | } | ||
564 | |||
565 | static struct pernet_operations lockd_net_ops = { | ||
566 | .init = lockd_init_net, | ||
567 | .exit = lockd_exit_net, | ||
568 | .id = &lockd_net_id, | ||
569 | .size = sizeof(struct lockd_net), | ||
570 | }; | ||
571 | |||
572 | |||
500 | /* | 573 | /* |
501 | * Initialising and terminating the module. | 574 | * Initialising and terminating the module. |
502 | */ | 575 | */ |
503 | 576 | ||
504 | static int __init init_nlm(void) | 577 | static int __init init_nlm(void) |
505 | { | 578 | { |
579 | int err; | ||
580 | |||
506 | #ifdef CONFIG_SYSCTL | 581 | #ifdef CONFIG_SYSCTL |
582 | err = -ENOMEM; | ||
507 | nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root); | 583 | nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root); |
508 | return nlm_sysctl_table ? 0 : -ENOMEM; | 584 | if (nlm_sysctl_table == NULL) |
509 | #else | 585 | goto err_sysctl; |
586 | #endif | ||
587 | err = register_pernet_subsys(&lockd_net_ops); | ||
588 | if (err) | ||
589 | goto err_pernet; | ||
510 | return 0; | 590 | return 0; |
591 | |||
592 | err_pernet: | ||
593 | #ifdef CONFIG_SYSCTL | ||
594 | unregister_sysctl_table(nlm_sysctl_table); | ||
511 | #endif | 595 | #endif |
596 | err_sysctl: | ||
597 | return err; | ||
512 | } | 598 | } |
513 | 599 | ||
514 | static void __exit exit_nlm(void) | 600 | static void __exit exit_nlm(void) |
515 | { | 601 | { |
516 | /* FIXME: delete all NLM clients */ | 602 | /* FIXME: delete all NLM clients */ |
517 | nlm_shutdown_hosts(); | 603 | nlm_shutdown_hosts(); |
604 | unregister_pernet_subsys(&lockd_net_ops); | ||
518 | #ifdef CONFIG_SYSCTL | 605 | #ifdef CONFIG_SYSCTL |
519 | unregister_sysctl_table(nlm_sysctl_table); | 606 | unregister_sysctl_table(nlm_sysctl_table); |
520 | #endif | 607 | #endif |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index f0179c3745d2..e46353f41a42 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -46,7 +46,6 @@ static void nlmsvc_remove_block(struct nlm_block *block); | |||
46 | static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock); | 46 | static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock); |
47 | static void nlmsvc_freegrantargs(struct nlm_rqst *call); | 47 | static void nlmsvc_freegrantargs(struct nlm_rqst *call); |
48 | static const struct rpc_call_ops nlmsvc_grant_ops; | 48 | static const struct rpc_call_ops nlmsvc_grant_ops; |
49 | static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie); | ||
50 | 49 | ||
51 | /* | 50 | /* |
52 | * The list of blocked locks to retry | 51 | * The list of blocked locks to retry |
@@ -54,6 +53,35 @@ static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie); | |||
54 | static LIST_HEAD(nlm_blocked); | 53 | static LIST_HEAD(nlm_blocked); |
55 | static DEFINE_SPINLOCK(nlm_blocked_lock); | 54 | static DEFINE_SPINLOCK(nlm_blocked_lock); |
56 | 55 | ||
56 | #ifdef LOCKD_DEBUG | ||
57 | static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) | ||
58 | { | ||
59 | /* | ||
60 | * We can get away with a static buffer because we're only | ||
61 | * called with BKL held. | ||
62 | */ | ||
63 | static char buf[2*NLM_MAXCOOKIELEN+1]; | ||
64 | unsigned int i, len = sizeof(buf); | ||
65 | char *p = buf; | ||
66 | |||
67 | len--; /* allow for trailing \0 */ | ||
68 | if (len < 3) | ||
69 | return "???"; | ||
70 | for (i = 0 ; i < cookie->len ; i++) { | ||
71 | if (len < 2) { | ||
72 | strcpy(p-3, "..."); | ||
73 | break; | ||
74 | } | ||
75 | sprintf(p, "%02x", cookie->data[i]); | ||
76 | p += 2; | ||
77 | len -= 2; | ||
78 | } | ||
79 | *p = '\0'; | ||
80 | |||
81 | return buf; | ||
82 | } | ||
83 | #endif | ||
84 | |||
57 | /* | 85 | /* |
58 | * Insert a blocked lock into the global list | 86 | * Insert a blocked lock into the global list |
59 | */ | 87 | */ |
@@ -935,32 +963,3 @@ nlmsvc_retry_blocked(void) | |||
935 | 963 | ||
936 | return timeout; | 964 | return timeout; |
937 | } | 965 | } |
938 | |||
939 | #ifdef RPC_DEBUG | ||
940 | static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) | ||
941 | { | ||
942 | /* | ||
943 | * We can get away with a static buffer because we're only | ||
944 | * called with BKL held. | ||
945 | */ | ||
946 | static char buf[2*NLM_MAXCOOKIELEN+1]; | ||
947 | unsigned int i, len = sizeof(buf); | ||
948 | char *p = buf; | ||
949 | |||
950 | len--; /* allow for trailing \0 */ | ||
951 | if (len < 3) | ||
952 | return "???"; | ||
953 | for (i = 0 ; i < cookie->len ; i++) { | ||
954 | if (len < 2) { | ||
955 | strcpy(p-3, "..."); | ||
956 | break; | ||
957 | } | ||
958 | sprintf(p, "%02x", cookie->data[i]); | ||
959 | p += 2; | ||
960 | len -= 2; | ||
961 | } | ||
962 | *p = '\0'; | ||
963 | |||
964 | return buf; | ||
965 | } | ||
966 | #endif | ||