aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd')
-rw-r--r--fs/lockd/grace.c16
-rw-r--r--fs/lockd/host.c92
-rw-r--r--fs/lockd/netns.h7
-rw-r--r--fs/lockd/svc.c43
-rw-r--r--fs/lockd/svc4proc.c13
-rw-r--r--fs/lockd/svclock.c16
-rw-r--r--fs/lockd/svcproc.c15
-rw-r--r--fs/lockd/svcsubs.c19
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
8static LIST_HEAD(grace_list);
9static DEFINE_SPINLOCK(grace_lock); 11static 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 */
22void locks_start_grace(struct lock_manager *lm) 24void 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}
28EXPORT_SYMBOL_GPL(locks_start_grace); 32EXPORT_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 */
55int locks_in_grace(void) 59int 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}
59EXPORT_SYMBOL_GPL(locks_in_grace); 65EXPORT_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
44static unsigned long next_gc;
45static unsigned long nrhosts; 46static unsigned long nrhosts;
46static DEFINE_MUTEX(nlm_host_mutex); 47static DEFINE_MUTEX(nlm_host_mutex);
47 48
48static void nlm_gc_hosts(void); 49static void nlm_gc_hosts(struct net *net);
49 50
50struct nlm_lookup_host_info { 51struct 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:
172static void nlm_destroy_host_locked(struct nlm_host *host) 173static 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
575static 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
568void 604void
569nlm_shutdown_hosts_net(struct net *net) 605nlm_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)
599void 636void
600nlm_shutdown_hosts(void) 637nlm_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 */
625static void 648static void
626nlm_gc_hosts(void) 649nlm_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
6struct lockd_net { 7struct 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
10extern int lockd_net_id; 17extern 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
90static struct lock_manager lockd_manager = { 90static void grace_ender(struct work_struct *grace)
91};
92
93static 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
98static DECLARE_DELAYED_WORK(grace_period_end, grace_ender); 97 locks_end_grace(&ln->lockd_manager);
98}
99 99
100static void set_grace_period(void) 100static 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
109static void restart_grace(void) 110static 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
590static int lockd_init_net(struct net *net) 593static 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
605nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock) 605nlmsvc_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
633nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) 633nlmsvc_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
323static int 325static int
324nlmsvc_mark_host(void *data, struct nlm_host *dummy) 326nlmsvc_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 */
360void 364void
361nlmsvc_mark_resources(void) 365nlmsvc_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/*