aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorAnna Schumaker <bjschuma@netapp.com>2013-10-30 10:00:20 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-10-30 10:04:08 -0400
commite1a90ebd8b2349eb00ec22f0b8bf6ab8bbd06cc8 (patch)
tree0eb2d8a2ed995ced6594855ec2dbff846e2b759c /fs/nfsd
parent6f6cc3205c5f10129b8a10cdf8abf85d9db48a60 (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.c98
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
945nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) 945nfsd4_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
993static __be32 996static __be32
997nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
998{
999 if (argp->minorversion == 0)
1000 return nfs_ok;
1001 return nfserr_notsupp;
1002}
1003
1004static __be32
994nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read) 1005nfsd4_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
1541static 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
1602struct nfsd4_minorversion_ops { 1585static inline bool
1603 nfsd4_dec *decoders; 1586nfsd4_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;
1607static 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
1613static __be32 1597static __be32
1614nfsd4_decode_compound(struct nfsd4_compoundargs *argp) 1598nfsd4_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;