diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 107 |
1 files changed, 85 insertions, 22 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 65c8dae4b267..08ef91291132 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -202,14 +202,17 @@ static int nfs4_stat_to_errno(int); | |||
202 | #define encode_link_maxsz (op_encode_hdr_maxsz + \ | 202 | #define encode_link_maxsz (op_encode_hdr_maxsz + \ |
203 | nfs4_name_maxsz) | 203 | nfs4_name_maxsz) |
204 | #define decode_link_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz) | 204 | #define decode_link_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz) |
205 | #define encode_lockowner_maxsz (7) | ||
205 | #define encode_lock_maxsz (op_encode_hdr_maxsz + \ | 206 | #define encode_lock_maxsz (op_encode_hdr_maxsz + \ |
206 | 7 + \ | 207 | 7 + \ |
207 | 1 + encode_stateid_maxsz + 8) | 208 | 1 + encode_stateid_maxsz + 1 + \ |
209 | encode_lockowner_maxsz) | ||
208 | #define decode_lock_denied_maxsz \ | 210 | #define decode_lock_denied_maxsz \ |
209 | (8 + decode_lockowner_maxsz) | 211 | (8 + decode_lockowner_maxsz) |
210 | #define decode_lock_maxsz (op_decode_hdr_maxsz + \ | 212 | #define decode_lock_maxsz (op_decode_hdr_maxsz + \ |
211 | decode_lock_denied_maxsz) | 213 | decode_lock_denied_maxsz) |
212 | #define encode_lockt_maxsz (op_encode_hdr_maxsz + 12) | 214 | #define encode_lockt_maxsz (op_encode_hdr_maxsz + 5 + \ |
215 | encode_lockowner_maxsz) | ||
213 | #define decode_lockt_maxsz (op_decode_hdr_maxsz + \ | 216 | #define decode_lockt_maxsz (op_decode_hdr_maxsz + \ |
214 | decode_lock_denied_maxsz) | 217 | decode_lock_denied_maxsz) |
215 | #define encode_locku_maxsz (op_encode_hdr_maxsz + 3 + \ | 218 | #define encode_locku_maxsz (op_encode_hdr_maxsz + 3 + \ |
@@ -217,6 +220,11 @@ static int nfs4_stat_to_errno(int); | |||
217 | 4) | 220 | 4) |
218 | #define decode_locku_maxsz (op_decode_hdr_maxsz + \ | 221 | #define decode_locku_maxsz (op_decode_hdr_maxsz + \ |
219 | decode_stateid_maxsz) | 222 | decode_stateid_maxsz) |
223 | #define encode_release_lockowner_maxsz \ | ||
224 | (op_encode_hdr_maxsz + \ | ||
225 | encode_lockowner_maxsz) | ||
226 | #define decode_release_lockowner_maxsz \ | ||
227 | (op_decode_hdr_maxsz) | ||
220 | #define encode_access_maxsz (op_encode_hdr_maxsz + 1) | 228 | #define encode_access_maxsz (op_encode_hdr_maxsz + 1) |
221 | #define decode_access_maxsz (op_decode_hdr_maxsz + 2) | 229 | #define decode_access_maxsz (op_decode_hdr_maxsz + 2) |
222 | #define encode_symlink_maxsz (op_encode_hdr_maxsz + \ | 230 | #define encode_symlink_maxsz (op_encode_hdr_maxsz + \ |
@@ -471,6 +479,12 @@ static int nfs4_stat_to_errno(int); | |||
471 | decode_sequence_maxsz + \ | 479 | decode_sequence_maxsz + \ |
472 | decode_putfh_maxsz + \ | 480 | decode_putfh_maxsz + \ |
473 | decode_locku_maxsz) | 481 | decode_locku_maxsz) |
482 | #define NFS4_enc_release_lockowner_sz \ | ||
483 | (compound_encode_hdr_maxsz + \ | ||
484 | encode_lockowner_maxsz) | ||
485 | #define NFS4_dec_release_lockowner_sz \ | ||
486 | (compound_decode_hdr_maxsz + \ | ||
487 | decode_lockowner_maxsz) | ||
474 | #define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ | 488 | #define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ |
475 | encode_sequence_maxsz + \ | 489 | encode_sequence_maxsz + \ |
476 | encode_putfh_maxsz + \ | 490 | encode_putfh_maxsz + \ |
@@ -744,7 +758,7 @@ static void encode_compound_hdr(struct xdr_stream *xdr, | |||
744 | struct compound_hdr *hdr) | 758 | struct compound_hdr *hdr) |
745 | { | 759 | { |
746 | __be32 *p; | 760 | __be32 *p; |
747 | struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth; | 761 | struct rpc_auth *auth = req->rq_cred->cr_auth; |
748 | 762 | ||
749 | /* initialize running count of expected bytes in reply. | 763 | /* initialize running count of expected bytes in reply. |
750 | * NOTE: the replied tag SHOULD be the same is the one sent, | 764 | * NOTE: the replied tag SHOULD be the same is the one sent, |
@@ -1042,6 +1056,17 @@ static inline uint64_t nfs4_lock_length(struct file_lock *fl) | |||
1042 | return fl->fl_end - fl->fl_start + 1; | 1056 | return fl->fl_end - fl->fl_start + 1; |
1043 | } | 1057 | } |
1044 | 1058 | ||
1059 | static void encode_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner) | ||
1060 | { | ||
1061 | __be32 *p; | ||
1062 | |||
1063 | p = reserve_space(xdr, 28); | ||
1064 | p = xdr_encode_hyper(p, lowner->clientid); | ||
1065 | *p++ = cpu_to_be32(16); | ||
1066 | p = xdr_encode_opaque_fixed(p, "lock id:", 8); | ||
1067 | xdr_encode_hyper(p, lowner->id); | ||
1068 | } | ||
1069 | |||
1045 | /* | 1070 | /* |
1046 | * opcode,type,reclaim,offset,length,new_lock_owner = 32 | 1071 | * opcode,type,reclaim,offset,length,new_lock_owner = 32 |
1047 | * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 | 1072 | * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 |
@@ -1058,14 +1083,11 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args | |||
1058 | p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); | 1083 | p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); |
1059 | *p = cpu_to_be32(args->new_lock_owner); | 1084 | *p = cpu_to_be32(args->new_lock_owner); |
1060 | if (args->new_lock_owner){ | 1085 | if (args->new_lock_owner){ |
1061 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+32); | 1086 | p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4); |
1062 | *p++ = cpu_to_be32(args->open_seqid->sequence->counter); | 1087 | *p++ = cpu_to_be32(args->open_seqid->sequence->counter); |
1063 | p = xdr_encode_opaque_fixed(p, args->open_stateid->data, NFS4_STATEID_SIZE); | 1088 | p = xdr_encode_opaque_fixed(p, args->open_stateid->data, NFS4_STATEID_SIZE); |
1064 | *p++ = cpu_to_be32(args->lock_seqid->sequence->counter); | 1089 | *p++ = cpu_to_be32(args->lock_seqid->sequence->counter); |
1065 | p = xdr_encode_hyper(p, args->lock_owner.clientid); | 1090 | encode_lockowner(xdr, &args->lock_owner); |
1066 | *p++ = cpu_to_be32(16); | ||
1067 | p = xdr_encode_opaque_fixed(p, "lock id:", 8); | ||
1068 | xdr_encode_hyper(p, args->lock_owner.id); | ||
1069 | } | 1091 | } |
1070 | else { | 1092 | else { |
1071 | p = reserve_space(xdr, NFS4_STATEID_SIZE+4); | 1093 | p = reserve_space(xdr, NFS4_STATEID_SIZE+4); |
@@ -1080,15 +1102,12 @@ static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *ar | |||
1080 | { | 1102 | { |
1081 | __be32 *p; | 1103 | __be32 *p; |
1082 | 1104 | ||
1083 | p = reserve_space(xdr, 52); | 1105 | p = reserve_space(xdr, 24); |
1084 | *p++ = cpu_to_be32(OP_LOCKT); | 1106 | *p++ = cpu_to_be32(OP_LOCKT); |
1085 | *p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0)); | 1107 | *p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0)); |
1086 | p = xdr_encode_hyper(p, args->fl->fl_start); | 1108 | p = xdr_encode_hyper(p, args->fl->fl_start); |
1087 | p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); | 1109 | p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); |
1088 | p = xdr_encode_hyper(p, args->lock_owner.clientid); | 1110 | encode_lockowner(xdr, &args->lock_owner); |
1089 | *p++ = cpu_to_be32(16); | ||
1090 | p = xdr_encode_opaque_fixed(p, "lock id:", 8); | ||
1091 | xdr_encode_hyper(p, args->lock_owner.id); | ||
1092 | hdr->nops++; | 1111 | hdr->nops++; |
1093 | hdr->replen += decode_lockt_maxsz; | 1112 | hdr->replen += decode_lockt_maxsz; |
1094 | } | 1113 | } |
@@ -1108,6 +1127,17 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar | |||
1108 | hdr->replen += decode_locku_maxsz; | 1127 | hdr->replen += decode_locku_maxsz; |
1109 | } | 1128 | } |
1110 | 1129 | ||
1130 | static void encode_release_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner, struct compound_hdr *hdr) | ||
1131 | { | ||
1132 | __be32 *p; | ||
1133 | |||
1134 | p = reserve_space(xdr, 4); | ||
1135 | *p = cpu_to_be32(OP_RELEASE_LOCKOWNER); | ||
1136 | encode_lockowner(xdr, lowner); | ||
1137 | hdr->nops++; | ||
1138 | hdr->replen += decode_release_lockowner_maxsz; | ||
1139 | } | ||
1140 | |||
1111 | static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) | 1141 | static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) |
1112 | { | 1142 | { |
1113 | int len = name->len; | 1143 | int len = name->len; |
@@ -1172,7 +1202,7 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op | |||
1172 | break; | 1202 | break; |
1173 | default: | 1203 | default: |
1174 | clp = arg->server->nfs_client; | 1204 | clp = arg->server->nfs_client; |
1175 | if (clp->cl_minorversion > 0) { | 1205 | if (clp->cl_mvops->minor_version > 0) { |
1176 | if (nfs4_has_persistent_session(clp)) { | 1206 | if (nfs4_has_persistent_session(clp)) { |
1177 | *p = cpu_to_be32(NFS4_CREATE_GUARDED); | 1207 | *p = cpu_to_be32(NFS4_CREATE_GUARDED); |
1178 | encode_attrs(xdr, arg->u.attrs, arg->server); | 1208 | encode_attrs(xdr, arg->u.attrs, arg->server); |
@@ -1324,14 +1354,14 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr) | |||
1324 | hdr->replen += decode_putrootfh_maxsz; | 1354 | hdr->replen += decode_putrootfh_maxsz; |
1325 | } | 1355 | } |
1326 | 1356 | ||
1327 | static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx) | 1357 | static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx) |
1328 | { | 1358 | { |
1329 | nfs4_stateid stateid; | 1359 | nfs4_stateid stateid; |
1330 | __be32 *p; | 1360 | __be32 *p; |
1331 | 1361 | ||
1332 | p = reserve_space(xdr, NFS4_STATEID_SIZE); | 1362 | p = reserve_space(xdr, NFS4_STATEID_SIZE); |
1333 | if (ctx->state != NULL) { | 1363 | if (ctx->state != NULL) { |
1334 | nfs4_copy_stateid(&stateid, ctx->state, ctx->lockowner); | 1364 | nfs4_copy_stateid(&stateid, ctx->state, l_ctx->lockowner, l_ctx->pid); |
1335 | xdr_encode_opaque_fixed(p, stateid.data, NFS4_STATEID_SIZE); | 1365 | xdr_encode_opaque_fixed(p, stateid.data, NFS4_STATEID_SIZE); |
1336 | } else | 1366 | } else |
1337 | xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE); | 1367 | xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE); |
@@ -1344,7 +1374,7 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, | |||
1344 | p = reserve_space(xdr, 4); | 1374 | p = reserve_space(xdr, 4); |
1345 | *p = cpu_to_be32(OP_READ); | 1375 | *p = cpu_to_be32(OP_READ); |
1346 | 1376 | ||
1347 | encode_stateid(xdr, args->context); | 1377 | encode_stateid(xdr, args->context, args->lock_context); |
1348 | 1378 | ||
1349 | p = reserve_space(xdr, 12); | 1379 | p = reserve_space(xdr, 12); |
1350 | p = xdr_encode_hyper(p, args->offset); | 1380 | p = xdr_encode_hyper(p, args->offset); |
@@ -1523,7 +1553,7 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg | |||
1523 | p = reserve_space(xdr, 4); | 1553 | p = reserve_space(xdr, 4); |
1524 | *p = cpu_to_be32(OP_WRITE); | 1554 | *p = cpu_to_be32(OP_WRITE); |
1525 | 1555 | ||
1526 | encode_stateid(xdr, args->context); | 1556 | encode_stateid(xdr, args->context, args->lock_context); |
1527 | 1557 | ||
1528 | p = reserve_space(xdr, 16); | 1558 | p = reserve_space(xdr, 16); |
1529 | p = xdr_encode_hyper(p, args->offset); | 1559 | p = xdr_encode_hyper(p, args->offset); |
@@ -1704,7 +1734,7 @@ static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args) | |||
1704 | { | 1734 | { |
1705 | #if defined(CONFIG_NFS_V4_1) | 1735 | #if defined(CONFIG_NFS_V4_1) |
1706 | if (args->sa_session) | 1736 | if (args->sa_session) |
1707 | return args->sa_session->clp->cl_minorversion; | 1737 | return args->sa_session->clp->cl_mvops->minor_version; |
1708 | #endif /* CONFIG_NFS_V4_1 */ | 1738 | #endif /* CONFIG_NFS_V4_1 */ |
1709 | return 0; | 1739 | return 0; |
1710 | } | 1740 | } |
@@ -2048,6 +2078,20 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_ | |||
2048 | return 0; | 2078 | return 0; |
2049 | } | 2079 | } |
2050 | 2080 | ||
2081 | static int nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req, __be32 *p, struct nfs_release_lockowner_args *args) | ||
2082 | { | ||
2083 | struct xdr_stream xdr; | ||
2084 | struct compound_hdr hdr = { | ||
2085 | .minorversion = 0, | ||
2086 | }; | ||
2087 | |||
2088 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | ||
2089 | encode_compound_hdr(&xdr, req, &hdr); | ||
2090 | encode_release_lockowner(&xdr, &args->lock_owner, &hdr); | ||
2091 | encode_nops(&hdr); | ||
2092 | return 0; | ||
2093 | } | ||
2094 | |||
2051 | /* | 2095 | /* |
2052 | * Encode a READLINK request | 2096 | * Encode a READLINK request |
2053 | */ | 2097 | */ |
@@ -2395,7 +2439,7 @@ static int nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, uint32_t *p, | |||
2395 | { | 2439 | { |
2396 | struct xdr_stream xdr; | 2440 | struct xdr_stream xdr; |
2397 | struct compound_hdr hdr = { | 2441 | struct compound_hdr hdr = { |
2398 | .minorversion = args->client->cl_minorversion, | 2442 | .minorversion = args->client->cl_mvops->minor_version, |
2399 | }; | 2443 | }; |
2400 | 2444 | ||
2401 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 2445 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
@@ -2413,7 +2457,7 @@ static int nfs4_xdr_enc_create_session(struct rpc_rqst *req, uint32_t *p, | |||
2413 | { | 2457 | { |
2414 | struct xdr_stream xdr; | 2458 | struct xdr_stream xdr; |
2415 | struct compound_hdr hdr = { | 2459 | struct compound_hdr hdr = { |
2416 | .minorversion = args->client->cl_minorversion, | 2460 | .minorversion = args->client->cl_mvops->minor_version, |
2417 | }; | 2461 | }; |
2418 | 2462 | ||
2419 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 2463 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
@@ -2431,7 +2475,7 @@ static int nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, uint32_t *p, | |||
2431 | { | 2475 | { |
2432 | struct xdr_stream xdr; | 2476 | struct xdr_stream xdr; |
2433 | struct compound_hdr hdr = { | 2477 | struct compound_hdr hdr = { |
2434 | .minorversion = session->clp->cl_minorversion, | 2478 | .minorversion = session->clp->cl_mvops->minor_version, |
2435 | }; | 2479 | }; |
2436 | 2480 | ||
2437 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 2481 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); |
@@ -3973,6 +4017,11 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res) | |||
3973 | return status; | 4017 | return status; |
3974 | } | 4018 | } |
3975 | 4019 | ||
4020 | static int decode_release_lockowner(struct xdr_stream *xdr) | ||
4021 | { | ||
4022 | return decode_op_hdr(xdr, OP_RELEASE_LOCKOWNER); | ||
4023 | } | ||
4024 | |||
3976 | static int decode_lookup(struct xdr_stream *xdr) | 4025 | static int decode_lookup(struct xdr_stream *xdr) |
3977 | { | 4026 | { |
3978 | return decode_op_hdr(xdr, OP_LOOKUP); | 4027 | return decode_op_hdr(xdr, OP_LOOKUP); |
@@ -5259,6 +5308,19 @@ out: | |||
5259 | return status; | 5308 | return status; |
5260 | } | 5309 | } |
5261 | 5310 | ||
5311 | static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp, __be32 *p, void *dummy) | ||
5312 | { | ||
5313 | struct xdr_stream xdr; | ||
5314 | struct compound_hdr hdr; | ||
5315 | int status; | ||
5316 | |||
5317 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | ||
5318 | status = decode_compound_hdr(&xdr, &hdr); | ||
5319 | if (!status) | ||
5320 | status = decode_release_lockowner(&xdr); | ||
5321 | return status; | ||
5322 | } | ||
5323 | |||
5262 | /* | 5324 | /* |
5263 | * Decode READLINK response | 5325 | * Decode READLINK response |
5264 | */ | 5326 | */ |
@@ -5866,6 +5928,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
5866 | PROC(GETACL, enc_getacl, dec_getacl), | 5928 | PROC(GETACL, enc_getacl, dec_getacl), |
5867 | PROC(SETACL, enc_setacl, dec_setacl), | 5929 | PROC(SETACL, enc_setacl, dec_setacl), |
5868 | PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), | 5930 | PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), |
5931 | PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner), | ||
5869 | #if defined(CONFIG_NFS_V4_1) | 5932 | #if defined(CONFIG_NFS_V4_1) |
5870 | PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), | 5933 | PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), |
5871 | PROC(CREATE_SESSION, enc_create_session, dec_create_session), | 5934 | PROC(CREATE_SESSION, enc_create_session, dec_create_session), |