[pnfs] [PATCH 1/5] cb_sequence: client support for minorversion1 callbacks
Benny Halevy
bhalevy at panasas.com
Thu May 31 14:08:28 EDT 2007
Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
fs/nfs/callback.h | 13 +++++++++-
fs/nfs/callback_xdr.c | 63 ++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 61 insertions(+), 15 deletions(-)
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index 3b98754..263fc85 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -20,13 +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 29f9321..9b2fbde 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -132,7 +132,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);
@@ -147,14 +146,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;
}
@@ -353,31 +353,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:
op = &callback_ops[op_nr];
break;
- default:
- op_nr = OP_CB_ILLEGAL;
+ case OP_CB_LAYOUTRECALL:
+ 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))
@@ -394,6 +422,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;
}
/*
@@ -422,7 +456,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)
@@ -436,7 +471,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] = {
--
1.5.2.86.g99b5
More information about the pNFS
mailing list