[PATCH 1/4] cb_sequence: pnfs client support for minorversion1 callbacks
Benny Halevy
bhalevy at panasas.com
Tue May 29 09:18:18 EDT 2007
Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
fs/nfs/callback.h | 12 ++++++++-
fs/nfs/callback_xdr.c | 64 ++++++++++++++++++++++++++++++++++++++----------
2 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index aedc094..3bc2383 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -20,14 +20,24 @@ enum nfs4_callback_procnum {
enum nfs4_callback_opnum {
OP_CB_GETATTR = 3,
OP_CB_RECALL = 4,
+ /* Callback operations new to NFSv4.1 */
OP_CB_LAYOUTRECALL = 5,
+ OP_CB_NOTIFY = 6,
+ OP_CB_PUSH_DELEG = 7,
+ OP_CB_RECALL_ANY = 8,
+ OP_CB_RECALLABLE_OBJ_AVAIL = 9,
+ OP_CB_RECALL_SLOT = 10,
+ OP_CB_SEQUENCE = 11,
+ OP_CB_WANTS_CANCELLED = 12,
+ OP_CB_NOTIFY_LOCK = 13,
OP_CB_ILLEGAL = 10044,
};
struct cb_compound_hdr_arg {
int taglen;
const char *tag;
- unsigned int callback_ident;
+ unsigned int minorversion;
+ unsigned int callback_ident; /* minorversion 0 only */
unsigned nops;
};
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 9638750..f5c25ca 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -138,7 +138,6 @@ static unsigned decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
static unsigned decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
{
uint32_t *p;
- unsigned int minor_version;
unsigned status;
status = decode_string(xdr, &hdr->taglen, &hdr->tag);
@@ -153,14 +152,15 @@ static unsigned decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compou
p = read_buf(xdr, 12);
if (unlikely(p == NULL))
return htonl(NFS4ERR_RESOURCE);
- minor_version = ntohl(*p++);
+ hdr->minorversion = ntohl(*p++);
/* Check minor version is zero. */
- if (minor_version != 0) {
+ if (hdr->minorversion == 0)
+ hdr->callback_ident = ntohl(*p++);
+ else if (hdr->minorversion != 1) {
printk(KERN_WARNING "%s: NFSv4 server callback with illegal minor version %u!\n",
- __FUNCTION__, minor_version);
+ __FUNCTION__, hdr->minorversion);
return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
}
- hdr->callback_ident = ntohl(*p++);
hdr->nops = ntohl(*p);
return 0;
}
@@ -399,32 +399,59 @@ out:
return status;
}
-static unsigned process_op(struct svc_rqst *rqstp,
+static unsigned process_op(uint32_t minorversion, int nop,
+ struct svc_rqst *rqstp,
struct xdr_stream *xdr_in, void *argp,
struct xdr_stream *xdr_out, void *resp)
{
struct callback_op *op = &callback_ops[0];
- unsigned int op_nr = OP_CB_ILLEGAL;
- unsigned int status = 0;
+ unsigned int op_nr;
+ unsigned int status;
long maxlen;
unsigned res;
dprintk("%s: start\n", __FUNCTION__);
status = decode_op_hdr(xdr_in, &op_nr);
- if (likely(status == 0)) {
+ if (unlikely(status))
+ goto out_illegal;
+
+#if defined(CONFIG_NFS_V4_1)
+ if (minorversion == 1) {
switch (op_nr) {
case OP_CB_GETATTR:
case OP_CB_RECALL:
case OP_CB_LAYOUTRECALL:
op = &callback_ops[op_nr];
break;
- default:
- op_nr = OP_CB_ILLEGAL;
+ case OP_CB_NOTIFY:
+ case OP_CB_PUSH_DELEG:
+ case OP_CB_RECALL_ANY:
+ case OP_CB_RECALLABLE_OBJ_AVAIL:
+ case OP_CB_RECALL_SLOT:
+ case OP_CB_SEQUENCE:
+ case OP_CB_WANTS_CANCELLED:
+ case OP_CB_NOTIFY_LOCK:
op = &callback_ops[0];
- status = htonl(NFS4ERR_OP_ILLEGAL);
+ status = htonl(NFS4ERR_NOTSUPP);
+ break;
+ default:
+ goto out_illegal;
}
+
+ goto out;
+ }
+#endif /* defined(CONFIG_NFS_V4_1) */
+
+ switch (op_nr) {
+ case OP_CB_GETATTR:
+ case OP_CB_RECALL:
+ op = &callback_ops[op_nr];
+ break;
+ default:
+ goto out_illegal;
}
+out:
maxlen = xdr_out->end - xdr_out->p;
if (maxlen > 0 && maxlen < PAGE_SIZE) {
if (likely(status == 0 && op->decode_args != NULL))
@@ -441,6 +468,12 @@ static unsigned process_op(struct svc_rqst *rqstp,
status = op->encode_res(rqstp, xdr_out, resp);
dprintk("%s: done, status = %d\n", __FUNCTION__, status);
return status;
+
+out_illegal:
+ op_nr = OP_CB_ILLEGAL;
+ op = &callback_ops[0];
+ status = htonl(NFS4ERR_OP_ILLEGAL);
+ goto out;
}
/*
@@ -469,7 +502,8 @@ static int nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp
encode_compound_hdr_res(&xdr_out, &hdr_res);
for (;;) {
- status = process_op(rqstp, &xdr_in, argp, &xdr_out, resp);
+ status = process_op(hdr_arg.minorversion, nops,
+ rqstp, &xdr_in, argp, &xdr_out, resp);
if (status != 0)
break;
if (nops == hdr_arg.nops)
@@ -483,7 +517,7 @@ static int nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp
}
/*
- * Define NFS4 callback COMPOUND ops.
+ * Define NFS4.[01] callback COMPOUND ops.
*/
static struct callback_op callback_ops[] = {
[0] = {
@@ -500,6 +534,8 @@ static struct callback_op callback_ops[] = {
.decode_args = (callback_decode_arg_t)decode_recall_args,
.res_maxsize = CB_OP_RECALL_RES_MAXSZ,
},
+
+ /* NFSv4.1 callback operations */
[OP_CB_LAYOUTRECALL] = {
.process_op = (callback_process_op_t)nfs4_callback_pnfs_layoutrecall,
.decode_args = (callback_decode_arg_t)decode_pnfs_layoutrecall_args,
--
1.5.2.86.g99b5
--------------060104090809030008020508
Content-Type: text/plain;
name*0="0002-cb_sequence-client-implementation-of-cb_sequence.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename*0="0002-cb_sequence-client-implementation-of-cb_sequence.patch"
More information about the pNFS
mailing list