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 c513bbdf2d3..14ba4d9b285 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. |
