diff options
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/grace.c | 16 | ||||
-rw-r--r-- | fs/lockd/host.c | 92 | ||||
-rw-r--r-- | fs/lockd/netns.h | 7 | ||||
-rw-r--r-- | fs/lockd/svc.c | 43 | ||||
-rw-r--r-- | fs/lockd/svc4proc.c | 13 | ||||
-rw-r--r-- | fs/lockd/svclock.c | 16 | ||||
-rw-r--r-- | fs/lockd/svcproc.c | 15 | ||||
-rw-r--r-- | fs/lockd/svcsubs.c | 19 |
8 files changed, 142 insertions, 79 deletions
diff --git a/fs/lockd/grace.c b/fs/lockd/grace.c index 183cc1f0af1c..6d1ee7204c88 100644 --- a/fs/lockd/grace.c +++ b/fs/lockd/grace.c | |||
@@ -4,8 +4,10 @@ | |||
4 | 4 | ||
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/lockd/bind.h> | 6 | #include <linux/lockd/bind.h> |
7 | #include <net/net_namespace.h> | ||
8 | |||
9 | #include "netns.h" | ||
7 | 10 | ||
8 | static LIST_HEAD(grace_list); | ||
9 | static DEFINE_SPINLOCK(grace_lock); | 11 | static DEFINE_SPINLOCK(grace_lock); |
10 | 12 | ||
11 | /** | 13 | /** |
@@ -19,10 +21,12 @@ static DEFINE_SPINLOCK(grace_lock); | |||
19 | * | 21 | * |
20 | * This function is called to start a grace period. | 22 | * This function is called to start a grace period. |
21 | */ | 23 | */ |
22 | void locks_start_grace(struct lock_manager *lm) | 24 | void locks_start_grace(struct net *net, struct lock_manager *lm) |
23 | { | 25 | { |
26 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
27 | |||
24 | spin_lock(&grace_lock); | 28 | spin_lock(&grace_lock); |
25 | list_add(&lm->list, &grace_list); | 29 | list_add(&lm->list, &ln->grace_list); |
26 | spin_unlock(&grace_lock); | 30 | spin_unlock(&grace_lock); |
27 | } | 31 | } |
28 | EXPORT_SYMBOL_GPL(locks_start_grace); | 32 | EXPORT_SYMBOL_GPL(locks_start_grace); |
@@ -52,8 +56,10 @@ EXPORT_SYMBOL_GPL(locks_end_grace); | |||
52 | * to answer ordinary lock requests, and when they should accept only | 56 | * to answer ordinary lock requests, and when they should accept only |
53 | * lock reclaims. | 57 | * lock reclaims. |
54 | */ | 58 | */ |
55 | int locks_in_grace(void) | 59 | int locks_in_grace(struct net *net) |
56 | { | 60 | { |
57 | return !list_empty(&grace_list); | 61 | struct lockd_net *ln = net_generic(net, lockd_net_id); |
62 | |||
63 | return !list_empty(&ln->grace_list); | ||
58 | } | 64 | } |
59 | EXPORT_SYMBOL_GPL(locks_in_grace); | 65 | EXPORT_SYMBOL_GPL(locks_in_grace); |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index eb75ca7c2d6e..f9b22e58f78f 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #include <net/ipv6.h> | 22 | #include <net/ipv6.h> |
23 | 23 | ||
24 | #include "netns.h" | ||
25 | |||
24 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE | 26 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE |
25 | #define NLM_HOST_NRHASH 32 | 27 | #define NLM_HOST_NRHASH 32 |
26 | #define NLM_HOST_REBIND (60 * HZ) | 28 | #define NLM_HOST_REBIND (60 * HZ) |
@@ -41,11 +43,10 @@ static struct hlist_head nlm_client_hosts[NLM_HOST_NRHASH]; | |||
41 | hlist_for_each_entry_safe((host), (pos), (next), \ | 43 | hlist_for_each_entry_safe((host), (pos), (next), \ |
42 | (chain), h_hash) | 44 | (chain), h_hash) |
43 | 45 | ||
44 | static unsigned long next_gc; | ||
45 | static unsigned long nrhosts; | 46 | static unsigned long nrhosts; |
46 | static DEFINE_MUTEX(nlm_host_mutex); | 47 | static DEFINE_MUTEX(nlm_host_mutex); |
47 | 48 | ||
48 | static void nlm_gc_hosts(void); | 49 | static void nlm_gc_hosts(struct net *net); |
49 | 50 | ||
50 | struct nlm_lookup_host_info { | 51 | struct nlm_lookup_host_info { |
51 | const int server; /* search for server|client */ | 52 | const int server; /* search for server|client */ |
@@ -172,6 +173,7 @@ out: | |||
172 | static void nlm_destroy_host_locked(struct nlm_host *host) | 173 | static void nlm_destroy_host_locked(struct nlm_host *host) |
173 | { | 174 | { |
174 | struct rpc_clnt *clnt; | 175 | struct rpc_clnt *clnt; |
176 | struct lockd_net *ln = net_generic(host->net, lockd_net_id); | ||
175 | 177 | ||
176 | dprintk("lockd: destroy host %s\n", host->h_name); | 178 | dprintk("lockd: destroy host %s\n", host->h_name); |
177 | 179 | ||
@@ -188,6 +190,7 @@ static void nlm_destroy_host_locked(struct nlm_host *host) | |||
188 | rpc_shutdown_client(clnt); | 190 | rpc_shutdown_client(clnt); |
189 | kfree(host); | 191 | kfree(host); |
190 | 192 | ||
193 | ln->nrhosts--; | ||
191 | nrhosts--; | 194 | nrhosts--; |
192 | } | 195 | } |
193 | 196 | ||
@@ -228,6 +231,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
228 | struct hlist_node *pos; | 231 | struct hlist_node *pos; |
229 | struct nlm_host *host; | 232 | struct nlm_host *host; |
230 | struct nsm_handle *nsm = NULL; | 233 | struct nsm_handle *nsm = NULL; |
234 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
231 | 235 | ||
232 | dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, | 236 | dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, |
233 | (hostname ? hostname : "<none>"), version, | 237 | (hostname ? hostname : "<none>"), version, |
@@ -262,6 +266,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, | |||
262 | goto out; | 266 | goto out; |
263 | 267 | ||
264 | hlist_add_head(&host->h_hash, chain); | 268 | hlist_add_head(&host->h_hash, chain); |
269 | ln->nrhosts++; | ||
265 | nrhosts++; | 270 | nrhosts++; |
266 | 271 | ||
267 | dprintk("lockd: %s created host %s (%s)\n", __func__, | 272 | dprintk("lockd: %s created host %s (%s)\n", __func__, |
@@ -326,7 +331,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
326 | struct nsm_handle *nsm = NULL; | 331 | struct nsm_handle *nsm = NULL; |
327 | struct sockaddr *src_sap = svc_daddr(rqstp); | 332 | struct sockaddr *src_sap = svc_daddr(rqstp); |
328 | size_t src_len = rqstp->rq_daddrlen; | 333 | size_t src_len = rqstp->rq_daddrlen; |
329 | struct net *net = rqstp->rq_xprt->xpt_net; | 334 | struct net *net = SVC_NET(rqstp); |
330 | struct nlm_lookup_host_info ni = { | 335 | struct nlm_lookup_host_info ni = { |
331 | .server = 1, | 336 | .server = 1, |
332 | .sap = svc_addr(rqstp), | 337 | .sap = svc_addr(rqstp), |
@@ -337,6 +342,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
337 | .hostname_len = hostname_len, | 342 | .hostname_len = hostname_len, |
338 | .net = net, | 343 | .net = net, |
339 | }; | 344 | }; |
345 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
340 | 346 | ||
341 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, | 347 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, |
342 | (int)hostname_len, hostname, rqstp->rq_vers, | 348 | (int)hostname_len, hostname, rqstp->rq_vers, |
@@ -344,8 +350,8 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
344 | 350 | ||
345 | mutex_lock(&nlm_host_mutex); | 351 | mutex_lock(&nlm_host_mutex); |
346 | 352 | ||
347 | if (time_after_eq(jiffies, next_gc)) | 353 | if (time_after_eq(jiffies, ln->next_gc)) |
348 | nlm_gc_hosts(); | 354 | nlm_gc_hosts(net); |
349 | 355 | ||
350 | chain = &nlm_server_hosts[nlm_hash_address(ni.sap)]; | 356 | chain = &nlm_server_hosts[nlm_hash_address(ni.sap)]; |
351 | hlist_for_each_entry(host, pos, chain, h_hash) { | 357 | hlist_for_each_entry(host, pos, chain, h_hash) { |
@@ -382,6 +388,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, | |||
382 | memcpy(nlm_srcaddr(host), src_sap, src_len); | 388 | memcpy(nlm_srcaddr(host), src_sap, src_len); |
383 | host->h_srcaddrlen = src_len; | 389 | host->h_srcaddrlen = src_len; |
384 | hlist_add_head(&host->h_hash, chain); | 390 | hlist_add_head(&host->h_hash, chain); |
391 | ln->nrhosts++; | ||
385 | nrhosts++; | 392 | nrhosts++; |
386 | 393 | ||
387 | dprintk("lockd: %s created host %s (%s)\n", | 394 | dprintk("lockd: %s created host %s (%s)\n", |
@@ -565,6 +572,35 @@ void nlm_host_rebooted(const struct nlm_reboot *info) | |||
565 | nsm_release(nsm); | 572 | nsm_release(nsm); |
566 | } | 573 | } |
567 | 574 | ||
575 | static void nlm_complain_hosts(struct net *net) | ||
576 | { | ||
577 | struct hlist_head *chain; | ||
578 | struct hlist_node *pos; | ||
579 | struct nlm_host *host; | ||
580 | |||
581 | if (net) { | ||
582 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
583 | |||
584 | if (ln->nrhosts == 0) | ||
585 | return; | ||
586 | printk(KERN_WARNING "lockd: couldn't shutdown host module for net %p!\n", net); | ||
587 | dprintk("lockd: %lu hosts left in net %p:\n", ln->nrhosts, net); | ||
588 | } else { | ||
589 | if (nrhosts == 0) | ||
590 | return; | ||
591 | printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); | ||
592 | dprintk("lockd: %lu hosts left:\n", nrhosts); | ||
593 | } | ||
594 | |||
595 | for_each_host(host, pos, chain, nlm_server_hosts) { | ||
596 | if (net && host->net != net) | ||
597 | continue; | ||
598 | dprintk(" %s (cnt %d use %d exp %ld net %p)\n", | ||
599 | host->h_name, atomic_read(&host->h_count), | ||
600 | host->h_inuse, host->h_expires, host->net); | ||
601 | } | ||
602 | } | ||
603 | |||
568 | void | 604 | void |
569 | nlm_shutdown_hosts_net(struct net *net) | 605 | nlm_shutdown_hosts_net(struct net *net) |
570 | { | 606 | { |
@@ -572,11 +608,10 @@ nlm_shutdown_hosts_net(struct net *net) | |||
572 | struct hlist_node *pos; | 608 | struct hlist_node *pos; |
573 | struct nlm_host *host; | 609 | struct nlm_host *host; |
574 | 610 | ||
575 | dprintk("lockd: shutting down host module\n"); | ||
576 | mutex_lock(&nlm_host_mutex); | 611 | mutex_lock(&nlm_host_mutex); |
577 | 612 | ||
578 | /* First, make all hosts eligible for gc */ | 613 | /* First, make all hosts eligible for gc */ |
579 | dprintk("lockd: nuking all hosts...\n"); | 614 | dprintk("lockd: nuking all hosts in net %p...\n", net); |
580 | for_each_host(host, pos, chain, nlm_server_hosts) { | 615 | for_each_host(host, pos, chain, nlm_server_hosts) { |
581 | if (net && host->net != net) | 616 | if (net && host->net != net) |
582 | continue; | 617 | continue; |
@@ -588,8 +623,10 @@ nlm_shutdown_hosts_net(struct net *net) | |||
588 | } | 623 | } |
589 | 624 | ||
590 | /* Then, perform a garbage collection pass */ | 625 | /* Then, perform a garbage collection pass */ |
591 | nlm_gc_hosts(); | 626 | nlm_gc_hosts(net); |
592 | mutex_unlock(&nlm_host_mutex); | 627 | mutex_unlock(&nlm_host_mutex); |
628 | |||
629 | nlm_complain_hosts(net); | ||
593 | } | 630 | } |
594 | 631 | ||
595 | /* | 632 | /* |
@@ -599,22 +636,8 @@ nlm_shutdown_hosts_net(struct net *net) | |||
599 | void | 636 | void |
600 | nlm_shutdown_hosts(void) | 637 | nlm_shutdown_hosts(void) |
601 | { | 638 | { |
602 | struct hlist_head *chain; | 639 | dprintk("lockd: shutting down host module\n"); |
603 | struct hlist_node *pos; | ||
604 | struct nlm_host *host; | ||
605 | |||
606 | nlm_shutdown_hosts_net(NULL); | 640 | nlm_shutdown_hosts_net(NULL); |
607 | |||
608 | /* complain if any hosts are left */ | ||
609 | if (nrhosts != 0) { | ||
610 | printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); | ||
611 | dprintk("lockd: %lu hosts left:\n", nrhosts); | ||
612 | for_each_host(host, pos, chain, nlm_server_hosts) { | ||
613 | dprintk(" %s (cnt %d use %d exp %ld net %p)\n", | ||
614 | host->h_name, atomic_read(&host->h_count), | ||
615 | host->h_inuse, host->h_expires, host->net); | ||
616 | } | ||
617 | } | ||
618 | } | 641 | } |
619 | 642 | ||
620 | /* | 643 | /* |
@@ -623,30 +646,39 @@ nlm_shutdown_hosts(void) | |||
623 | * mark & sweep for resources held by remote clients. | 646 | * mark & sweep for resources held by remote clients. |
624 | */ | 647 | */ |
625 | static void | 648 | static void |
626 | nlm_gc_hosts(void) | 649 | nlm_gc_hosts(struct net *net) |
627 | { | 650 | { |
628 | struct hlist_head *chain; | 651 | struct hlist_head *chain; |
629 | struct hlist_node *pos, *next; | 652 | struct hlist_node *pos, *next; |
630 | struct nlm_host *host; | 653 | struct nlm_host *host; |
631 | 654 | ||
632 | dprintk("lockd: host garbage collection\n"); | 655 | dprintk("lockd: host garbage collection for net %p\n", net); |
633 | for_each_host(host, pos, chain, nlm_server_hosts) | 656 | for_each_host(host, pos, chain, nlm_server_hosts) { |
657 | if (net && host->net != net) | ||
658 | continue; | ||
634 | host->h_inuse = 0; | 659 | host->h_inuse = 0; |
660 | } | ||
635 | 661 | ||
636 | /* Mark all hosts that hold locks, blocks or shares */ | 662 | /* Mark all hosts that hold locks, blocks or shares */ |
637 | nlmsvc_mark_resources(); | 663 | nlmsvc_mark_resources(net); |
638 | 664 | ||
639 | for_each_host_safe(host, pos, next, chain, nlm_server_hosts) { | 665 | for_each_host_safe(host, pos, next, chain, nlm_server_hosts) { |
666 | if (net && host->net != net) | ||
667 | continue; | ||
640 | if (atomic_read(&host->h_count) || host->h_inuse | 668 | if (atomic_read(&host->h_count) || host->h_inuse |
641 | || time_before(jiffies, host->h_expires)) { | 669 | || time_before(jiffies, host->h_expires)) { |
642 | dprintk("nlm_gc_hosts skipping %s " | 670 | dprintk("nlm_gc_hosts skipping %s " |
643 | "(cnt %d use %d exp %ld)\n", | 671 | "(cnt %d use %d exp %ld net %p)\n", |
644 | host->h_name, atomic_read(&host->h_count), | 672 | host->h_name, atomic_read(&host->h_count), |
645 | host->h_inuse, host->h_expires); | 673 | host->h_inuse, host->h_expires, host->net); |
646 | continue; | 674 | continue; |
647 | } | 675 | } |
648 | nlm_destroy_host_locked(host); | 676 | nlm_destroy_host_locked(host); |
649 | } | 677 | } |
650 | 678 | ||
651 | next_gc = jiffies + NLM_HOST_COLLECT; | 679 | if (net) { |
680 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
681 | |||
682 | ln->next_gc = jiffies + NLM_HOST_COLLECT; | ||
683 | } | ||
652 | } | 684 | } |
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h index ce227e0fbc5c..4eee248ba96e 100644 --- a/fs/lockd/netns.h +++ b/fs/lockd/netns.h | |||
@@ -1,10 +1,17 @@ | |||
1 | #ifndef __LOCKD_NETNS_H__ | 1 | #ifndef __LOCKD_NETNS_H__ |
2 | #define __LOCKD_NETNS_H__ | 2 | #define __LOCKD_NETNS_H__ |
3 | 3 | ||
4 | #include <linux/fs.h> | ||
4 | #include <net/netns/generic.h> | 5 | #include <net/netns/generic.h> |
5 | 6 | ||
6 | struct lockd_net { | 7 | struct lockd_net { |
7 | unsigned int nlmsvc_users; | 8 | unsigned int nlmsvc_users; |
9 | unsigned long next_gc; | ||
10 | unsigned long nrhosts; | ||
11 | |||
12 | struct delayed_work grace_period_end; | ||
13 | struct lock_manager lockd_manager; | ||
14 | struct list_head grace_list; | ||
8 | }; | 15 | }; |
9 | 16 | ||
10 | extern int lockd_net_id; | 17 | extern int lockd_net_id; |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 80938fda67e0..31a63f87b806 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -87,32 +87,36 @@ static unsigned long get_lockd_grace_period(void) | |||
87 | return nlm_timeout * 5 * HZ; | 87 | return nlm_timeout * 5 * HZ; |
88 | } | 88 | } |
89 | 89 | ||
90 | static struct lock_manager lockd_manager = { | 90 | static void grace_ender(struct work_struct *grace) |
91 | }; | ||
92 | |||
93 | static void grace_ender(struct work_struct *not_used) | ||
94 | { | 91 | { |
95 | locks_end_grace(&lockd_manager); | 92 | struct delayed_work *dwork = container_of(grace, struct delayed_work, |
96 | } | 93 | work); |
94 | struct lockd_net *ln = container_of(dwork, struct lockd_net, | ||
95 | grace_period_end); | ||
97 | 96 | ||
98 | static DECLARE_DELAYED_WORK(grace_period_end, grace_ender); | 97 | locks_end_grace(&ln->lockd_manager); |
98 | } | ||
99 | 99 | ||
100 | static void set_grace_period(void) | 100 | static void set_grace_period(struct net *net) |
101 | { | 101 | { |
102 | unsigned long grace_period = get_lockd_grace_period(); | 102 | unsigned long grace_period = get_lockd_grace_period(); |
103 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
103 | 104 | ||
104 | locks_start_grace(&lockd_manager); | 105 | locks_start_grace(net, &ln->lockd_manager); |
105 | cancel_delayed_work_sync(&grace_period_end); | 106 | cancel_delayed_work_sync(&ln->grace_period_end); |
106 | schedule_delayed_work(&grace_period_end, grace_period); | 107 | schedule_delayed_work(&ln->grace_period_end, grace_period); |
107 | } | 108 | } |
108 | 109 | ||
109 | static void restart_grace(void) | 110 | static void restart_grace(void) |
110 | { | 111 | { |
111 | if (nlmsvc_ops) { | 112 | if (nlmsvc_ops) { |
112 | cancel_delayed_work_sync(&grace_period_end); | 113 | struct net *net = &init_net; |
113 | locks_end_grace(&lockd_manager); | 114 | struct lockd_net *ln = net_generic(net, lockd_net_id); |
115 | |||
116 | cancel_delayed_work_sync(&ln->grace_period_end); | ||
117 | locks_end_grace(&ln->lockd_manager); | ||
114 | nlmsvc_invalidate_all(); | 118 | nlmsvc_invalidate_all(); |
115 | set_grace_period(); | 119 | set_grace_period(net); |
116 | } | 120 | } |
117 | } | 121 | } |
118 | 122 | ||
@@ -137,8 +141,6 @@ lockd(void *vrqstp) | |||
137 | nlm_timeout = LOCKD_DFLT_TIMEO; | 141 | nlm_timeout = LOCKD_DFLT_TIMEO; |
138 | nlmsvc_timeout = nlm_timeout * HZ; | 142 | nlmsvc_timeout = nlm_timeout * HZ; |
139 | 143 | ||
140 | set_grace_period(); | ||
141 | |||
142 | /* | 144 | /* |
143 | * The main request loop. We don't terminate until the last | 145 | * The main request loop. We don't terminate until the last |
144 | * NFS mount or NFS daemon has gone away. | 146 | * NFS mount or NFS daemon has gone away. |
@@ -184,8 +186,6 @@ lockd(void *vrqstp) | |||
184 | svc_process(rqstp); | 186 | svc_process(rqstp); |
185 | } | 187 | } |
186 | flush_signals(current); | 188 | flush_signals(current); |
187 | cancel_delayed_work_sync(&grace_period_end); | ||
188 | locks_end_grace(&lockd_manager); | ||
189 | if (nlmsvc_ops) | 189 | if (nlmsvc_ops) |
190 | nlmsvc_invalidate_all(); | 190 | nlmsvc_invalidate_all(); |
191 | nlm_shutdown_hosts(); | 191 | nlm_shutdown_hosts(); |
@@ -266,6 +266,7 @@ static int lockd_up_net(struct svc_serv *serv, struct net *net) | |||
266 | error = make_socks(serv, net); | 266 | error = make_socks(serv, net); |
267 | if (error < 0) | 267 | if (error < 0) |
268 | goto err_socks; | 268 | goto err_socks; |
269 | set_grace_period(net); | ||
269 | dprintk("lockd_up_net: per-net data created; net=%p\n", net); | 270 | dprintk("lockd_up_net: per-net data created; net=%p\n", net); |
270 | return 0; | 271 | return 0; |
271 | 272 | ||
@@ -283,6 +284,8 @@ static void lockd_down_net(struct svc_serv *serv, struct net *net) | |||
283 | if (ln->nlmsvc_users) { | 284 | if (ln->nlmsvc_users) { |
284 | if (--ln->nlmsvc_users == 0) { | 285 | if (--ln->nlmsvc_users == 0) { |
285 | nlm_shutdown_hosts_net(net); | 286 | nlm_shutdown_hosts_net(net); |
287 | cancel_delayed_work_sync(&ln->grace_period_end); | ||
288 | locks_end_grace(&ln->lockd_manager); | ||
286 | svc_shutdown_net(serv, net); | 289 | svc_shutdown_net(serv, net); |
287 | dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); | 290 | dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); |
288 | } | 291 | } |
@@ -589,6 +592,10 @@ module_param(nlm_max_connections, uint, 0644); | |||
589 | 592 | ||
590 | static int lockd_init_net(struct net *net) | 593 | static int lockd_init_net(struct net *net) |
591 | { | 594 | { |
595 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
596 | |||
597 | INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); | ||
598 | INIT_LIST_HEAD(&ln->grace_list); | ||
592 | return 0; | 599 | return 0; |
593 | } | 600 | } |
594 | 601 | ||
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 185fda894789..b147d1ae71fd 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/lockd/lockd.h> | 12 | #include <linux/lockd/lockd.h> |
13 | #include <linux/lockd/share.h> | 13 | #include <linux/lockd/share.h> |
14 | #include <linux/sunrpc/svc_xprt.h> | ||
14 | 15 | ||
15 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 16 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
16 | 17 | ||
@@ -151,7 +152,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
151 | resp->cookie = argp->cookie; | 152 | resp->cookie = argp->cookie; |
152 | 153 | ||
153 | /* Don't accept requests during grace period */ | 154 | /* Don't accept requests during grace period */ |
154 | if (locks_in_grace()) { | 155 | if (locks_in_grace(SVC_NET(rqstp))) { |
155 | resp->status = nlm_lck_denied_grace_period; | 156 | resp->status = nlm_lck_denied_grace_period; |
156 | return rpc_success; | 157 | return rpc_success; |
157 | } | 158 | } |
@@ -161,7 +162,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
161 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 162 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
162 | 163 | ||
163 | /* Try to cancel request. */ | 164 | /* Try to cancel request. */ |
164 | resp->status = nlmsvc_cancel_blocked(file, &argp->lock); | 165 | resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock); |
165 | 166 | ||
166 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); | 167 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); |
167 | nlmsvc_release_host(host); | 168 | nlmsvc_release_host(host); |
@@ -184,7 +185,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
184 | resp->cookie = argp->cookie; | 185 | resp->cookie = argp->cookie; |
185 | 186 | ||
186 | /* Don't accept new lock requests during grace period */ | 187 | /* Don't accept new lock requests during grace period */ |
187 | if (locks_in_grace()) { | 188 | if (locks_in_grace(SVC_NET(rqstp))) { |
188 | resp->status = nlm_lck_denied_grace_period; | 189 | resp->status = nlm_lck_denied_grace_period; |
189 | return rpc_success; | 190 | return rpc_success; |
190 | } | 191 | } |
@@ -194,7 +195,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
194 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 195 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
195 | 196 | ||
196 | /* Now try to remove the lock */ | 197 | /* Now try to remove the lock */ |
197 | resp->status = nlmsvc_unlock(file, &argp->lock); | 198 | resp->status = nlmsvc_unlock(SVC_NET(rqstp), file, &argp->lock); |
198 | 199 | ||
199 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); | 200 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); |
200 | nlmsvc_release_host(host); | 201 | nlmsvc_release_host(host); |
@@ -322,7 +323,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
322 | resp->cookie = argp->cookie; | 323 | resp->cookie = argp->cookie; |
323 | 324 | ||
324 | /* Don't accept new lock requests during grace period */ | 325 | /* Don't accept new lock requests during grace period */ |
325 | if (locks_in_grace() && !argp->reclaim) { | 326 | if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) { |
326 | resp->status = nlm_lck_denied_grace_period; | 327 | resp->status = nlm_lck_denied_grace_period; |
327 | return rpc_success; | 328 | return rpc_success; |
328 | } | 329 | } |
@@ -355,7 +356,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
355 | resp->cookie = argp->cookie; | 356 | resp->cookie = argp->cookie; |
356 | 357 | ||
357 | /* Don't accept requests during grace period */ | 358 | /* Don't accept requests during grace period */ |
358 | if (locks_in_grace()) { | 359 | if (locks_in_grace(SVC_NET(rqstp))) { |
359 | resp->status = nlm_lck_denied_grace_period; | 360 | resp->status = nlm_lck_denied_grace_period; |
360 | return rpc_success; | 361 | return rpc_success; |
361 | } | 362 | } |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index b54acaf65987..fb1a2bedbe97 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/sunrpc/clnt.h> | 28 | #include <linux/sunrpc/clnt.h> |
29 | #include <linux/sunrpc/svc.h> | 29 | #include <linux/sunrpc/svc_xprt.h> |
30 | #include <linux/lockd/nlm.h> | 30 | #include <linux/lockd/nlm.h> |
31 | #include <linux/lockd/lockd.h> | 31 | #include <linux/lockd/lockd.h> |
32 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
@@ -446,11 +446,11 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
446 | goto out; | 446 | goto out; |
447 | } | 447 | } |
448 | 448 | ||
449 | if (locks_in_grace() && !reclaim) { | 449 | if (locks_in_grace(SVC_NET(rqstp)) && !reclaim) { |
450 | ret = nlm_lck_denied_grace_period; | 450 | ret = nlm_lck_denied_grace_period; |
451 | goto out; | 451 | goto out; |
452 | } | 452 | } |
453 | if (reclaim && !locks_in_grace()) { | 453 | if (reclaim && !locks_in_grace(SVC_NET(rqstp))) { |
454 | ret = nlm_lck_denied_grace_period; | 454 | ret = nlm_lck_denied_grace_period; |
455 | goto out; | 455 | goto out; |
456 | } | 456 | } |
@@ -558,7 +558,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
558 | goto out; | 558 | goto out; |
559 | } | 559 | } |
560 | 560 | ||
561 | if (locks_in_grace()) { | 561 | if (locks_in_grace(SVC_NET(rqstp))) { |
562 | ret = nlm_lck_denied_grace_period; | 562 | ret = nlm_lck_denied_grace_period; |
563 | goto out; | 563 | goto out; |
564 | } | 564 | } |
@@ -602,7 +602,7 @@ out: | |||
602 | * must be removed. | 602 | * must be removed. |
603 | */ | 603 | */ |
604 | __be32 | 604 | __be32 |
605 | nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) | 605 | nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock) |
606 | { | 606 | { |
607 | int error; | 607 | int error; |
608 | 608 | ||
@@ -614,7 +614,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) | |||
614 | (long long)lock->fl.fl_end); | 614 | (long long)lock->fl.fl_end); |
615 | 615 | ||
616 | /* First, cancel any lock that might be there */ | 616 | /* First, cancel any lock that might be there */ |
617 | nlmsvc_cancel_blocked(file, lock); | 617 | nlmsvc_cancel_blocked(net, file, lock); |
618 | 618 | ||
619 | lock->fl.fl_type = F_UNLCK; | 619 | lock->fl.fl_type = F_UNLCK; |
620 | error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); | 620 | error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); |
@@ -630,7 +630,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) | |||
630 | * The calling procedure must check whether the file can be closed. | 630 | * The calling procedure must check whether the file can be closed. |
631 | */ | 631 | */ |
632 | __be32 | 632 | __be32 |
633 | nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | 633 | nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *lock) |
634 | { | 634 | { |
635 | struct nlm_block *block; | 635 | struct nlm_block *block; |
636 | int status = 0; | 636 | int status = 0; |
@@ -642,7 +642,7 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | |||
642 | (long long)lock->fl.fl_start, | 642 | (long long)lock->fl.fl_start, |
643 | (long long)lock->fl.fl_end); | 643 | (long long)lock->fl.fl_end); |
644 | 644 | ||
645 | if (locks_in_grace()) | 645 | if (locks_in_grace(net)) |
646 | return nlm_lck_denied_grace_period; | 646 | return nlm_lck_denied_grace_period; |
647 | 647 | ||
648 | mutex_lock(&file->f_mutex); | 648 | mutex_lock(&file->f_mutex); |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 90cfe9a0bf55..3009a365e082 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/lockd/lockd.h> | 12 | #include <linux/lockd/lockd.h> |
13 | #include <linux/lockd/share.h> | 13 | #include <linux/lockd/share.h> |
14 | #include <linux/sunrpc/svc_xprt.h> | ||
14 | 15 | ||
15 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 16 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
16 | 17 | ||
@@ -175,13 +176,14 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
175 | { | 176 | { |
176 | struct nlm_host *host; | 177 | struct nlm_host *host; |
177 | struct nlm_file *file; | 178 | struct nlm_file *file; |
179 | struct net *net = SVC_NET(rqstp); | ||
178 | 180 | ||
179 | dprintk("lockd: CANCEL called\n"); | 181 | dprintk("lockd: CANCEL called\n"); |
180 | 182 | ||
181 | resp->cookie = argp->cookie; | 183 | resp->cookie = argp->cookie; |
182 | 184 | ||
183 | /* Don't accept requests during grace period */ | 185 | /* Don't accept requests during grace period */ |
184 | if (locks_in_grace()) { | 186 | if (locks_in_grace(net)) { |
185 | resp->status = nlm_lck_denied_grace_period; | 187 | resp->status = nlm_lck_denied_grace_period; |
186 | return rpc_success; | 188 | return rpc_success; |
187 | } | 189 | } |
@@ -191,7 +193,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
191 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 193 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
192 | 194 | ||
193 | /* Try to cancel request. */ | 195 | /* Try to cancel request. */ |
194 | resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); | 196 | resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock)); |
195 | 197 | ||
196 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); | 198 | dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); |
197 | nlmsvc_release_host(host); | 199 | nlmsvc_release_host(host); |
@@ -208,13 +210,14 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
208 | { | 210 | { |
209 | struct nlm_host *host; | 211 | struct nlm_host *host; |
210 | struct nlm_file *file; | 212 | struct nlm_file *file; |
213 | struct net *net = SVC_NET(rqstp); | ||
211 | 214 | ||
212 | dprintk("lockd: UNLOCK called\n"); | 215 | dprintk("lockd: UNLOCK called\n"); |
213 | 216 | ||
214 | resp->cookie = argp->cookie; | 217 | resp->cookie = argp->cookie; |
215 | 218 | ||
216 | /* Don't accept new lock requests during grace period */ | 219 | /* Don't accept new lock requests during grace period */ |
217 | if (locks_in_grace()) { | 220 | if (locks_in_grace(net)) { |
218 | resp->status = nlm_lck_denied_grace_period; | 221 | resp->status = nlm_lck_denied_grace_period; |
219 | return rpc_success; | 222 | return rpc_success; |
220 | } | 223 | } |
@@ -224,7 +227,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
224 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 227 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
225 | 228 | ||
226 | /* Now try to remove the lock */ | 229 | /* Now try to remove the lock */ |
227 | resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); | 230 | resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock)); |
228 | 231 | ||
229 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); | 232 | dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); |
230 | nlmsvc_release_host(host); | 233 | nlmsvc_release_host(host); |
@@ -362,7 +365,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
362 | resp->cookie = argp->cookie; | 365 | resp->cookie = argp->cookie; |
363 | 366 | ||
364 | /* Don't accept new lock requests during grace period */ | 367 | /* Don't accept new lock requests during grace period */ |
365 | if (locks_in_grace() && !argp->reclaim) { | 368 | if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) { |
366 | resp->status = nlm_lck_denied_grace_period; | 369 | resp->status = nlm_lck_denied_grace_period; |
367 | return rpc_success; | 370 | return rpc_success; |
368 | } | 371 | } |
@@ -395,7 +398,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
395 | resp->cookie = argp->cookie; | 398 | resp->cookie = argp->cookie; |
396 | 399 | ||
397 | /* Don't accept requests during grace period */ | 400 | /* Don't accept requests during grace period */ |
398 | if (locks_in_grace()) { | 401 | if (locks_in_grace(SVC_NET(rqstp))) { |
399 | resp->status = nlm_lck_denied_grace_period; | 402 | resp->status = nlm_lck_denied_grace_period; |
400 | return rpc_success; | 403 | return rpc_success; |
401 | } | 404 | } |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 2240d384d787..0deb5f6c9dd4 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
@@ -309,7 +309,8 @@ nlm_release_file(struct nlm_file *file) | |||
309 | * Helpers function for resource traversal | 309 | * Helpers function for resource traversal |
310 | * | 310 | * |
311 | * nlmsvc_mark_host: | 311 | * nlmsvc_mark_host: |
312 | * used by the garbage collector; simply sets h_inuse. | 312 | * used by the garbage collector; simply sets h_inuse only for those |
313 | * hosts, which passed network check. | ||
313 | * Always returns 0. | 314 | * Always returns 0. |
314 | * | 315 | * |
315 | * nlmsvc_same_host: | 316 | * nlmsvc_same_host: |
@@ -320,12 +321,15 @@ nlm_release_file(struct nlm_file *file) | |||
320 | * returns 1 iff the host is a client. | 321 | * returns 1 iff the host is a client. |
321 | * Used by nlmsvc_invalidate_all | 322 | * Used by nlmsvc_invalidate_all |
322 | */ | 323 | */ |
324 | |||
323 | static int | 325 | static int |
324 | nlmsvc_mark_host(void *data, struct nlm_host *dummy) | 326 | nlmsvc_mark_host(void *data, struct nlm_host *hint) |
325 | { | 327 | { |
326 | struct nlm_host *host = data; | 328 | struct nlm_host *host = data; |
327 | 329 | ||
328 | host->h_inuse = 1; | 330 | if ((hint->net == NULL) || |
331 | (host->net == hint->net)) | ||
332 | host->h_inuse = 1; | ||
329 | return 0; | 333 | return 0; |
330 | } | 334 | } |
331 | 335 | ||
@@ -358,10 +362,13 @@ nlmsvc_is_client(void *data, struct nlm_host *dummy) | |||
358 | * Mark all hosts that still hold resources | 362 | * Mark all hosts that still hold resources |
359 | */ | 363 | */ |
360 | void | 364 | void |
361 | nlmsvc_mark_resources(void) | 365 | nlmsvc_mark_resources(struct net *net) |
362 | { | 366 | { |
363 | dprintk("lockd: nlmsvc_mark_resources\n"); | 367 | struct nlm_host hint; |
364 | nlm_traverse_files(NULL, nlmsvc_mark_host, NULL); | 368 | |
369 | dprintk("lockd: nlmsvc_mark_resources for net %p\n", net); | ||
370 | hint.net = net; | ||
371 | nlm_traverse_files(&hint, nlmsvc_mark_host, NULL); | ||
365 | } | 372 | } |
366 | 373 | ||
367 | /* | 374 | /* |