[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