nfsd: tabulate nfs4 xdr encoding functions
authorBenny Halevy <bhalevy@panasas.com>
Fri, 4 Jul 2008 11:38:33 +0000 (14:38 +0300)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Fri, 4 Jul 2008 20:21:30 +0000 (16:21 -0400)
In preparation for minorversion 1

All encoders now return an nfserr status (typically their
nfserr argument).  Unsupported ops go through nfsd4_encode_operation
too, so use nfsd4_encode_noop to encode nothing for their reply body.

Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
fs/nfsd/nfs4xdr.c

index a40bec53fa66e908d2d74886c7f6c7cf8aed5758..9b6a9bafc6b402afe88f9ea40dab2e55993ab462 100644 (file)
@@ -1950,7 +1950,7 @@ fail:
        return -EINVAL;
 }
 
-static void
+static __be32
 nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
 {
        ENCODE_HEAD;
@@ -1961,9 +1961,10 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
                WRITE32(access->ac_resp_access);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
 {
        ENCODE_SEQID_OP_HEAD;
@@ -1975,10 +1976,11 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
                ADJUST_ARGS();
        }
        ENCODE_SEQID_OP_TAIL(close->cl_stateowner);
+       return nfserr;
 }
 
 
-static void
+static __be32
 nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
 {
        ENCODE_HEAD;
@@ -1988,9 +1990,10 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
                WRITEMEM(commit->co_verf.data, 8);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
 {
        ENCODE_HEAD;
@@ -2003,6 +2006,7 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
                WRITE32(create->cr_bmval[1]);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
 static __be32
@@ -2023,9 +2027,10 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
        return nfserr;
 }
 
-static void
-nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh *fhp)
+static __be32
+nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
 {
+       struct svc_fh *fhp = *fhpp;
        unsigned int len;
        ENCODE_HEAD;
 
@@ -2036,6 +2041,7 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
                WRITEMEM(&fhp->fh_handle.fh_base, len);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
 /*
@@ -2063,7 +2069,7 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie
        ADJUST_ARGS();
 }
 
-static void
+static __be32
 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
 {
        ENCODE_SEQID_OP_HEAD;
@@ -2077,16 +2083,18 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo
                nfsd4_encode_lock_denied(resp, &lock->lk_denied);
 
        ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
 {
        if (nfserr == nfserr_denied)
                nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
 {
        ENCODE_SEQID_OP_HEAD;
@@ -2099,10 +2107,11 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
        }
                                        
        ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);
+       return nfserr;
 }
 
 
-static void
+static __be32
 nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
 {
        ENCODE_HEAD;
@@ -2112,10 +2121,11 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li
                WRITECINFO(link->li_cinfo);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
 
-static void
+static __be32
 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
 {
        ENCODE_SEQID_OP_HEAD;
@@ -2178,9 +2188,10 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
        /* XXX save filehandle here */
 out:
        ENCODE_SEQID_OP_TAIL(open->op_stateowner);
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
 {
        ENCODE_SEQID_OP_HEAD;
@@ -2193,9 +2204,10 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct
        }
 
        ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
 {
        ENCODE_SEQID_OP_HEAD;
@@ -2208,6 +2220,7 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struc
        }
 
        ENCODE_SEQID_OP_TAIL(od->od_stateowner);
+       return nfserr;
 }
 
 static __be32
@@ -2402,7 +2415,7 @@ err_no_verf:
        return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
 {
        ENCODE_HEAD;
@@ -2412,9 +2425,10 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
                WRITECINFO(remove->rm_cinfo);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
 {
        ENCODE_HEAD;
@@ -2425,9 +2439,10 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
                WRITECINFO(rename->rn_tinfo);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
                     struct nfsd4_secinfo *secinfo)
 {
@@ -2491,13 +2506,14 @@ nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
 out:
        if (exp)
                exp_put(exp);
+       return nfserr;
 }
 
 /*
  * The SETATTR encode routine is special -- it always encodes a bitmap,
  * regardless of the error status.
  */
-static void
+static __be32
 nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
 {
        ENCODE_HEAD;
@@ -2514,9 +2530,10 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
                WRITE32(setattr->sa_bmval[1]);
        }
        ADJUST_ARGS();
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
 {
        ENCODE_HEAD;
@@ -2533,9 +2550,10 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct n
                WRITE32(0);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
-static void
+static __be32
 nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
 {
        ENCODE_HEAD;
@@ -2547,8 +2565,56 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w
                WRITEMEM(write->wr_verifier.data, 8);
                ADJUST_ARGS();
        }
+       return nfserr;
 }
 
+static __be32
+nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
+{
+       return nfserr;
+}
+
+typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
+
+static nfsd4_enc nfsd4_enc_ops[] = {
+       [OP_ACCESS]             (nfsd4_enc)nfsd4_encode_access,
+       [OP_CLOSE]              (nfsd4_enc)nfsd4_encode_close,
+       [OP_COMMIT]             (nfsd4_enc)nfsd4_encode_commit,
+       [OP_CREATE]             (nfsd4_enc)nfsd4_encode_create,
+       [OP_DELEGPURGE]         (nfsd4_enc)nfsd4_encode_noop,
+       [OP_DELEGRETURN]        (nfsd4_enc)nfsd4_encode_noop,
+       [OP_GETATTR]            (nfsd4_enc)nfsd4_encode_getattr,
+       [OP_GETFH]              (nfsd4_enc)nfsd4_encode_getfh,
+       [OP_LINK]               (nfsd4_enc)nfsd4_encode_link,
+       [OP_LOCK]               (nfsd4_enc)nfsd4_encode_lock,
+       [OP_LOCKT]              (nfsd4_enc)nfsd4_encode_lockt,
+       [OP_LOCKU]              (nfsd4_enc)nfsd4_encode_locku,
+       [OP_LOOKUP]             (nfsd4_enc)nfsd4_encode_noop,
+       [OP_LOOKUPP]            (nfsd4_enc)nfsd4_encode_noop,
+       [OP_NVERIFY]            (nfsd4_enc)nfsd4_encode_noop,
+       [OP_OPEN]               (nfsd4_enc)nfsd4_encode_open,
+       [OP_OPEN_CONFIRM]       (nfsd4_enc)nfsd4_encode_open_confirm,
+       [OP_OPEN_DOWNGRADE]     (nfsd4_enc)nfsd4_encode_open_downgrade,
+       [OP_PUTFH]              (nfsd4_enc)nfsd4_encode_noop,
+       [OP_PUTPUBFH]           (nfsd4_enc)nfsd4_encode_noop,
+       [OP_PUTROOTFH]          (nfsd4_enc)nfsd4_encode_noop,
+       [OP_READ]               (nfsd4_enc)nfsd4_encode_read,
+       [OP_READDIR]            (nfsd4_enc)nfsd4_encode_readdir,
+       [OP_READLINK]           (nfsd4_enc)nfsd4_encode_readlink,
+       [OP_REMOVE]             (nfsd4_enc)nfsd4_encode_remove,
+       [OP_RENAME]             (nfsd4_enc)nfsd4_encode_rename,
+       [OP_RENEW]              (nfsd4_enc)nfsd4_encode_noop,
+       [OP_RESTOREFH]          (nfsd4_enc)nfsd4_encode_noop,
+       [OP_SAVEFH]             (nfsd4_enc)nfsd4_encode_noop,
+       [OP_SECINFO]            (nfsd4_enc)nfsd4_encode_secinfo,
+       [OP_SETATTR]            (nfsd4_enc)nfsd4_encode_setattr,
+       [OP_SETCLIENTID]        (nfsd4_enc)nfsd4_encode_setclientid,
+       [OP_SETCLIENTID_CONFIRM](nfsd4_enc)nfsd4_encode_noop,
+       [OP_VERIFY]             (nfsd4_enc)nfsd4_encode_noop,
+       [OP_WRITE]              (nfsd4_enc)nfsd4_encode_write,
+       [OP_RELEASE_LOCKOWNER]  (nfsd4_enc)nfsd4_encode_noop,
+};
+
 void
 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 {
@@ -2560,101 +2626,12 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
        statp = p++;    /* to be backfilled at the end */
        ADJUST_ARGS();
 
-       switch (op->opnum) {
-       case OP_ACCESS:
-               nfsd4_encode_access(resp, op->status, &op->u.access);
-               break;
-       case OP_CLOSE:
-               nfsd4_encode_close(resp, op->status, &op->u.close);
-               break;
-       case OP_COMMIT:
-               nfsd4_encode_commit(resp, op->status, &op->u.commit);
-               break;
-       case OP_CREATE:
-               nfsd4_encode_create(resp, op->status, &op->u.create);
-               break;
-       case OP_DELEGRETURN:
-               break;
-       case OP_GETATTR:
-               op->status = nfsd4_encode_getattr(resp, op->status, &op->u.getattr);
-               break;
-       case OP_GETFH:
-               nfsd4_encode_getfh(resp, op->status, op->u.getfh);
-               break;
-       case OP_LINK:
-               nfsd4_encode_link(resp, op->status, &op->u.link);
-               break;
-       case OP_LOCK:
-               nfsd4_encode_lock(resp, op->status, &op->u.lock);
-               break;
-       case OP_LOCKT:
-               nfsd4_encode_lockt(resp, op->status, &op->u.lockt);
-               break;
-       case OP_LOCKU:
-               nfsd4_encode_locku(resp, op->status, &op->u.locku);
-               break;
-       case OP_LOOKUP:
-               break;
-       case OP_LOOKUPP:
-               break;
-       case OP_NVERIFY:
-               break;
-       case OP_OPEN:
-               nfsd4_encode_open(resp, op->status, &op->u.open);
-               break;
-       case OP_OPEN_CONFIRM:
-               nfsd4_encode_open_confirm(resp, op->status, &op->u.open_confirm);
-               break;
-       case OP_OPEN_DOWNGRADE:
-               nfsd4_encode_open_downgrade(resp, op->status, &op->u.open_downgrade);
-               break;
-       case OP_PUTFH:
-               break;
-       case OP_PUTROOTFH:
-               break;
-       case OP_READ:
-               op->status = nfsd4_encode_read(resp, op->status, &op->u.read);
-               break;
-       case OP_READDIR:
-               op->status = nfsd4_encode_readdir(resp, op->status, &op->u.readdir);
-               break;
-       case OP_READLINK:
-               op->status = nfsd4_encode_readlink(resp, op->status, &op->u.readlink);
-               break;
-       case OP_REMOVE:
-               nfsd4_encode_remove(resp, op->status, &op->u.remove);
-               break;
-       case OP_RENAME:
-               nfsd4_encode_rename(resp, op->status, &op->u.rename);
-               break;
-       case OP_RENEW:
-               break;
-       case OP_RESTOREFH:
-               break;
-       case OP_SAVEFH:
-               break;
-       case OP_SECINFO:
-               nfsd4_encode_secinfo(resp, op->status, &op->u.secinfo);
-               break;
-       case OP_SETATTR:
-               nfsd4_encode_setattr(resp, op->status, &op->u.setattr);
-               break;
-       case OP_SETCLIENTID:
-               nfsd4_encode_setclientid(resp, op->status, &op->u.setclientid);
-               break;
-       case OP_SETCLIENTID_CONFIRM:
-               break;
-       case OP_VERIFY:
-               break;
-       case OP_WRITE:
-               nfsd4_encode_write(resp, op->status, &op->u.write);
-               break;
-       case OP_RELEASE_LOCKOWNER:
-               break;
-       default:
-               break;
-       }
-
+       if (op->opnum == OP_ILLEGAL)
+               goto status;
+       BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
+              !nfsd4_enc_ops[op->opnum]);
+       op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
+status:
        /*
         * Note: We write the status directly, instead of using WRITE32(),
         * since it is already in network byte order.