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 f848b52c67b..3ddcbb1c0a4 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 8d4ea8351e3..ba1dc2eebd1 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 180ac34feb9..3d35e3e80c1 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 6f29836ec0c..eb75ca7c2d6 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 65ba36b80a9..7ef14b3c5be 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 00000000000..ce227e0fbc5 --- /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 2444780f5cf..f49b9afc443 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 f0179c3745d..e46353f41a4 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 | ||
