[pnfs] [PATCH 08/10] nfs41: Implement NFSv4.1 callback service process.

Ricardo Labiaga ricardo.labiaga at netapp.com
Wed Jan 2 19:01:49 EST 2008


nfs41_callback_up() initializes the necessary queues and creates the new
nfs41_callback_svc thread.  This thread executes the callback service which
waits for requests to arrive on the svc_serv->sv_cb_list.

NFS41_BC_MIN_CALLBACKS is set to 1 because we expect callbacks to not
cause substantial latency.

The actual processing of the callback will be implemented as a separate patch.

Signed-off-by: Ricardo Labiaga <ricardo.labiaga at netapp.com>
---
 fs/nfs/callback.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index a72de66..331e976 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -15,6 +15,9 @@
 #include <linux/nfs_fs.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
+#if defined(CONFIG_NFS_V4_1)
+#include <linux/sunrpc/bc_xprt.h>
+#endif
 
 #include <net/inet_sock.h>
 
@@ -23,6 +26,11 @@
 #include "internal.h"
 
 #define NFSDBG_FACILITY NFSDBG_CALLBACK
+/*
+ * Callbacks are expected to not cause substantial latency,
+ * so we limit their concurrency to 1.
+ */
+#define	NFS41_BC_MIN_CALLBACKS 1
 
 struct nfs_callback_data {
 	unsigned int users;
@@ -104,6 +112,62 @@ static void nfs4_callback_svc(struct svc_rqst *rqstp)
 	module_put_and_exit(0);
 }
 
+#if defined(CONFIG_NFS_V4_1)
+
+/*
+ * The callback service for NFSv4.1 callbacks
+ */
+static void nfs41_callback_svc(struct svc_rqst *rqstp)
+{
+	struct svc_serv *serv = rqstp->rq_server;
+	struct list_head *entry;
+	struct rpc_rqst *req;
+
+	DEFINE_WAIT(wq);
+
+	__module_get(THIS_MODULE);
+
+	lock_kernel();
+
+	nfs_callback_info.pid = current->pid;
+	daemonize("nfsv41-svc");
+	/* Process request with signals blocked, but allow SIGKILL.  */
+	allow_signal(SIGKILL);
+
+	complete(&nfs_callback_info.started);
+
+	for (;;) {
+		if (signalled()) {
+			if (nfs_callback_info.users == 0)
+				break;
+			flush_signals(current);
+		}
+
+		prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
+		spin_lock_bh(&serv->sv_cb_lock);
+		if (!list_empty(&serv->sv_cb_list)) {
+			entry = serv->sv_cb_list.next;
+			list_del(entry);
+			spin_unlock_bh(&serv->sv_cb_lock);
+			req = list_entry(entry, struct rpc_rqst, rq_list);
+			dprintk("Need to invoke bc_process() here\n");
+			dprintk("Freeing the bc_request for now\n");
+			xprt_free_bc_request(req);
+		} else {
+			spin_unlock_bh(&serv->sv_cb_lock);
+			schedule();
+		}
+		finish_wait(&serv->sv_cb_waitq, &wq);
+	}
+
+	svc_exit_thread(rqstp);
+	nfs_callback_info.pid = 0;
+	complete(&nfs_callback_info.stopped);
+	unlock_kernel();
+	module_put_and_exit(0);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
 
 /*
  * Bring up the NFSv4 callback service
@@ -123,6 +187,28 @@ int nfs4_callback_up(struct svc_serv *serv)
 	return ret;
 }
 
+#if defined(CONFIG_NFS_V4_1)
+/*
+ * Bring up the NFSv4.1 callback service
+ */
+int nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
+{
+	int ret;
+
+	xprt->serv = serv;
+	ret = xprt_setup_backchannel(xprt, NFS41_BC_MIN_CALLBACKS);
+	if (ret < 0)
+		return ret;
+
+	INIT_LIST_HEAD(&serv->sv_cb_list);
+	spin_lock_init(&serv->sv_cb_lock);
+	init_waitqueue_head(&serv->sv_cb_waitq);
+	ret = svc_create_thread(nfs41_callback_svc, serv);
+
+	return ret;
+}
+#endif /* CONFIG_NFS_V4_1 */
+
 /*
  * Bring up the server process if it is not already up.
  */
@@ -130,6 +216,9 @@ int nfs_callback_up(int minorversion, void *args)
 {
 	struct svc_serv *serv;
 	int ret = 0;
+#if defined(CONFIG_NFS_V4_1)
+	struct rpc_xprt *xprt = (struct rpc_xprt *)args;
+#endif
 
 	lock_kernel();
 	mutex_lock(&nfs_callback_mutex);
@@ -146,6 +235,11 @@ int nfs_callback_up(int minorversion, void *args)
 	case 0:
 		ret = nfs4_callback_up(serv);
 		break;
+#if defined(CONFIG_NFS_V4_1)
+	case 1:
+		ret = nfs41_callback_up(serv, xprt);
+		break;
+#endif /* CONFIG_NFS_V4_1 */
 	}
 	if (ret < 0)
 		goto out_destroy;
-- 
1.5.3.3


More information about the pNFS mailing list