aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd')
-rw-r--r--fs/lockd/Makefile2
-rw-r--r--fs/lockd/grace.c59
-rw-r--r--fs/lockd/svc.c20
-rw-r--r--fs/lockd/svc4proc.c12
-rw-r--r--fs/lockd/svcproc.c12
5 files changed, 77 insertions, 28 deletions
diff --git a/fs/lockd/Makefile b/fs/lockd/Makefile
index 7725a0a9a555..97f6073ab339 100644
--- a/fs/lockd/Makefile
+++ b/fs/lockd/Makefile
@@ -5,6 +5,6 @@
5obj-$(CONFIG_LOCKD) += lockd.o 5obj-$(CONFIG_LOCKD) += lockd.o
6 6
7lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \ 7lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \
8 svcproc.o svcsubs.o mon.o xdr.o 8 svcproc.o svcsubs.o mon.o xdr.o grace.o
9lockd-objs-$(CONFIG_LOCKD_V4) += xdr4.o svc4proc.o 9lockd-objs-$(CONFIG_LOCKD_V4) += xdr4.o svc4proc.o
10lockd-objs := $(lockd-objs-y) 10lockd-objs := $(lockd-objs-y)
diff --git a/fs/lockd/grace.c b/fs/lockd/grace.c
new file mode 100644
index 000000000000..183cc1f0af1c
--- /dev/null
+++ b/fs/lockd/grace.c
@@ -0,0 +1,59 @@
1/*
2 * Common code for control of lockd and nfsv4 grace periods.
3 */
4
5#include <linux/module.h>
6#include <linux/lockd/bind.h>
7
8static LIST_HEAD(grace_list);
9static DEFINE_SPINLOCK(grace_lock);
10
11/**
12 * locks_start_grace
13 * @lm: who this grace period is for
14 *
15 * A grace period is a period during which locks should not be given
16 * out. Currently grace periods are only enforced by the two lock
17 * managers (lockd and nfsd), using the locks_in_grace() function to
18 * check when they are in a grace period.
19 *
20 * This function is called to start a grace period.
21 */
22void locks_start_grace(struct lock_manager *lm)
23{
24 spin_lock(&grace_lock);
25 list_add(&lm->list, &grace_list);
26 spin_unlock(&grace_lock);
27}
28EXPORT_SYMBOL_GPL(locks_start_grace);
29
30/**
31 * locks_end_grace
32 * @lm: who this grace period is for
33 *
34 * Call this function to state that the given lock manager is ready to
35 * resume regular locking. The grace period will not end until all lock
36 * managers that called locks_start_grace() also call locks_end_grace().
37 * Note that callers count on it being safe to call this more than once,
38 * and the second call should be a no-op.
39 */
40void locks_end_grace(struct lock_manager *lm)
41{
42 spin_lock(&grace_lock);
43 list_del_init(&lm->list);
44 spin_unlock(&grace_lock);
45}
46EXPORT_SYMBOL_GPL(locks_end_grace);
47
48/**
49 * locks_in_grace
50 *
51 * Lock managers call this function to determine when it is OK for them
52 * to answer ordinary lock requests, and when they should accept only
53 * lock reclaims.
54 */
55int locks_in_grace(void)
56{
57 return !list_empty(&grace_list);
58}
59EXPORT_SYMBOL_GPL(locks_in_grace);
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index f345ef7fb8ae..f013aed11533 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -51,7 +51,6 @@ static DEFINE_MUTEX(nlmsvc_mutex);
51static unsigned int nlmsvc_users; 51static unsigned int nlmsvc_users;
52static struct task_struct *nlmsvc_task; 52static struct task_struct *nlmsvc_task;
53static struct svc_rqst *nlmsvc_rqst; 53static struct svc_rqst *nlmsvc_rqst;
54int nlmsvc_grace_period;
55unsigned long nlmsvc_timeout; 54unsigned long nlmsvc_timeout;
56 55
57/* 56/*
@@ -85,30 +84,21 @@ static unsigned long get_lockd_grace_period(void)
85 return nlm_timeout * 5 * HZ; 84 return nlm_timeout * 5 * HZ;
86} 85}
87 86
88unsigned long get_nfs_grace_period(void) 87static struct lock_manager lockd_manager = {
89{ 88};
90 unsigned long lockdgrace = get_lockd_grace_period();
91 unsigned long nfsdgrace = 0;
92
93 if (nlmsvc_ops)
94 nfsdgrace = nlmsvc_ops->get_grace_period();
95
96 return max(lockdgrace, nfsdgrace);
97}
98EXPORT_SYMBOL(get_nfs_grace_period);
99 89
100static void grace_ender(struct work_struct *not_used) 90static void grace_ender(struct work_struct *not_used)
101{ 91{
102 nlmsvc_grace_period = 0; 92 locks_end_grace(&lockd_manager);
103} 93}
104 94
105static DECLARE_DELAYED_WORK(grace_period_end, grace_ender); 95static DECLARE_DELAYED_WORK(grace_period_end, grace_ender);
106 96
107static void set_grace_period(void) 97static void set_grace_period(void)
108{ 98{
109 unsigned long grace_period = get_nfs_grace_period() + jiffies; 99 unsigned long grace_period = get_lockd_grace_period();
110 100
111 nlmsvc_grace_period = 1; 101 locks_start_grace(&lockd_manager);
112 cancel_delayed_work_sync(&grace_period_end); 102 cancel_delayed_work_sync(&grace_period_end);
113 schedule_delayed_work(&grace_period_end, grace_period); 103 schedule_delayed_work(&grace_period_end, grace_period);
114} 104}
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 4a714f64515b..7ca617367b3e 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -89,7 +89,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
89 resp->cookie = argp->cookie; 89 resp->cookie = argp->cookie;
90 90
91 /* Don't accept test requests during grace period */ 91 /* Don't accept test requests during grace period */
92 if (nlmsvc_grace_period) { 92 if (locks_in_grace()) {
93 resp->status = nlm_lck_denied_grace_period; 93 resp->status = nlm_lck_denied_grace_period;
94 return rc; 94 return rc;
95 } 95 }
@@ -123,7 +123,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
123 resp->cookie = argp->cookie; 123 resp->cookie = argp->cookie;
124 124
125 /* Don't accept new lock requests during grace period */ 125 /* Don't accept new lock requests during grace period */
126 if (nlmsvc_grace_period && !argp->reclaim) { 126 if (locks_in_grace() && !argp->reclaim) {
127 resp->status = nlm_lck_denied_grace_period; 127 resp->status = nlm_lck_denied_grace_period;
128 return rc; 128 return rc;
129 } 129 }
@@ -169,7 +169,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
169 resp->cookie = argp->cookie; 169 resp->cookie = argp->cookie;
170 170
171 /* Don't accept requests during grace period */ 171 /* Don't accept requests during grace period */
172 if (nlmsvc_grace_period) { 172 if (locks_in_grace()) {
173 resp->status = nlm_lck_denied_grace_period; 173 resp->status = nlm_lck_denied_grace_period;
174 return rpc_success; 174 return rpc_success;
175 } 175 }
@@ -202,7 +202,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
202 resp->cookie = argp->cookie; 202 resp->cookie = argp->cookie;
203 203
204 /* Don't accept new lock requests during grace period */ 204 /* Don't accept new lock requests during grace period */
205 if (nlmsvc_grace_period) { 205 if (locks_in_grace()) {
206 resp->status = nlm_lck_denied_grace_period; 206 resp->status = nlm_lck_denied_grace_period;
207 return rpc_success; 207 return rpc_success;
208 } 208 }
@@ -341,7 +341,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
341 resp->cookie = argp->cookie; 341 resp->cookie = argp->cookie;
342 342
343 /* Don't accept new lock requests during grace period */ 343 /* Don't accept new lock requests during grace period */
344 if (nlmsvc_grace_period && !argp->reclaim) { 344 if (locks_in_grace() && !argp->reclaim) {
345 resp->status = nlm_lck_denied_grace_period; 345 resp->status = nlm_lck_denied_grace_period;
346 return rpc_success; 346 return rpc_success;
347 } 347 }
@@ -374,7 +374,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
374 resp->cookie = argp->cookie; 374 resp->cookie = argp->cookie;
375 375
376 /* Don't accept requests during grace period */ 376 /* Don't accept requests during grace period */
377 if (nlmsvc_grace_period) { 377 if (locks_in_grace()) {
378 resp->status = nlm_lck_denied_grace_period; 378 resp->status = nlm_lck_denied_grace_period;
379 return rpc_success; 379 return rpc_success;
380 } 380 }
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 76262c1986f2..1b013e198804 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -118,7 +118,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
118 resp->cookie = argp->cookie; 118 resp->cookie = argp->cookie;
119 119
120 /* Don't accept test requests during grace period */ 120 /* Don't accept test requests during grace period */
121 if (nlmsvc_grace_period) { 121 if (locks_in_grace()) {
122 resp->status = nlm_lck_denied_grace_period; 122 resp->status = nlm_lck_denied_grace_period;
123 return rc; 123 return rc;
124 } 124 }
@@ -153,7 +153,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
153 resp->cookie = argp->cookie; 153 resp->cookie = argp->cookie;
154 154
155 /* Don't accept new lock requests during grace period */ 155 /* Don't accept new lock requests during grace period */
156 if (nlmsvc_grace_period && !argp->reclaim) { 156 if (locks_in_grace() && !argp->reclaim) {
157 resp->status = nlm_lck_denied_grace_period; 157 resp->status = nlm_lck_denied_grace_period;
158 return rc; 158 return rc;
159 } 159 }
@@ -199,7 +199,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
199 resp->cookie = argp->cookie; 199 resp->cookie = argp->cookie;
200 200
201 /* Don't accept requests during grace period */ 201 /* Don't accept requests during grace period */
202 if (nlmsvc_grace_period) { 202 if (locks_in_grace()) {
203 resp->status = nlm_lck_denied_grace_period; 203 resp->status = nlm_lck_denied_grace_period;
204 return rpc_success; 204 return rpc_success;
205 } 205 }
@@ -232,7 +232,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
232 resp->cookie = argp->cookie; 232 resp->cookie = argp->cookie;
233 233
234 /* Don't accept new lock requests during grace period */ 234 /* Don't accept new lock requests during grace period */
235 if (nlmsvc_grace_period) { 235 if (locks_in_grace()) {
236 resp->status = nlm_lck_denied_grace_period; 236 resp->status = nlm_lck_denied_grace_period;
237 return rpc_success; 237 return rpc_success;
238 } 238 }
@@ -373,7 +373,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
373 resp->cookie = argp->cookie; 373 resp->cookie = argp->cookie;
374 374
375 /* Don't accept new lock requests during grace period */ 375 /* Don't accept new lock requests during grace period */
376 if (nlmsvc_grace_period && !argp->reclaim) { 376 if (locks_in_grace() && !argp->reclaim) {
377 resp->status = nlm_lck_denied_grace_period; 377 resp->status = nlm_lck_denied_grace_period;
378 return rpc_success; 378 return rpc_success;
379 } 379 }
@@ -406,7 +406,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
406 resp->cookie = argp->cookie; 406 resp->cookie = argp->cookie;
407 407
408 /* Don't accept requests during grace period */ 408 /* Don't accept requests during grace period */
409 if (nlmsvc_grace_period) { 409 if (locks_in_grace()) {
410 resp->status = nlm_lck_denied_grace_period; 410 resp->status = nlm_lck_denied_grace_period;
411 return rpc_success; 411 return rpc_success;
412 } 412 }