lockd: move lockd's grace period handling into its own module
authorJeff Layton <jlayton@primarydata.com>
Fri, 12 Sep 2014 20:40:20 +0000 (16:40 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Wed, 17 Sep 2014 20:33:11 +0000 (16:33 -0400)
Currently, all of the grace period handling is part of lockd. Eventually
though we'd like to be able to build v4-only servers, at which point
we'll need to put all of this elsewhere.

Move the code itself into fs/nfs_common and have it build a grace.ko
module. Then, rejigger the Kconfig options so that both nfsd and lockd
enable it automatically.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>
fs/Kconfig
fs/lockd/Makefile
fs/lockd/grace.c [deleted file]
fs/lockd/netns.h
fs/lockd/svc.c
fs/nfs_common/Makefile
fs/nfs_common/grace.c [new file with mode: 0644]
fs/nfsd/Kconfig
include/linux/proc_fs.h

index 312393f..db5dc15 100644 (file)
@@ -233,9 +233,13 @@ if NETWORK_FILESYSTEMS
 source "fs/nfs/Kconfig"
 source "fs/nfsd/Kconfig"
 
+config GRACE_PERIOD
+       tristate
+
 config LOCKD
        tristate
        depends on FILE_LOCKING
+       select GRACE_PERIOD
 
 config LOCKD_V4
        bool
@@ -249,7 +253,7 @@ config NFS_ACL_SUPPORT
 
 config NFS_COMMON
        bool
-       depends on NFSD || NFS_FS
+       depends on NFSD || NFS_FS || LOCKD
        default y
 
 source "net/sunrpc/Kconfig"
index ca58d64..6a0b351 100644 (file)
@@ -5,6 +5,6 @@
 obj-$(CONFIG_LOCKD) += lockd.o
 
 lockd-objs-y := clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \
-               svcshare.o svcproc.o svcsubs.o mon.o xdr.o grace.o
+               svcshare.o svcproc.o svcsubs.o mon.o xdr.o
 lockd-objs-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o
 lockd-objs                   := $(lockd-objs-y)
diff --git a/fs/lockd/grace.c b/fs/lockd/grace.c
deleted file mode 100644 (file)
index 6d1ee72..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Common code for control of lockd and nfsv4 grace periods.
- */
-
-#include <linux/module.h>
-#include <linux/lockd/bind.h>
-#include <net/net_namespace.h>
-
-#include "netns.h"
-
-static DEFINE_SPINLOCK(grace_lock);
-
-/**
- * locks_start_grace
- * @lm: who this grace period is for
- *
- * A grace period is a period during which locks should not be given
- * out.  Currently grace periods are only enforced by the two lock
- * managers (lockd and nfsd), using the locks_in_grace() function to
- * check when they are in a grace period.
- *
- * This function is called to start a grace period.
- */
-void locks_start_grace(struct net *net, struct lock_manager *lm)
-{
-       struct lockd_net *ln = net_generic(net, lockd_net_id);
-
-       spin_lock(&grace_lock);
-       list_add(&lm->list, &ln->grace_list);
-       spin_unlock(&grace_lock);
-}
-EXPORT_SYMBOL_GPL(locks_start_grace);
-
-/**
- * locks_end_grace
- * @lm: who this grace period is for
- *
- * Call this function to state that the given lock manager is ready to
- * resume regular locking.  The grace period will not end until all lock
- * managers that called locks_start_grace() also call locks_end_grace().
- * Note that callers count on it being safe to call this more than once,
- * and the second call should be a no-op.
- */
-void locks_end_grace(struct lock_manager *lm)
-{
-       spin_lock(&grace_lock);
-       list_del_init(&lm->list);
-       spin_unlock(&grace_lock);
-}
-EXPORT_SYMBOL_GPL(locks_end_grace);
-
-/**
- * locks_in_grace
- *
- * Lock managers call this function to determine when it is OK for them
- * to answer ordinary lock requests, and when they should accept only
- * lock reclaims.
- */
-int locks_in_grace(struct net *net)
-{
-       struct lockd_net *ln = net_generic(net, lockd_net_id);
-
-       return !list_empty(&ln->grace_list);
-}
-EXPORT_SYMBOL_GPL(locks_in_grace);
index 5010b55..097bfa3 100644 (file)
@@ -11,7 +11,6 @@ struct lockd_net {
 
        struct delayed_work grace_period_end;
        struct lock_manager lockd_manager;
-       struct list_head grace_list;
 
        spinlock_t nsm_clnt_lock;
        unsigned int nsm_users;
index 09857b4..266b679 100644 (file)
@@ -586,7 +586,7 @@ static int lockd_init_net(struct net *net)
        struct lockd_net *ln = net_generic(net, lockd_net_id);
 
        INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
-       INIT_LIST_HEAD(&ln->grace_list);
+       INIT_LIST_HEAD(&ln->lockd_manager.list);
        spin_lock_init(&ln->nsm_clnt_lock);
        return 0;
 }
index f689ed8..d153ca3 100644 (file)
@@ -3,5 +3,6 @@
 #
 
 obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o
-
 nfs_acl-objs := nfsacl.o
+
+obj-$(CONFIG_GRACE_PERIOD) += grace.o
diff --git a/fs/nfs_common/grace.c b/fs/nfs_common/grace.c
new file mode 100644 (file)
index 0000000..ae6e58e
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Common code for control of lockd and nfsv4 grace periods.
+ *
+ * Transplanted from lockd code
+ */
+
+#include <linux/module.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+#include <linux/fs.h>
+
+static int grace_net_id;
+static DEFINE_SPINLOCK(grace_lock);
+
+/**
+ * locks_start_grace
+ * @net: net namespace that this lock manager belongs to
+ * @lm: who this grace period is for
+ *
+ * A grace period is a period during which locks should not be given
+ * out.  Currently grace periods are only enforced by the two lock
+ * managers (lockd and nfsd), using the locks_in_grace() function to
+ * check when they are in a grace period.
+ *
+ * This function is called to start a grace period.
+ */
+void
+locks_start_grace(struct net *net, struct lock_manager *lm)
+{
+       struct list_head *grace_list = net_generic(net, grace_net_id);
+
+       spin_lock(&grace_lock);
+       list_add(&lm->list, grace_list);
+       spin_unlock(&grace_lock);
+}
+EXPORT_SYMBOL_GPL(locks_start_grace);
+
+/**
+ * locks_end_grace
+ * @net: net namespace that this lock manager belongs to
+ * @lm: who this grace period is for
+ *
+ * Call this function to state that the given lock manager is ready to
+ * resume regular locking.  The grace period will not end until all lock
+ * managers that called locks_start_grace() also call locks_end_grace().
+ * Note that callers count on it being safe to call this more than once,
+ * and the second call should be a no-op.
+ */
+void
+locks_end_grace(struct lock_manager *lm)
+{
+       spin_lock(&grace_lock);
+       list_del_init(&lm->list);
+       spin_unlock(&grace_lock);
+}
+EXPORT_SYMBOL_GPL(locks_end_grace);
+
+/**
+ * locks_in_grace
+ *
+ * Lock managers call this function to determine when it is OK for them
+ * to answer ordinary lock requests, and when they should accept only
+ * lock reclaims.
+ */
+int
+locks_in_grace(struct net *net)
+{
+       struct list_head *grace_list = net_generic(net, grace_net_id);
+
+       return !list_empty(grace_list);
+}
+EXPORT_SYMBOL_GPL(locks_in_grace);
+
+static int __net_init
+grace_init_net(struct net *net)
+{
+       struct list_head *grace_list = net_generic(net, grace_net_id);
+
+       INIT_LIST_HEAD(grace_list);
+       return 0;
+}
+
+static void __net_exit
+grace_exit_net(struct net *net)
+{
+       struct list_head *grace_list = net_generic(net, grace_net_id);
+
+       BUG_ON(!list_empty(grace_list));
+}
+
+static struct pernet_operations grace_net_ops = {
+       .init = grace_init_net,
+       .exit = grace_exit_net,
+       .id   = &grace_net_id,
+       .size = sizeof(struct list_head),
+};
+
+static int __init
+init_grace(void)
+{
+       return register_pernet_subsys(&grace_net_ops);
+}
+
+static void __exit
+exit_grace(void)
+{
+       unregister_pernet_subsys(&grace_net_ops);
+}
+
+MODULE_AUTHOR("Jeff Layton <jlayton@primarydata.com>");
+MODULE_LICENSE("GPL");
+module_init(init_grace)
+module_exit(exit_grace)
index f3586b6..7339515 100644 (file)
@@ -71,6 +71,7 @@ config NFSD_V4
        select FS_POSIX_ACL
        select SUNRPC_GSS
        select CRYPTO
+       select GRACE_PERIOD
        help
          This option enables support in your system's NFS server for
          version 4 of the NFS protocol (RFC 3530).
index 9d117f6..b97bf2e 100644 (file)
@@ -74,6 +74,8 @@ static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *p
 
 #endif /* CONFIG_PROC_FS */
 
+struct net;
+
 static inline struct proc_dir_entry *proc_net_mkdir(
        struct net *net, const char *name, struct proc_dir_entry *parent)
 {