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 | |
| 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>
| -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; |
