aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-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
-rw-r--r--fs/nfsd/lockd.c1
-rw-r--r--fs/nfsd/nfs4proc.c8
-rw-r--r--fs/nfsd/nfs4state.c34
8 files changed, 96 insertions, 52 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 }
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c
index 15c6faeec77c..b2786a5f9afe 100644
--- a/fs/nfsd/lockd.c
+++ b/fs/nfsd/lockd.c
@@ -70,7 +70,6 @@ nlm_fclose(struct file *filp)
70static struct nlmsvc_binding nfsd_nlm_ops = { 70static struct nlmsvc_binding nfsd_nlm_ops = {
71 .fopen = nlm_fopen, /* open file for locking */ 71 .fopen = nlm_fopen, /* open file for locking */
72 .fclose = nlm_fclose, /* close file */ 72 .fclose = nlm_fclose, /* close file */
73 .get_grace_period = get_nfs4_grace_period,
74}; 73};
75 74
76void 75void
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index e5b51ffafc6c..669461e291ae 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -201,10 +201,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
201 /* Openowner is now set, so sequence id will get bumped. Now we need 201 /* Openowner is now set, so sequence id will get bumped. Now we need
202 * these checks before we do any creates: */ 202 * these checks before we do any creates: */
203 status = nfserr_grace; 203 status = nfserr_grace;
204 if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) 204 if (locks_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
205 goto out; 205 goto out;
206 status = nfserr_no_grace; 206 status = nfserr_no_grace;
207 if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) 207 if (!locks_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
208 goto out; 208 goto out;
209 209
210 switch (open->op_claim_type) { 210 switch (open->op_claim_type) {
@@ -575,7 +575,7 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
575{ 575{
576 __be32 status; 576 __be32 status;
577 577
578 if (nfs4_in_grace()) 578 if (locks_in_grace())
579 return nfserr_grace; 579 return nfserr_grace;
580 status = nfsd_unlink(rqstp, &cstate->current_fh, 0, 580 status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
581 remove->rm_name, remove->rm_namelen); 581 remove->rm_name, remove->rm_namelen);
@@ -596,7 +596,7 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
596 596
597 if (!cstate->save_fh.fh_dentry) 597 if (!cstate->save_fh.fh_dentry)
598 return status; 598 return status;
599 if (nfs4_in_grace() && !(cstate->save_fh.fh_export->ex_flags 599 if (locks_in_grace() && !(cstate->save_fh.fh_export->ex_flags
600 & NFSEXP_NOSUBTREECHECK)) 600 & NFSEXP_NOSUBTREECHECK))
601 return nfserr_grace; 601 return nfserr_grace;
602 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname, 602 status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 1578d7a2667e..0cc7ff5d5ab5 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -61,7 +61,6 @@
61static time_t lease_time = 90; /* default lease time */ 61static time_t lease_time = 90; /* default lease time */
62static time_t user_lease_time = 90; 62static time_t user_lease_time = 90;
63static time_t boot_time; 63static time_t boot_time;
64static int in_grace = 1;
65static u32 current_ownerid = 1; 64static u32 current_ownerid = 1;
66static u32 current_fileid = 1; 65static u32 current_fileid = 1;
67static u32 current_delegid = 1; 66static u32 current_delegid = 1;
@@ -1640,7 +1639,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
1640 case NFS4_OPEN_CLAIM_NULL: 1639 case NFS4_OPEN_CLAIM_NULL:
1641 /* Let's not give out any delegations till everyone's 1640 /* Let's not give out any delegations till everyone's
1642 * had the chance to reclaim theirs.... */ 1641 * had the chance to reclaim theirs.... */
1643 if (nfs4_in_grace()) 1642 if (locks_in_grace())
1644 goto out; 1643 goto out;
1645 if (!atomic_read(&cb->cb_set) || !sop->so_confirmed) 1644 if (!atomic_read(&cb->cb_set) || !sop->so_confirmed)
1646 goto out; 1645 goto out;
@@ -1816,12 +1815,15 @@ out:
1816 return status; 1815 return status;
1817} 1816}
1818 1817
1818struct lock_manager nfsd4_manager = {
1819};
1820
1819static void 1821static void
1820end_grace(void) 1822nfsd4_end_grace(void)
1821{ 1823{
1822 dprintk("NFSD: end of grace period\n"); 1824 dprintk("NFSD: end of grace period\n");
1823 nfsd4_recdir_purge_old(); 1825 nfsd4_recdir_purge_old();
1824 in_grace = 0; 1826 locks_end_grace(&nfsd4_manager);
1825} 1827}
1826 1828
1827static time_t 1829static time_t
@@ -1838,8 +1840,8 @@ nfs4_laundromat(void)
1838 nfs4_lock_state(); 1840 nfs4_lock_state();
1839 1841
1840 dprintk("NFSD: laundromat service - starting\n"); 1842 dprintk("NFSD: laundromat service - starting\n");
1841 if (in_grace) 1843 if (locks_in_grace())
1842 end_grace(); 1844 nfsd4_end_grace();
1843 list_for_each_safe(pos, next, &client_lru) { 1845 list_for_each_safe(pos, next, &client_lru) {
1844 clp = list_entry(pos, struct nfs4_client, cl_lru); 1846 clp = list_entry(pos, struct nfs4_client, cl_lru);
1845 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) { 1847 if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
@@ -1974,7 +1976,7 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
1974 return nfserr_bad_stateid; 1976 return nfserr_bad_stateid;
1975 else if (ONE_STATEID(stateid) && (flags & RD_STATE)) 1977 else if (ONE_STATEID(stateid) && (flags & RD_STATE))
1976 return nfs_ok; 1978 return nfs_ok;
1977 else if (nfs4_in_grace()) { 1979 else if (locks_in_grace()) {
1978 /* Answer in remaining cases depends on existance of 1980 /* Answer in remaining cases depends on existance of
1979 * conflicting state; so we must wait out the grace period. */ 1981 * conflicting state; so we must wait out the grace period. */
1980 return nfserr_grace; 1982 return nfserr_grace;
@@ -1993,7 +1995,7 @@ check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
1993static inline int 1995static inline int
1994io_during_grace_disallowed(struct inode *inode, int flags) 1996io_during_grace_disallowed(struct inode *inode, int flags)
1995{ 1997{
1996 return nfs4_in_grace() && (flags & (RD_STATE | WR_STATE)) 1998 return locks_in_grace() && (flags & (RD_STATE | WR_STATE))
1997 && mandatory_lock(inode); 1999 && mandatory_lock(inode);
1998} 2000}
1999 2001
@@ -2693,10 +2695,10 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2693 filp = lock_stp->st_vfs_file; 2695 filp = lock_stp->st_vfs_file;
2694 2696
2695 status = nfserr_grace; 2697 status = nfserr_grace;
2696 if (nfs4_in_grace() && !lock->lk_reclaim) 2698 if (locks_in_grace() && !lock->lk_reclaim)
2697 goto out; 2699 goto out;
2698 status = nfserr_no_grace; 2700 status = nfserr_no_grace;
2699 if (!nfs4_in_grace() && lock->lk_reclaim) 2701 if (!locks_in_grace() && lock->lk_reclaim)
2700 goto out; 2702 goto out;
2701 2703
2702 locks_init_lock(&file_lock); 2704 locks_init_lock(&file_lock);
@@ -2779,7 +2781,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
2779 int error; 2781 int error;
2780 __be32 status; 2782 __be32 status;
2781 2783
2782 if (nfs4_in_grace()) 2784 if (locks_in_grace())
2783 return nfserr_grace; 2785 return nfserr_grace;
2784 2786
2785 if (check_lock_length(lockt->lt_offset, lockt->lt_length)) 2787 if (check_lock_length(lockt->lt_offset, lockt->lt_length))
@@ -3192,9 +3194,9 @@ __nfs4_state_start(void)
3192 unsigned long grace_time; 3194 unsigned long grace_time;
3193 3195
3194 boot_time = get_seconds(); 3196 boot_time = get_seconds();
3195 grace_time = get_nfs_grace_period(); 3197 grace_time = get_nfs4_grace_period();
3196 lease_time = user_lease_time; 3198 lease_time = user_lease_time;
3197 in_grace = 1; 3199 locks_start_grace(&nfsd4_manager);
3198 printk(KERN_INFO "NFSD: starting %ld-second grace period\n", 3200 printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
3199 grace_time/HZ); 3201 grace_time/HZ);
3200 laundry_wq = create_singlethread_workqueue("nfsd4"); 3202 laundry_wq = create_singlethread_workqueue("nfsd4");
@@ -3213,12 +3215,6 @@ nfs4_state_start(void)
3213 return; 3215 return;
3214} 3216}
3215 3217
3216int
3217nfs4_in_grace(void)
3218{
3219 return in_grace;
3220}
3221
3222time_t 3218time_t
3223nfs4_lease_time(void) 3219nfs4_lease_time(void)
3224{ 3220{