aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/grace.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-09-06 12:34:25 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-10-03 16:19:02 -0400
commitaf558e33bedab672f5cfd3260bce7445e353fe21 (patch)
treeeb89187b6c12640a00584bd35be035ba332e4af3 /fs/lockd/grace.c
parentd5b337b4877f7c4e1d761434ee04d045b0201e03 (diff)
nfsd: common grace period control
Rewrite grace period code to unify management of grace period across lockd and nfsd. The current code has lockd and nfsd cooperate to compute a grace period which is satisfactory to them both, and then individually enforce it. This creates a slight race condition, since the enforcement is not coordinated. It's also more complicated than necessary. Here instead we have lockd and nfsd each inform common code when they enter the grace period, and when they're ready to leave the grace period, and allow normal locking only after both of them are ready to leave. We also expect the locks_start_grace()/locks_end_grace() interface here to be simpler to build on for future cluster/high-availability work, which may require (for example) putting individual filesystems into grace, or enforcing grace periods across multiple cluster nodes. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/lockd/grace.c')
-rw-r--r--fs/lockd/grace.c59
1 files changed, 59 insertions, 0 deletions
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);