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), |
