Commit e1a90ebd authored by Anna Schumaker's avatar Anna Schumaker Committed by J. Bruce Fields

NFSD: Combine decode operations for v4 and v4.1

We were using a different array of function pointers to represent each
minor version.  This makes adding a new minor version tedious, since it
needs a step to copy, paste and modify a new version of the same
functions.

This patch combines the v4 and v4.1 arrays into a single instance and
will check minor version support inside each decoder function.
Signed-off-by: default avatarAnna Schumaker <bjschuma@netapp.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 6f6cc320
...@@ -945,13 +945,16 @@ static __be32 ...@@ -945,13 +945,16 @@ static __be32
nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
{ {
DECODE_HEAD; DECODE_HEAD;
if (argp->minorversion >= 1)
return nfserr_notsupp;
status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid); status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
if (status) if (status)
return status; return status;
READ_BUF(4); READ_BUF(4);
READ32(open_conf->oc_seqid); READ32(open_conf->oc_seqid);
DECODE_TAIL; DECODE_TAIL;
} }
...@@ -990,6 +993,14 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) ...@@ -990,6 +993,14 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
DECODE_TAIL; DECODE_TAIL;
} }
static __be32
nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
{
if (argp->minorversion == 0)
return nfs_ok;
return nfserr_notsupp;
}
static __be32 static __be32
nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
{ {
...@@ -1061,6 +1072,9 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) ...@@ -1061,6 +1072,9 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
{ {
DECODE_HEAD; DECODE_HEAD;
if (argp->minorversion >= 1)
return nfserr_notsupp;
READ_BUF(sizeof(clientid_t)); READ_BUF(sizeof(clientid_t));
COPYMEM(clientid, sizeof(clientid_t)); COPYMEM(clientid, sizeof(clientid_t));
...@@ -1111,6 +1125,9 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient ...@@ -1111,6 +1125,9 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient
{ {
DECODE_HEAD; DECODE_HEAD;
if (argp->minorversion >= 1)
return nfserr_notsupp;
READ_BUF(NFS4_VERIFIER_SIZE); READ_BUF(NFS4_VERIFIER_SIZE);
COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE); COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
...@@ -1137,6 +1154,9 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s ...@@ -1137,6 +1154,9 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s
{ {
DECODE_HEAD; DECODE_HEAD;
if (argp->minorversion >= 1)
return nfserr_notsupp;
READ_BUF(8 + NFS4_VERIFIER_SIZE); READ_BUF(8 + NFS4_VERIFIER_SIZE);
COPYMEM(&scd_c->sc_clientid, 8); COPYMEM(&scd_c->sc_clientid, 8);
COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE); COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
...@@ -1220,6 +1240,9 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel ...@@ -1220,6 +1240,9 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
{ {
DECODE_HEAD; DECODE_HEAD;
if (argp->minorversion >= 1)
return nfserr_notsupp;
READ_BUF(12); READ_BUF(12);
COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
READ32(rlockowner->rl_owner.len); READ32(rlockowner->rl_owner.len);
...@@ -1519,7 +1542,7 @@ static nfsd4_dec nfsd4_dec_ops[] = { ...@@ -1519,7 +1542,7 @@ static nfsd4_dec nfsd4_dec_ops[] = {
[OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm,
[OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
[OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
[OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop, [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh,
[OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
[OP_READ] = (nfsd4_dec)nfsd4_decode_read, [OP_READ] = (nfsd4_dec)nfsd4_decode_read,
[OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
...@@ -1536,46 +1559,6 @@ static nfsd4_dec nfsd4_dec_ops[] = { ...@@ -1536,46 +1559,6 @@ static nfsd4_dec nfsd4_dec_ops[] = {
[OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
[OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
[OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner,
};
static nfsd4_dec nfsd41_dec_ops[] = {
[OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
[OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
[OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
[OP_CREATE] = (nfsd4_dec)nfsd4_decode_create,
[OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn,
[OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr,
[OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop,
[OP_LINK] = (nfsd4_dec)nfsd4_decode_link,
[OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock,
[OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt,
[OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku,
[OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup,
[OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop,
[OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify,
[OP_OPEN] = (nfsd4_dec)nfsd4_decode_open,
[OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
[OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
[OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
[OP_READ] = (nfsd4_dec)nfsd4_decode_read,
[OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
[OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop,
[OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove,
[OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename,
[OP_RENEW] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop,
[OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop,
[OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo,
[OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr,
[OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp,
[OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp,
[OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
[OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
[OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp,
/* new operations for NFSv4.1 */ /* new operations for NFSv4.1 */
[OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl, [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl,
...@@ -1599,23 +1582,23 @@ static nfsd4_dec nfsd41_dec_ops[] = { ...@@ -1599,23 +1582,23 @@ static nfsd4_dec nfsd41_dec_ops[] = {
[OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete,
}; };
struct nfsd4_minorversion_ops { static inline bool
nfsd4_dec *decoders; nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
int nops; {
}; if (op->opnum < FIRST_NFS4_OP || op->opnum > LAST_NFS4_OP)
return false;
static struct nfsd4_minorversion_ops nfsd4_minorversion[] = { else if (argp->minorversion == 0 && op->opnum > OP_RELEASE_LOCKOWNER)
[0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) }, return false;
[1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, else if (argp->minorversion == 1 && op->opnum > OP_RECLAIM_COMPLETE)
[2] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, return false;
}; return true;
}
static __be32 static __be32
nfsd4_decode_compound(struct nfsd4_compoundargs *argp) nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
{ {
DECODE_HEAD; DECODE_HEAD;
struct nfsd4_op *op; struct nfsd4_op *op;
struct nfsd4_minorversion_ops *ops;
bool cachethis = false; bool cachethis = false;
int i; int i;
...@@ -1640,10 +1623,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) ...@@ -1640,10 +1623,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
} }
} }
if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion)) if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
argp->opcnt = 0; argp->opcnt = 0;
ops = &nfsd4_minorversion[argp->minorversion];
for (i = 0; i < argp->opcnt; i++) { for (i = 0; i < argp->opcnt; i++) {
op = &argp->ops[i]; op = &argp->ops[i];
op->replay = NULL; op->replay = NULL;
...@@ -1651,8 +1633,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) ...@@ -1651,8 +1633,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
READ_BUF(4); READ_BUF(4);
READ32(op->opnum); READ32(op->opnum);
if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP) if (nfsd4_opnum_in_range(argp, op))
op->status = ops->decoders[op->opnum](argp, &op->u); op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
else { else {
op->opnum = OP_ILLEGAL; op->opnum = OP_ILLEGAL;
op->status = nfserr_op_illegal; op->status = nfserr_op_illegal;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment