diff options
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 392 |
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 | ||
988 | static __be32 | 988 | static __be32 |
989 | nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p) | ||
990 | { | ||
991 | return nfs_ok; | ||
992 | } | ||
993 | |||
994 | static __be32 | ||
995 | nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p) | ||
996 | { | ||
997 | return nfserr_opnotsupp; | ||
998 | } | ||
999 | |||
1000 | typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *); | ||
1001 | |||
1002 | static 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 | |||
1042 | struct nfsd4_minorversion_ops { | ||
1043 | nfsd4_dec *decoders; | ||
1044 | int nops; | ||
1045 | }; | ||
1046 | |||
1047 | static struct nfsd4_minorversion_ops nfsd4_minorversion[] = { | ||
1048 | [0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) }, | ||
1049 | }; | ||
1050 | |||
1051 | static __be32 | ||
989 | nfsd4_decode_compound(struct nfsd4_compoundargs *argp) | 1052 | nfsd4_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 | ||
1994 | static void | 1953 | static __be32 |
1995 | nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access) | 1954 | nfsd4_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 | ||
2007 | static void | 1967 | static __be32 |
2008 | nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close) | 1968 | nfsd4_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 | ||
2022 | static void | 1983 | static __be32 |
2023 | nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit) | 1984 | nfsd4_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 | ||
2034 | static void | 1996 | static __be32 |
2035 | nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create) | 1997 | nfsd4_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 | ||
2049 | static __be32 | 2012 | static __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 | ||
2067 | static void | 2030 | static __be32 |
2068 | nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh *fhp) | 2031 | nfsd4_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 | ||
2107 | static void | 2072 | static __be32 |
2108 | nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock) | 2073 | nfsd4_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 | ||
2123 | static void | 2089 | static __be32 |
2124 | nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt) | 2090 | nfsd4_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 | ||
2130 | static void | 2097 | static __be32 |
2131 | nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku) | 2098 | nfsd4_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 | ||
2146 | static void | 2114 | static __be32 |
2147 | nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link) | 2115 | nfsd4_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 | ||
2159 | static void | 2128 | static __be32 |
2160 | nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open) | 2129 | nfsd4_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 */ |
2220 | out: | 2189 | out: |
2221 | ENCODE_SEQID_OP_TAIL(open->op_stateowner); | 2190 | ENCODE_SEQID_OP_TAIL(open->op_stateowner); |
2191 | return nfserr; | ||
2222 | } | 2192 | } |
2223 | 2193 | ||
2224 | static void | 2194 | static __be32 |
2225 | nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc) | 2195 | nfsd4_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 | ||
2239 | static void | 2210 | static __be32 |
2240 | nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od) | 2211 | nfsd4_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 | ||
2254 | static __be32 | 2226 | static __be32 |
@@ -2443,7 +2415,7 @@ err_no_verf: | |||
2443 | return nfserr; | 2415 | return nfserr; |
2444 | } | 2416 | } |
2445 | 2417 | ||
2446 | static void | 2418 | static __be32 |
2447 | nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove) | 2419 | nfsd4_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 | ||
2458 | static void | 2431 | static __be32 |
2459 | nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename) | 2432 | nfsd4_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 | ||
2471 | static void | 2445 | static __be32 |
2472 | nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, | 2446 | nfsd4_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, | |||
2532 | out: | 2506 | out: |
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 | */ |
2541 | static void | 2516 | static __be32 |
2542 | nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr) | 2517 | nfsd4_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 | ||
2560 | static void | 2536 | static __be32 |
2561 | nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd) | 2537 | nfsd4_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 | ||
2579 | static void | 2556 | static __be32 |
2580 | nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write) | 2557 | nfsd4_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 | ||
2571 | static __be32 | ||
2572 | nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p) | ||
2573 | { | ||
2574 | return nfserr; | ||
2575 | } | ||
2576 | |||
2577 | typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *); | ||
2578 | |||
2579 | static 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 | |||
2593 | void | 2618 | void |
2594 | nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) | 2619 | nfsd4_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); | 2634 | status: |
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. |