aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c392
1 files changed, 164 insertions, 228 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c513bbdf2d36..14ba4d9b2859 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -986,10 +986,74 @@ nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_rel
986} 986}
987 987
988static __be32 988static __be32
989nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
990{
991 return nfs_ok;
992}
993
994static __be32
995nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
996{
997 return nfserr_opnotsupp;
998}
999
1000typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
1001
1002static nfsd4_dec nfsd4_dec_ops[] = {
1003 [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
1004 [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
1005 [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
1006 [OP_CREATE] = (nfsd4_dec)nfsd4_decode_create,
1007 [OP_DELEGPURGE] = (nfsd4_dec)nfsd4_decode_notsupp,
1008 [OP_DELEGRETURN] = (nfsd4_dec)nfsd4_decode_delegreturn,
1009 [OP_GETATTR] = (nfsd4_dec)nfsd4_decode_getattr,
1010 [OP_GETFH] = (nfsd4_dec)nfsd4_decode_noop,
1011 [OP_LINK] = (nfsd4_dec)nfsd4_decode_link,
1012 [OP_LOCK] = (nfsd4_dec)nfsd4_decode_lock,
1013 [OP_LOCKT] = (nfsd4_dec)nfsd4_decode_lockt,
1014 [OP_LOCKU] = (nfsd4_dec)nfsd4_decode_locku,
1015 [OP_LOOKUP] = (nfsd4_dec)nfsd4_decode_lookup,
1016 [OP_LOOKUPP] = (nfsd4_dec)nfsd4_decode_noop,
1017 [OP_NVERIFY] = (nfsd4_dec)nfsd4_decode_verify,
1018 [OP_OPEN] = (nfsd4_dec)nfsd4_decode_open,
1019 [OP_OPENATTR] = (nfsd4_dec)nfsd4_decode_notsupp,
1020 [OP_OPEN_CONFIRM] = (nfsd4_dec)nfsd4_decode_open_confirm,
1021 [OP_OPEN_DOWNGRADE] = (nfsd4_dec)nfsd4_decode_open_downgrade,
1022 [OP_PUTFH] = (nfsd4_dec)nfsd4_decode_putfh,
1023 [OP_PUTPUBFH] = (nfsd4_dec)nfsd4_decode_notsupp,
1024 [OP_PUTROOTFH] = (nfsd4_dec)nfsd4_decode_noop,
1025 [OP_READ] = (nfsd4_dec)nfsd4_decode_read,
1026 [OP_READDIR] = (nfsd4_dec)nfsd4_decode_readdir,
1027 [OP_READLINK] = (nfsd4_dec)nfsd4_decode_noop,
1028 [OP_REMOVE] = (nfsd4_dec)nfsd4_decode_remove,
1029 [OP_RENAME] = (nfsd4_dec)nfsd4_decode_rename,
1030 [OP_RENEW] = (nfsd4_dec)nfsd4_decode_renew,
1031 [OP_RESTOREFH] = (nfsd4_dec)nfsd4_decode_noop,
1032 [OP_SAVEFH] = (nfsd4_dec)nfsd4_decode_noop,
1033 [OP_SECINFO] = (nfsd4_dec)nfsd4_decode_secinfo,
1034 [OP_SETATTR] = (nfsd4_dec)nfsd4_decode_setattr,
1035 [OP_SETCLIENTID] = (nfsd4_dec)nfsd4_decode_setclientid,
1036 [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
1037 [OP_VERIFY] = (nfsd4_dec)nfsd4_decode_verify,
1038 [OP_WRITE] = (nfsd4_dec)nfsd4_decode_write,
1039 [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner,
1040};
1041
1042struct nfsd4_minorversion_ops {
1043 nfsd4_dec *decoders;
1044 int nops;
1045};
1046
1047static struct nfsd4_minorversion_ops nfsd4_minorversion[] = {
1048 [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) },
1049};
1050
1051static __be32
989nfsd4_decode_compound(struct nfsd4_compoundargs *argp) 1052nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
990{ 1053{
991 DECODE_HEAD; 1054 DECODE_HEAD;
992 struct nfsd4_op *op; 1055 struct nfsd4_op *op;
1056 struct nfsd4_minorversion_ops *ops;
993 int i; 1057 int i;
994 1058
995 /* 1059 /*
@@ -1019,6 +1083,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1019 } 1083 }
1020 } 1084 }
1021 1085
1086 if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion))
1087 argp->opcnt = 0;
1088
1089 ops = &nfsd4_minorversion[argp->minorversion];
1022 for (i = 0; i < argp->opcnt; i++) { 1090 for (i = 0; i < argp->opcnt; i++) {
1023 op = &argp->ops[i]; 1091 op = &argp->ops[i];
1024 op->replay = NULL; 1092 op->replay = NULL;
@@ -1056,120 +1124,11 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1056 } 1124 }
1057 op->opnum = ntohl(*argp->p++); 1125 op->opnum = ntohl(*argp->p++);
1058 1126
1059 switch (op->opnum) { 1127 if (op->opnum >= OP_ACCESS && op->opnum < ops->nops)
1060 case 2: /* Reserved operation */ 1128 op->status = ops->decoders[op->opnum](argp, &op->u);
1061 op->opnum = OP_ILLEGAL; 1129 else {
1062 if (argp->minorversion == 0)
1063 op->status = nfserr_op_illegal;
1064 else
1065 op->status = nfserr_minor_vers_mismatch;
1066 break;
1067 case OP_ACCESS:
1068 op->status = nfsd4_decode_access(argp, &op->u.access);
1069 break;
1070 case OP_CLOSE:
1071 op->status = nfsd4_decode_close(argp, &op->u.close);
1072 break;
1073 case OP_COMMIT:
1074 op->status = nfsd4_decode_commit(argp, &op->u.commit);
1075 break;
1076 case OP_CREATE:
1077 op->status = nfsd4_decode_create(argp, &op->u.create);
1078 break;
1079 case OP_DELEGRETURN:
1080 op->status = nfsd4_decode_delegreturn(argp, &op->u.delegreturn);
1081 break;
1082 case OP_GETATTR:
1083 op->status = nfsd4_decode_getattr(argp, &op->u.getattr);
1084 break;
1085 case OP_GETFH:
1086 op->status = nfs_ok;
1087 break;
1088 case OP_LINK:
1089 op->status = nfsd4_decode_link(argp, &op->u.link);
1090 break;
1091 case OP_LOCK:
1092 op->status = nfsd4_decode_lock(argp, &op->u.lock);
1093 break;
1094 case OP_LOCKT:
1095 op->status = nfsd4_decode_lockt(argp, &op->u.lockt);
1096 break;
1097 case OP_LOCKU:
1098 op->status = nfsd4_decode_locku(argp, &op->u.locku);
1099 break;
1100 case OP_LOOKUP:
1101 op->status = nfsd4_decode_lookup(argp, &op->u.lookup);
1102 break;
1103 case OP_LOOKUPP:
1104 op->status = nfs_ok;
1105 break;
1106 case OP_NVERIFY:
1107 op->status = nfsd4_decode_verify(argp, &op->u.nverify);
1108 break;
1109 case OP_OPEN:
1110 op->status = nfsd4_decode_open(argp, &op->u.open);
1111 break;
1112 case OP_OPEN_CONFIRM:
1113 op->status = nfsd4_decode_open_confirm(argp, &op->u.open_confirm);
1114 break;
1115 case OP_OPEN_DOWNGRADE:
1116 op->status = nfsd4_decode_open_downgrade(argp, &op->u.open_downgrade);
1117 break;
1118 case OP_PUTFH:
1119 op->status = nfsd4_decode_putfh(argp, &op->u.putfh);
1120 break;
1121 case OP_PUTROOTFH:
1122 op->status = nfs_ok;
1123 break;
1124 case OP_READ:
1125 op->status = nfsd4_decode_read(argp, &op->u.read);
1126 break;
1127 case OP_READDIR:
1128 op->status = nfsd4_decode_readdir(argp, &op->u.readdir);
1129 break;
1130 case OP_READLINK:
1131 op->status = nfs_ok;
1132 break;
1133 case OP_REMOVE:
1134 op->status = nfsd4_decode_remove(argp, &op->u.remove);
1135 break;
1136 case OP_RENAME:
1137 op->status = nfsd4_decode_rename(argp, &op->u.rename);
1138 break;
1139 case OP_RESTOREFH:
1140 op->status = nfs_ok;
1141 break;
1142 case OP_RENEW:
1143 op->status = nfsd4_decode_renew(argp, &op->u.renew);
1144 break;
1145 case OP_SAVEFH:
1146 op->status = nfs_ok;
1147 break;
1148 case OP_SECINFO:
1149 op->status = nfsd4_decode_secinfo(argp, &op->u.secinfo);
1150 break;
1151 case OP_SETATTR:
1152 op->status = nfsd4_decode_setattr(argp, &op->u.setattr);
1153 break;
1154 case OP_SETCLIENTID:
1155 op->status = nfsd4_decode_setclientid(argp, &op->u.setclientid);
1156 break;
1157 case OP_SETCLIENTID_CONFIRM:
1158 op->status = nfsd4_decode_setclientid_confirm(argp, &op->u.setclientid_confirm);
1159 break;
1160 case OP_VERIFY:
1161 op->status = nfsd4_decode_verify(argp, &op->u.verify);
1162 break;
1163 case OP_WRITE:
1164 op->status = nfsd4_decode_write(argp, &op->u.write);
1165 break;
1166 case OP_RELEASE_LOCKOWNER:
1167 op->status = nfsd4_decode_release_lockowner(argp, &op->u.release_lockowner);
1168 break;
1169 default:
1170 op->opnum = OP_ILLEGAL; 1130 op->opnum = OP_ILLEGAL;
1171 op->status = nfserr_op_illegal; 1131 op->status = nfserr_op_illegal;
1172 break;
1173 } 1132 }
1174 1133
1175 if (op->status) { 1134 if (op->status) {
@@ -1201,11 +1160,11 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1201 *p++ = htonl((u32)((n) >> 32)); \ 1160 *p++ = htonl((u32)((n) >> 32)); \
1202 *p++ = htonl((u32)(n)); \ 1161 *p++ = htonl((u32)(n)); \
1203} while (0) 1162} while (0)
1204#define WRITEMEM(ptr,nbytes) do { \ 1163#define WRITEMEM(ptr,nbytes) do { if (nbytes > 0) { \
1205 *(p + XDR_QUADLEN(nbytes) -1) = 0; \ 1164 *(p + XDR_QUADLEN(nbytes) -1) = 0; \
1206 memcpy(p, ptr, nbytes); \ 1165 memcpy(p, ptr, nbytes); \
1207 p += XDR_QUADLEN(nbytes); \ 1166 p += XDR_QUADLEN(nbytes); \
1208} while (0) 1167}} while (0)
1209#define WRITECINFO(c) do { \ 1168#define WRITECINFO(c) do { \
1210 *p++ = htonl(c.atomic); \ 1169 *p++ = htonl(c.atomic); \
1211 *p++ = htonl(c.before_ctime_sec); \ 1170 *p++ = htonl(c.before_ctime_sec); \
@@ -1991,7 +1950,7 @@ fail:
1991 return -EINVAL; 1950 return -EINVAL;
1992} 1951}
1993 1952
1994static void 1953static __be32
1995nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) 1954nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
1996{ 1955{
1997 ENCODE_HEAD; 1956 ENCODE_HEAD;
@@ -2002,9 +1961,10 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2002 WRITE32(access->ac_resp_access); 1961 WRITE32(access->ac_resp_access);
2003 ADJUST_ARGS(); 1962 ADJUST_ARGS();
2004 } 1963 }
1964 return nfserr;
2005} 1965}
2006 1966
2007static void 1967static __be32
2008nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) 1968nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2009{ 1969{
2010 ENCODE_SEQID_OP_HEAD; 1970 ENCODE_SEQID_OP_HEAD;
@@ -2016,10 +1976,11 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
2016 ADJUST_ARGS(); 1976 ADJUST_ARGS();
2017 } 1977 }
2018 ENCODE_SEQID_OP_TAIL(close->cl_stateowner); 1978 ENCODE_SEQID_OP_TAIL(close->cl_stateowner);
1979 return nfserr;
2019} 1980}
2020 1981
2021 1982
2022static void 1983static __be32
2023nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) 1984nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
2024{ 1985{
2025 ENCODE_HEAD; 1986 ENCODE_HEAD;
@@ -2029,9 +1990,10 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2029 WRITEMEM(commit->co_verf.data, 8); 1990 WRITEMEM(commit->co_verf.data, 8);
2030 ADJUST_ARGS(); 1991 ADJUST_ARGS();
2031 } 1992 }
1993 return nfserr;
2032} 1994}
2033 1995
2034static void 1996static __be32
2035nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) 1997nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
2036{ 1998{
2037 ENCODE_HEAD; 1999 ENCODE_HEAD;
@@ -2044,6 +2006,7 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2044 WRITE32(create->cr_bmval[1]); 2006 WRITE32(create->cr_bmval[1]);
2045 ADJUST_ARGS(); 2007 ADJUST_ARGS();
2046 } 2008 }
2009 return nfserr;
2047} 2010}
2048 2011
2049static __be32 2012static __be32
@@ -2064,9 +2027,10 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
2064 return nfserr; 2027 return nfserr;
2065} 2028}
2066 2029
2067static void 2030static __be32
2068nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh *fhp) 2031nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
2069{ 2032{
2033 struct svc_fh *fhp = *fhpp;
2070 unsigned int len; 2034 unsigned int len;
2071 ENCODE_HEAD; 2035 ENCODE_HEAD;
2072 2036
@@ -2077,6 +2041,7 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
2077 WRITEMEM(&fhp->fh_handle.fh_base, len); 2041 WRITEMEM(&fhp->fh_handle.fh_base, len);
2078 ADJUST_ARGS(); 2042 ADJUST_ARGS();
2079 } 2043 }
2044 return nfserr;
2080} 2045}
2081 2046
2082/* 2047/*
@@ -2104,7 +2069,7 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie
2104 ADJUST_ARGS(); 2069 ADJUST_ARGS();
2105} 2070}
2106 2071
2107static void 2072static __be32
2108nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) 2073nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
2109{ 2074{
2110 ENCODE_SEQID_OP_HEAD; 2075 ENCODE_SEQID_OP_HEAD;
@@ -2118,16 +2083,18 @@ nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lo
2118 nfsd4_encode_lock_denied(resp, &lock->lk_denied); 2083 nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2119 2084
2120 ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner); 2085 ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);
2086 return nfserr;
2121} 2087}
2122 2088
2123static void 2089static __be32
2124nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) 2090nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
2125{ 2091{
2126 if (nfserr == nfserr_denied) 2092 if (nfserr == nfserr_denied)
2127 nfsd4_encode_lock_denied(resp, &lockt->lt_denied); 2093 nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
2094 return nfserr;
2128} 2095}
2129 2096
2130static void 2097static __be32
2131nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) 2098nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
2132{ 2099{
2133 ENCODE_SEQID_OP_HEAD; 2100 ENCODE_SEQID_OP_HEAD;
@@ -2140,10 +2107,11 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
2140 } 2107 }
2141 2108
2142 ENCODE_SEQID_OP_TAIL(locku->lu_stateowner); 2109 ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);
2110 return nfserr;
2143} 2111}
2144 2112
2145 2113
2146static void 2114static __be32
2147nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) 2115nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
2148{ 2116{
2149 ENCODE_HEAD; 2117 ENCODE_HEAD;
@@ -2153,10 +2121,11 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li
2153 WRITECINFO(link->li_cinfo); 2121 WRITECINFO(link->li_cinfo);
2154 ADJUST_ARGS(); 2122 ADJUST_ARGS();
2155 } 2123 }
2124 return nfserr;
2156} 2125}
2157 2126
2158 2127
2159static void 2128static __be32
2160nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) 2129nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
2161{ 2130{
2162 ENCODE_SEQID_OP_HEAD; 2131 ENCODE_SEQID_OP_HEAD;
@@ -2219,9 +2188,10 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
2219 /* XXX save filehandle here */ 2188 /* XXX save filehandle here */
2220out: 2189out:
2221 ENCODE_SEQID_OP_TAIL(open->op_stateowner); 2190 ENCODE_SEQID_OP_TAIL(open->op_stateowner);
2191 return nfserr;
2222} 2192}
2223 2193
2224static void 2194static __be32
2225nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) 2195nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2226{ 2196{
2227 ENCODE_SEQID_OP_HEAD; 2197 ENCODE_SEQID_OP_HEAD;
@@ -2234,9 +2204,10 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct
2234 } 2204 }
2235 2205
2236 ENCODE_SEQID_OP_TAIL(oc->oc_stateowner); 2206 ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
2207 return nfserr;
2237} 2208}
2238 2209
2239static void 2210static __be32
2240nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) 2211nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2241{ 2212{
2242 ENCODE_SEQID_OP_HEAD; 2213 ENCODE_SEQID_OP_HEAD;
@@ -2249,6 +2220,7 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struc
2249 } 2220 }
2250 2221
2251 ENCODE_SEQID_OP_TAIL(od->od_stateowner); 2222 ENCODE_SEQID_OP_TAIL(od->od_stateowner);
2223 return nfserr;
2252} 2224}
2253 2225
2254static __be32 2226static __be32
@@ -2443,7 +2415,7 @@ err_no_verf:
2443 return nfserr; 2415 return nfserr;
2444} 2416}
2445 2417
2446static void 2418static __be32
2447nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) 2419nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
2448{ 2420{
2449 ENCODE_HEAD; 2421 ENCODE_HEAD;
@@ -2453,9 +2425,10 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2453 WRITECINFO(remove->rm_cinfo); 2425 WRITECINFO(remove->rm_cinfo);
2454 ADJUST_ARGS(); 2426 ADJUST_ARGS();
2455 } 2427 }
2428 return nfserr;
2456} 2429}
2457 2430
2458static void 2431static __be32
2459nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) 2432nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
2460{ 2433{
2461 ENCODE_HEAD; 2434 ENCODE_HEAD;
@@ -2466,9 +2439,10 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
2466 WRITECINFO(rename->rn_tinfo); 2439 WRITECINFO(rename->rn_tinfo);
2467 ADJUST_ARGS(); 2440 ADJUST_ARGS();
2468 } 2441 }
2442 return nfserr;
2469} 2443}
2470 2444
2471static void 2445static __be32
2472nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, 2446nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
2473 struct nfsd4_secinfo *secinfo) 2447 struct nfsd4_secinfo *secinfo)
2474{ 2448{
@@ -2532,13 +2506,14 @@ nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
2532out: 2506out:
2533 if (exp) 2507 if (exp)
2534 exp_put(exp); 2508 exp_put(exp);
2509 return nfserr;
2535} 2510}
2536 2511
2537/* 2512/*
2538 * The SETATTR encode routine is special -- it always encodes a bitmap, 2513 * The SETATTR encode routine is special -- it always encodes a bitmap,
2539 * regardless of the error status. 2514 * regardless of the error status.
2540 */ 2515 */
2541static void 2516static __be32
2542nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) 2517nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
2543{ 2518{
2544 ENCODE_HEAD; 2519 ENCODE_HEAD;
@@ -2555,9 +2530,10 @@ nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
2555 WRITE32(setattr->sa_bmval[1]); 2530 WRITE32(setattr->sa_bmval[1]);
2556 } 2531 }
2557 ADJUST_ARGS(); 2532 ADJUST_ARGS();
2533 return nfserr;
2558} 2534}
2559 2535
2560static void 2536static __be32
2561nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) 2537nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
2562{ 2538{
2563 ENCODE_HEAD; 2539 ENCODE_HEAD;
@@ -2574,9 +2550,10 @@ nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct n
2574 WRITE32(0); 2550 WRITE32(0);
2575 ADJUST_ARGS(); 2551 ADJUST_ARGS();
2576 } 2552 }
2553 return nfserr;
2577} 2554}
2578 2555
2579static void 2556static __be32
2580nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) 2557nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
2581{ 2558{
2582 ENCODE_HEAD; 2559 ENCODE_HEAD;
@@ -2588,8 +2565,56 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w
2588 WRITEMEM(write->wr_verifier.data, 8); 2565 WRITEMEM(write->wr_verifier.data, 8);
2589 ADJUST_ARGS(); 2566 ADJUST_ARGS();
2590 } 2567 }
2568 return nfserr;
2591} 2569}
2592 2570
2571static __be32
2572nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
2573{
2574 return nfserr;
2575}
2576
2577typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
2578
2579static nfsd4_enc nfsd4_enc_ops[] = {
2580 [OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access,
2581 [OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close,
2582 [OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit,
2583 [OP_CREATE] = (nfsd4_enc)nfsd4_encode_create,
2584 [OP_DELEGPURGE] = (nfsd4_enc)nfsd4_encode_noop,
2585 [OP_DELEGRETURN] = (nfsd4_enc)nfsd4_encode_noop,
2586 [OP_GETATTR] = (nfsd4_enc)nfsd4_encode_getattr,
2587 [OP_GETFH] = (nfsd4_enc)nfsd4_encode_getfh,
2588 [OP_LINK] = (nfsd4_enc)nfsd4_encode_link,
2589 [OP_LOCK] = (nfsd4_enc)nfsd4_encode_lock,
2590 [OP_LOCKT] = (nfsd4_enc)nfsd4_encode_lockt,
2591 [OP_LOCKU] = (nfsd4_enc)nfsd4_encode_locku,
2592 [OP_LOOKUP] = (nfsd4_enc)nfsd4_encode_noop,
2593 [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop,
2594 [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop,
2595 [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open,
2596 [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm,
2597 [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade,
2598 [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop,
2599 [OP_PUTPUBFH] = (nfsd4_enc)nfsd4_encode_noop,
2600 [OP_PUTROOTFH] = (nfsd4_enc)nfsd4_encode_noop,
2601 [OP_READ] = (nfsd4_enc)nfsd4_encode_read,
2602 [OP_READDIR] = (nfsd4_enc)nfsd4_encode_readdir,
2603 [OP_READLINK] = (nfsd4_enc)nfsd4_encode_readlink,
2604 [OP_REMOVE] = (nfsd4_enc)nfsd4_encode_remove,
2605 [OP_RENAME] = (nfsd4_enc)nfsd4_encode_rename,
2606 [OP_RENEW] = (nfsd4_enc)nfsd4_encode_noop,
2607 [OP_RESTOREFH] = (nfsd4_enc)nfsd4_encode_noop,
2608 [OP_SAVEFH] = (nfsd4_enc)nfsd4_encode_noop,
2609 [OP_SECINFO] = (nfsd4_enc)nfsd4_encode_secinfo,
2610 [OP_SETATTR] = (nfsd4_enc)nfsd4_encode_setattr,
2611 [OP_SETCLIENTID] = (nfsd4_enc)nfsd4_encode_setclientid,
2612 [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
2613 [OP_VERIFY] = (nfsd4_enc)nfsd4_encode_noop,
2614 [OP_WRITE] = (nfsd4_enc)nfsd4_encode_write,
2615 [OP_RELEASE_LOCKOWNER] = (nfsd4_enc)nfsd4_encode_noop,
2616};
2617
2593void 2618void
2594nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) 2619nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
2595{ 2620{
@@ -2601,101 +2626,12 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
2601 statp = p++; /* to be backfilled at the end */ 2626 statp = p++; /* to be backfilled at the end */
2602 ADJUST_ARGS(); 2627 ADJUST_ARGS();
2603 2628
2604 switch (op->opnum) { 2629 if (op->opnum == OP_ILLEGAL)
2605 case OP_ACCESS: 2630 goto status;
2606 nfsd4_encode_access(resp, op->status, &op->u.access); 2631 BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
2607 break; 2632 !nfsd4_enc_ops[op->opnum]);
2608 case OP_CLOSE: 2633 op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
2609 nfsd4_encode_close(resp, op->status, &op->u.close); 2634status:
2610 break;
2611 case OP_COMMIT:
2612 nfsd4_encode_commit(resp, op->status, &op->u.commit);
2613 break;
2614 case OP_CREATE:
2615 nfsd4_encode_create(resp, op->status, &op->u.create);
2616 break;
2617 case OP_DELEGRETURN:
2618 break;
2619 case OP_GETATTR:
2620 op->status = nfsd4_encode_getattr(resp, op->status, &op->u.getattr);
2621 break;
2622 case OP_GETFH:
2623 nfsd4_encode_getfh(resp, op->status, op->u.getfh);
2624 break;
2625 case OP_LINK:
2626 nfsd4_encode_link(resp, op->status, &op->u.link);
2627 break;
2628 case OP_LOCK:
2629 nfsd4_encode_lock(resp, op->status, &op->u.lock);
2630 break;
2631 case OP_LOCKT:
2632 nfsd4_encode_lockt(resp, op->status, &op->u.lockt);
2633 break;
2634 case OP_LOCKU:
2635 nfsd4_encode_locku(resp, op->status, &op->u.locku);
2636 break;
2637 case OP_LOOKUP:
2638 break;
2639 case OP_LOOKUPP:
2640 break;
2641 case OP_NVERIFY:
2642 break;
2643 case OP_OPEN:
2644 nfsd4_encode_open(resp, op->status, &op->u.open);
2645 break;
2646 case OP_OPEN_CONFIRM:
2647 nfsd4_encode_open_confirm(resp, op->status, &op->u.open_confirm);
2648 break;
2649 case OP_OPEN_DOWNGRADE:
2650 nfsd4_encode_open_downgrade(resp, op->status, &op->u.open_downgrade);
2651 break;
2652 case OP_PUTFH:
2653 break;
2654 case OP_PUTROOTFH:
2655 break;
2656 case OP_READ:
2657 op->status = nfsd4_encode_read(resp, op->status, &op->u.read);
2658 break;
2659 case OP_READDIR:
2660 op->status = nfsd4_encode_readdir(resp, op->status, &op->u.readdir);
2661 break;
2662 case OP_READLINK:
2663 op->status = nfsd4_encode_readlink(resp, op->status, &op->u.readlink);
2664 break;
2665 case OP_REMOVE:
2666 nfsd4_encode_remove(resp, op->status, &op->u.remove);
2667 break;
2668 case OP_RENAME:
2669 nfsd4_encode_rename(resp, op->status, &op->u.rename);
2670 break;
2671 case OP_RENEW:
2672 break;
2673 case OP_RESTOREFH:
2674 break;
2675 case OP_SAVEFH:
2676 break;
2677 case OP_SECINFO:
2678 nfsd4_encode_secinfo(resp, op->status, &op->u.secinfo);
2679 break;
2680 case OP_SETATTR:
2681 nfsd4_encode_setattr(resp, op->status, &op->u.setattr);
2682 break;
2683 case OP_SETCLIENTID:
2684 nfsd4_encode_setclientid(resp, op->status, &op->u.setclientid);
2685 break;
2686 case OP_SETCLIENTID_CONFIRM:
2687 break;
2688 case OP_VERIFY:
2689 break;
2690 case OP_WRITE:
2691 nfsd4_encode_write(resp, op->status, &op->u.write);
2692 break;
2693 case OP_RELEASE_LOCKOWNER:
2694 break;
2695 default:
2696 break;
2697 }
2698
2699 /* 2635 /*
2700 * Note: We write the status directly, instead of using WRITE32(), 2636 * Note: We write the status directly, instead of using WRITE32(),
2701 * since it is already in network byte order. 2637 * since it is already in network byte order.