diff options
author | Anna Schumaker <bjschuma@netapp.com> | 2013-10-30 10:00:20 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2013-10-30 10:04:08 -0400 |
commit | e1a90ebd8b2349eb00ec22f0b8bf6ab8bbd06cc8 (patch) | |
tree | 0eb2d8a2ed995ced6594855ec2dbff846e2b759c /fs/nfsd | |
parent | 6f6cc3205c5f10129b8a10cdf8abf85d9db48a60 (diff) |
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: Anna Schumaker <bjschuma@netapp.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 98 |
1 files changed, 40 insertions, 58 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index d9454fe5653f..99bebea20668 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -945,13 +945,16 @@ static __be32 | |||
945 | nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) | 945 | nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) |
946 | { | 946 | { |
947 | DECODE_HEAD; | 947 | DECODE_HEAD; |
948 | 948 | ||
949 | if (argp->minorversion >= 1) | ||
950 | return nfserr_notsupp; | ||
951 | |||
949 | status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid); | 952 | status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid); |
950 | if (status) | 953 | if (status) |
951 | return status; | 954 | return status; |
952 | READ_BUF(4); | 955 | READ_BUF(4); |
953 | READ32(open_conf->oc_seqid); | 956 | READ32(open_conf->oc_seqid); |
954 | 957 | ||
955 | DECODE_TAIL; | 958 | DECODE_TAIL; |
956 | } | 959 | } |
957 | 960 | ||
@@ -991,6 +994,14 @@ nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) | |||
991 | } | 994 | } |
992 | 995 | ||
993 | static __be32 | 996 | static __be32 |
997 | nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p) | ||
998 | { | ||
999 | if (argp->minorversion == 0) | ||
1000 | return nfs_ok; | ||
1001 | return nfserr_notsupp; | ||
1002 | } | ||
1003 | |||
1004 | static __be32 | ||
994 | nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) | 1005 | nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) |
995 | { | 1006 | { |
996 | DECODE_HEAD; | 1007 | DECODE_HEAD; |
@@ -1061,6 +1072,9 @@ nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid) | |||
1061 | { | 1072 | { |
1062 | DECODE_HEAD; | 1073 | DECODE_HEAD; |
1063 | 1074 | ||
1075 | if (argp->minorversion >= 1) | ||
1076 | return nfserr_notsupp; | ||
1077 | |||
1064 | READ_BUF(sizeof(clientid_t)); | 1078 | READ_BUF(sizeof(clientid_t)); |
1065 | COPYMEM(clientid, sizeof(clientid_t)); | 1079 | COPYMEM(clientid, sizeof(clientid_t)); |
1066 | 1080 | ||
@@ -1111,6 +1125,9 @@ nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclient | |||
1111 | { | 1125 | { |
1112 | DECODE_HEAD; | 1126 | DECODE_HEAD; |
1113 | 1127 | ||
1128 | if (argp->minorversion >= 1) | ||
1129 | return nfserr_notsupp; | ||
1130 | |||
1114 | READ_BUF(NFS4_VERIFIER_SIZE); | 1131 | READ_BUF(NFS4_VERIFIER_SIZE); |
1115 | COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE); | 1132 | COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE); |
1116 | 1133 | ||
@@ -1137,6 +1154,9 @@ nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_s | |||
1137 | { | 1154 | { |
1138 | DECODE_HEAD; | 1155 | DECODE_HEAD; |
1139 | 1156 | ||
1157 | if (argp->minorversion >= 1) | ||
1158 | return nfserr_notsupp; | ||
1159 | |||
1140 | READ_BUF(8 + NFS4_VERIFIER_SIZE); | 1160 | READ_BUF(8 + NFS4_VERIFIER_SIZE); |
1141 | COPYMEM(&scd_c->sc_clientid, 8); | 1161 | COPYMEM(&scd_c->sc_clientid, 8); |
1142 | COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE); | 1162 | COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE); |
@@ -1220,6 +1240,9 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel | |||
1220 | { | 1240 | { |
1221 | DECODE_HEAD; | 1241 | DECODE_HEAD; |
1222 | 1242 | ||
1243 | if (argp->minorversion >= 1) | ||
1244 | return nfserr_notsupp; | ||
1245 | |||
1223 | READ_BUF(12); | 1246 | READ_BUF(12); |
1224 | COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); | 1247 | COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t)); |
1225 | READ32(rlockowner->rl_owner.len); | 1248 | READ32(rlockowner->rl_owner.len); |
@@ -1519,7 +1542,7 @@ static nfsd4_dec nfsd4_dec_ops[] = { | |||
1519 | [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, | 1542 | [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm, |
1520 | [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, | 1543 | [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, |
1521 | [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, | 1544 | [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, |
1522 | [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_noop, | 1545 | [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_putpubfh, |
1523 | [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, | 1546 | [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, |
1524 | [OP_READ] = (nfsd4_dec)nfsd4_decode_read, | 1547 | [OP_READ] = (nfsd4_dec)nfsd4_decode_read, |
1525 | [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, | 1548 | [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, |
@@ -1536,46 +1559,6 @@ static nfsd4_dec nfsd4_dec_ops[] = { | |||
1536 | [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, | 1559 | [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, |
1537 | [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, | 1560 | [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, |
1538 | [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, | 1561 | [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, |
1539 | }; | ||
1540 | |||
1541 | static nfsd4_dec nfsd41_dec_ops[] = { | ||
1542 | [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, | ||
1543 | [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, | ||
1544 | [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, | ||
1545 | [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create, | ||
1546 | [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
1547 | [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn, | ||
1548 | [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr, | ||
1549 | [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop, | ||
1550 | [OP_LINK] = (nfsd4_dec)nfsd4_decode_link, | ||
1551 | [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock, | ||
1552 | [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt, | ||
1553 | [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku, | ||
1554 | [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup, | ||
1555 | [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop, | ||
1556 | [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify, | ||
1557 | [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open, | ||
1558 | [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
1559 | [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
1560 | [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade, | ||
1561 | [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh, | ||
1562 | [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
1563 | [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop, | ||
1564 | [OP_READ] = (nfsd4_dec)nfsd4_decode_read, | ||
1565 | [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir, | ||
1566 | [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop, | ||
1567 | [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove, | ||
1568 | [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename, | ||
1569 | [OP_RENEW] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
1570 | [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop, | ||
1571 | [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop, | ||
1572 | [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo, | ||
1573 | [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr, | ||
1574 | [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
1575 | [OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp, | ||
1576 | [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify, | ||
1577 | [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write, | ||
1578 | [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_notsupp, | ||
1579 | 1562 | ||
1580 | /* new operations for NFSv4.1 */ | 1563 | /* new operations for NFSv4.1 */ |
1581 | [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl, | 1564 | [OP_BACKCHANNEL_CTL] = (nfsd4_dec)nfsd4_decode_backchannel_ctl, |
@@ -1599,23 +1582,23 @@ static nfsd4_dec nfsd41_dec_ops[] = { | |||
1599 | [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, | 1582 | [OP_RECLAIM_COMPLETE] = (nfsd4_dec)nfsd4_decode_reclaim_complete, |
1600 | }; | 1583 | }; |
1601 | 1584 | ||
1602 | struct nfsd4_minorversion_ops { | 1585 | static inline bool |
1603 | nfsd4_dec *decoders; | 1586 | nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op) |
1604 | int nops; | 1587 | { |
1605 | }; | 1588 | if (op->opnum < FIRST_NFS4_OP || op->opnum > LAST_NFS4_OP) |
1606 | 1589 | return false; | |
1607 | static struct nfsd4_minorversion_ops nfsd4_minorversion[] = { | 1590 | else if (argp->minorversion == 0 && op->opnum > OP_RELEASE_LOCKOWNER) |
1608 | [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) }, | 1591 | return false; |
1609 | [1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, | 1592 | else if (argp->minorversion == 1 && op->opnum > OP_RECLAIM_COMPLETE) |
1610 | [2] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) }, | 1593 | return false; |
1611 | }; | 1594 | return true; |
1595 | } | ||
1612 | 1596 | ||
1613 | static __be32 | 1597 | static __be32 |
1614 | nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | 1598 | nfsd4_decode_compound(struct nfsd4_compoundargs *argp) |
1615 | { | 1599 | { |
1616 | DECODE_HEAD; | 1600 | DECODE_HEAD; |
1617 | struct nfsd4_op *op; | 1601 | struct nfsd4_op *op; |
1618 | struct nfsd4_minorversion_ops *ops; | ||
1619 | bool cachethis = false; | 1602 | bool cachethis = false; |
1620 | int i; | 1603 | int i; |
1621 | 1604 | ||
@@ -1640,10 +1623,9 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
1640 | } | 1623 | } |
1641 | } | 1624 | } |
1642 | 1625 | ||
1643 | if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion)) | 1626 | if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION) |
1644 | argp->opcnt = 0; | 1627 | argp->opcnt = 0; |
1645 | 1628 | ||
1646 | ops = &nfsd4_minorversion[argp->minorversion]; | ||
1647 | for (i = 0; i < argp->opcnt; i++) { | 1629 | for (i = 0; i < argp->opcnt; i++) { |
1648 | op = &argp->ops[i]; | 1630 | op = &argp->ops[i]; |
1649 | op->replay = NULL; | 1631 | op->replay = NULL; |
@@ -1651,8 +1633,8 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | |||
1651 | READ_BUF(4); | 1633 | READ_BUF(4); |
1652 | READ32(op->opnum); | 1634 | READ32(op->opnum); |
1653 | 1635 | ||
1654 | if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP) | 1636 | if (nfsd4_opnum_in_range(argp, op)) |
1655 | op->status = ops->decoders[op->opnum](argp, &op->u); | 1637 | op->status = nfsd4_dec_ops[op->opnum](argp, &op->u); |
1656 | else { | 1638 | else { |
1657 | op->opnum = OP_ILLEGAL; | 1639 | op->opnum = OP_ILLEGAL; |
1658 | op->status = nfserr_op_illegal; | 1640 | op->status = nfserr_op_illegal; |