[PATCH 3/4] cb_sequence: nfsd callback minorversion1 cleanup

Benny Halevy bhalevy at panasas.com
Tue May 29 11:07:02 EDT 2007


Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
 fs/nfsd/nfs4callback.c     |  198 +++++++++++++++++++++++++++++++++++---------
 include/linux/nfsd/state.h |    1 -
 2 files changed, 158 insertions(+), 41 deletions(-)

diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 5a0d983..2438308 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -86,15 +86,25 @@ enum nfs_cb_opnum4 {
 #define NFS4_enc_cb_recall_sz		(cb_compound_enc_hdr_sz +       \
 					1 + enc_stateid_sz +            \
 					enc_nfs4_fh_sz)
-
 #define NFS4_dec_cb_recall_sz		(cb_compound_dec_hdr_sz  +      \
 					op_dec_sz)
-#define NFS4_enc_cb_layout_sz		(cb_compound_enc_hdr_sz +       \
+
+#if defined(CONFIG_NFSD_V4_1)
+#define NFS41_enc_cb_null_sz		0
+#define NFS41_dec_cb_null_sz		0
+#define cb_compound41_enc_hdr_sz	3
+#define cb_compound41_dec_hdr_sz	(3 + (NFS4_MAXTAGLEN >> 2))
+#define NFS41_enc_cb_recall_sz		(cb_compound41_enc_hdr_sz +     \
+					1 + enc_stateid_sz +            \
+					enc_nfs4_fh_sz)
+#define NFS41_dec_cb_recall_sz		(cb_compound_dec_hdr_sz  +      \
+					op_dec_sz)
+#define NFS41_enc_cb_layout_sz		(cb_compound_enc_hdr_sz +       \
 					1 + 3 +                         \
 					enc_nfs4_fh_sz + 4)
-
-#define NFS4_dec_cb_layout_sz		(cb_compound_dec_hdr_sz  +      \
+#define NFS41_dec_cb_layout_sz		(cb_compound_dec_hdr_sz  +      \
 					op_dec_sz)
+#endif /* defined(CONFIG_NFSD_V4_1) */
 
 /*
 * Generic encode routines from fs/nfs/nfs4xdr.c
@@ -157,7 +167,6 @@ xdr_error:                                      \
 
 struct nfs4_cb_compound_hdr {
 	/* args */
-	u32		minorversion;
 	u32		ident;		/* minorversion 0 only */
 	u32		nops;
 
@@ -231,10 +240,8 @@ encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
 
 	RESERVE_SPACE(16);
 	WRITE32(0);            /* tag length is always 0 */
-	WRITE32(hdr->minorversion);
-	if (hdr->minorversion == 0) {
-		WRITE32(hdr->ident);
-	}
+	WRITE32(0);            /* minorversion */
+	WRITE32(hdr->ident);
 	WRITE32(hdr->nops);
 	return 0;
 }
@@ -310,7 +317,6 @@ nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args
 {
 	struct xdr_stream xdr;
 	struct nfs4_cb_compound_hdr hdr = {
-		.minorversion = args->cbr_minorversion,
 		.ident = args->cbr_ident,
 		.nops   = 1,
 	};
@@ -320,24 +326,51 @@ nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p, struct nfs4_cb_recall *args
 	return (encode_cb_recall(&xdr, args));
 }
 
-#ifdef CONFIG_PNFS
+#if defined(CONFIG_NFSD_V4_1)
+static int
+encode_cb_compound41_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
+{
+	u32 * p;
+
+	RESERVE_SPACE(16);
+	WRITE32(0);            /* tag length is always 0 */
+	WRITE32(1);            /* minorversion */
+	WRITE32(hdr->nops);
+	return 0;
+}
+
 static int
-nfs4_xdr_enc_cb_layout(struct rpc_rqst *req, u32 *p, struct nfs4_layoutrecall *args)
+nfs41_xdr_enc_cb_recall(struct rpc_rqst *req, u32 *p,
+                        struct nfs4_cb_recall *args)
 {
 	struct xdr_stream xdr;
+	struct nfs4_cb_compound_hdr hdr = {
+		.ident = args->cbr_ident,
+		.nops   = 1,
+	};
 
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_cb_compound41_hdr(&xdr, &hdr);
+	return (encode_cb_recall(&xdr, args));
+}
+
+#ifdef CONFIG_PNFS
+static int
+nfs41_xdr_enc_cb_layout(struct rpc_rqst *req, u32 *p,
+                        struct nfs4_layoutrecall *args)
+{
+	struct xdr_stream xdr;
 	struct nfs4_cb_compound_hdr hdr = {
-		.minorversion = 1,
 		.ident = 0,
 		.nops   = 1,
 	};
 
 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
-	encode_cb_compound_hdr(&xdr, &hdr);
-
+	encode_cb_compound41_hdr(&xdr, &hdr);
 	return (encode_cb_layout(&xdr, args));
 }
 #endif /* CONFIG_PNFS */
+#endif /* defined(CONFIG_NFSD_V4_1) */
 
 static int
 decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){
@@ -396,9 +429,26 @@ out:
 	return status;
 }
 
+#if defined(CONFIG_NFSD_V4_1)
+static int
+nfs41_xdr_dec_cb_recall(struct rpc_rqst *rqstp, u32 *p)
+{
+	struct xdr_stream xdr;
+	struct nfs4_cb_compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_cb_compound_hdr(&xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_cb_op_hdr(&xdr, OP_CB_RECALL);
+out:
+	return status;
+}
+
 #ifdef CONFIG_PNFS
 static int
-nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp, u32 *p)
+nfs41_xdr_dec_cb_layout(struct rpc_rqst *rqstp, u32 *p)
 {
 	struct xdr_stream xdr;
 	struct nfs4_cb_compound_hdr hdr;
@@ -413,6 +463,7 @@ out:
 	return status;
 }
 #endif /* CONFIG_PNFS */
+#endif /* defined(CONFIG_NFSD_V4_1) */
 
 /*
  * RPC procedure tables
@@ -434,20 +485,45 @@ out:
 static struct rpc_procinfo     nfs4_cb_procedures[] = {
     PROC(CB_NULL,      NULL,     enc_cb_null,     dec_cb_null),
     PROC(CB_RECALL,    COMPOUND,   enc_cb_recall,      dec_cb_recall),
-#ifdef CONFIG_PNFS
-    PROC(CB_LAYOUT,    COMPOUND,   enc_cb_layout,      dec_cb_layout),
-#endif
 };
 
 static struct rpc_version       nfs_cb_version4 = {
-        .number                 = 1,
+        .number                 = 0,
         .nrprocs                = ARRAY_SIZE(nfs4_cb_procedures),
         .procs                  = nfs4_cb_procedures
 };
 
+#if defined(CONFIG_NFSD_V4_1)
+#define PROC41(proc, call, argtype, restype)                            \
+[NFSPROC4_CLNT_##proc] = {                                      	\
+        .p_proc   = NFSPROC4_CB_##call,					\
+        .p_encode = (kxdrproc_t) nfs41_xdr_##argtype,                   \
+        .p_decode = (kxdrproc_t) nfs41_xdr_##restype,                   \
+        .p_bufsiz = MAX(NFS41_##argtype##_sz,NFS41_##restype##_sz) << 2,\
+        .p_statidx = NFSPROC4_CB_##call,				\
+	.p_name   = #proc,                                              \
+}
+
+static struct rpc_procinfo     nfs41_cb_procedures[] = {
+    PROC(CB_NULL,      NULL,     enc_cb_null,     dec_cb_null),
+    PROC41(CB_RECALL,    COMPOUND,   enc_cb_recall,      dec_cb_recall),
+#ifdef CONFIG_PNFS
+    PROC41(CB_LAYOUT,    COMPOUND,   enc_cb_layout,      dec_cb_layout),
+#endif
+};
+
+static struct rpc_version       nfs_cb_version41 = {
+        .number                 = 1,
+        .nrprocs                = ARRAY_SIZE(nfs41_cb_procedures),
+        .procs                  = nfs41_cb_procedures
+};
+#endif /* defined(CONFIG_NFSD_V4_1) */
+
 static struct rpc_version *	nfs_cb_version[] = {
-	NULL,
 	&nfs_cb_version4,
+#if defined(CONFIG_NFSD_V4_1)
+	&nfs_cb_version41,
+#endif
 };
 
 /*
@@ -530,7 +606,7 @@ nfsd4_probe_callback(struct nfs4_client *clp)
 	 * XXX AUTH_UNIX only - need AUTH_GSS....
 	 */
 	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
-	clnt = rpc_new_client(xprt, hostname, program, 1, RPC_AUTH_UNIX);
+	clnt = rpc_new_client(xprt, hostname, program, 0, RPC_AUTH_UNIX);
 	if (IS_ERR(clnt)) {
 		dprintk("NFSD: couldn't create callback client\n");
 		goto out_err;
@@ -585,7 +661,7 @@ nfsd41_probe_callback(struct nfs4_client *clp)
 	struct rpc_stat *	stat = &cb->cb_stat;
 	struct rpc_clnt *	clnt;
 	struct rpc_message msg = {
-		.rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
+		.rpc_proc       = &nfs41_cb_procedures[NFSPROC4_CLNT_CB_NULL],
 		.rpc_argp       = clp,
 	};
 	char                    hostname[32];
@@ -687,6 +763,56 @@ static const struct rpc_call_ops nfs4_cb_null_ops = {
 	.rpc_call_done = nfs4_cb_null,
 };
 
+static int
+_nfsd4_cb_recall(struct nfs4_delegation *dp, struct rpc_message *msg)
+{
+	struct nfs4_client *clp = dp->dl_client;
+	struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+	struct nfs4_cb_recall *cbr = &dp->dl_recall;
+	int retries = 1;
+	int status = 0;
+
+	msg->rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL];
+	msg->rpc_argp = cbr;
+
+	status = rpc_call_sync(clnt, msg, RPC_TASK_SOFT);
+	while (retries--) {
+		switch (status) {
+			case -EIO:
+				/* Network partition? */
+			case -EBADHANDLE:
+			case -NFS4ERR_BAD_STATEID:
+				/* Race: client probably got cb_recall
+				 * before open reply granting delegation */
+				break;
+			default:
+				return status;
+		}
+		ssleep(2);
+		status = rpc_call_sync(clnt, msg, RPC_TASK_SOFT);
+	}
+
+	return status;
+}
+
+#if defined(CONFIG_NFSD_V4_1)
+static int
+_nfsd41_cb_recall(struct nfs4_delegation *dp, struct rpc_message *msg)
+{
+	struct nfs4_client *clp = dp->dl_client;
+	struct rpc_clnt *clnt = clp->cl_callback.cb_client;
+	struct nfs4_cb_recall *cbr = &dp->dl_recall;
+	int status;
+
+	msg->rpc_proc = &nfs41_cb_procedures[NFSPROC4_CLNT_CB_RECALL];
+	msg->rpc_argp = cbr;
+
+	status = rpc_call_sync(clnt, msg, RPC_TASK_SOFT);
+
+	return status;
+}
+#endif /* defined(CONFIG_NFSD_V4_1) */
+
 /*
  * called with dp->dl_count inc'ed.
  * nfs4_lock_state() may or may not have been called.
@@ -711,26 +837,18 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
 	if (IS_ERR(msg.rpc_cred))
 		goto out;
 
-	cbr->cbr_minorversion = clp->cl_callback.cb_minorversion;
 	cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */
 	cbr->cbr_dp = dp;
 
-	status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT);
-	while (retries--) {
-		switch (status) {
-			case -EIO:
-				/* Network partition? */
-			case -EBADHANDLE:
-			case -NFS4ERR_BAD_STATEID:
-				/* Race: client probably got cb_recall
-				 * before open reply granting delegation */
-				break;
-			default:
-				goto out_put_cred;
-		}
-		ssleep(2);
-		status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT);
+#if defined(CONFIG_NFSD_V4_1)
+	if (clp->cl_callback.cb_minorversion == 1) {
+		status = _nfsd41_cb_recall(dp, &msg);
+		goto out_put_cred;
 	}
+#endif /* defined(CONFIG_NFSD_V4_1) */
+
+	status = _nfsd4_cb_recall(dp, &msg);
+
 out_put_cred:
 	put_rpccred(msg.rpc_cred);
 out:
@@ -757,7 +875,7 @@ nfsd4_cb_layout(struct nfs4_layoutrecall *clr)
 	struct nfs4_client *clp = clr->clr_client;
 	struct rpc_clnt *clnt = NULL;
 	struct rpc_message msg = {
-		.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_LAYOUT],
+		.rpc_proc = &nfs41_cb_procedures[NFSPROC4_CLNT_CB_RECALL],
 		.rpc_argp = clr,
 	};
 
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
index c905f6d..f15a975 100644
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -70,7 +70,6 @@ typedef struct {
 
 
 struct nfs4_cb_recall {
-	u32			cbr_minorversion;
 	u32			cbr_ident;
 	int			cbr_trunc;
 	stateid_t		cbr_stateid;
-- 
1.5.2.86.g99b5


--------------060104090809030008020508
Content-Type: text/plain;
 name*0="0004-cb_sequence-nfsd-callback-initial-implementation.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename*0="0004-cb_sequence-nfsd-callback-initial-implementation.patch"



More information about the pNFS mailing list