diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 85ee1d17a461..7a243a2cf0be 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -246,6 +246,8 @@ static int nfs4_stat_to_errno(int); | |||
246 | (0) | 246 | (0) |
247 | 247 | ||
248 | #if defined(CONFIG_NFS_V4_1) | 248 | #if defined(CONFIG_NFS_V4_1) |
249 | #define NFS4_MAX_MACHINE_NAME_LEN (64) | ||
250 | |||
249 | #define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \ | 251 | #define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \ |
250 | encode_verifier_maxsz + \ | 252 | encode_verifier_maxsz + \ |
251 | 1 /* co_ownerid.len */ + \ | 253 | 1 /* co_ownerid.len */ + \ |
@@ -267,6 +269,31 @@ static int nfs4_stat_to_errno(int); | |||
267 | XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \ | 269 | XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \ |
268 | 1 /* eir_server_impl_id array length */ + \ | 270 | 1 /* eir_server_impl_id array length */ + \ |
269 | 0 /* ignored eir_server_impl_id contents */) | 271 | 0 /* ignored eir_server_impl_id contents */) |
272 | #define encode_channel_attrs_maxsz (6 + 1 /* ca_rdma_ird.len (0) */) | ||
273 | #define decode_channel_attrs_maxsz (6 + \ | ||
274 | 1 /* ca_rdma_ird.len */ + \ | ||
275 | 1 /* ca_rdma_ird */) | ||
276 | #define encode_create_session_maxsz (op_encode_hdr_maxsz + \ | ||
277 | 2 /* csa_clientid */ + \ | ||
278 | 1 /* csa_sequence */ + \ | ||
279 | 1 /* csa_flags */ + \ | ||
280 | encode_channel_attrs_maxsz + \ | ||
281 | encode_channel_attrs_maxsz + \ | ||
282 | 1 /* csa_cb_program */ + \ | ||
283 | 1 /* csa_sec_parms.len (1) */ + \ | ||
284 | 1 /* cb_secflavor (AUTH_SYS) */ + \ | ||
285 | 1 /* stamp */ + \ | ||
286 | 1 /* machinename.len */ + \ | ||
287 | XDR_QUADLEN(NFS4_MAX_MACHINE_NAME_LEN) + \ | ||
288 | 1 /* uid */ + \ | ||
289 | 1 /* gid */ + \ | ||
290 | 1 /* gids.len (0) */) | ||
291 | #define decode_create_session_maxsz (op_decode_hdr_maxsz + \ | ||
292 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \ | ||
293 | 1 /* csr_sequence */ + \ | ||
294 | 1 /* csr_flags */ + \ | ||
295 | decode_channel_attrs_maxsz + \ | ||
296 | decode_channel_attrs_maxsz) | ||
270 | #define encode_sequence_maxsz 0 /* stub */ | 297 | #define encode_sequence_maxsz 0 /* stub */ |
271 | #define decode_sequence_maxsz 0 /* stub */ | 298 | #define decode_sequence_maxsz 0 /* stub */ |
272 | #else /* CONFIG_NFS_V4_1 */ | 299 | #else /* CONFIG_NFS_V4_1 */ |
@@ -622,6 +649,12 @@ static int nfs4_stat_to_errno(int); | |||
622 | #define NFS4_dec_exchange_id_sz \ | 649 | #define NFS4_dec_exchange_id_sz \ |
623 | (compound_decode_hdr_maxsz + \ | 650 | (compound_decode_hdr_maxsz + \ |
624 | decode_exchange_id_maxsz) | 651 | decode_exchange_id_maxsz) |
652 | #define NFS4_enc_create_session_sz \ | ||
653 | (compound_encode_hdr_maxsz + \ | ||
654 | encode_create_session_maxsz) | ||
655 | #define NFS4_dec_create_session_sz \ | ||
656 | (compound_decode_hdr_maxsz + \ | ||
657 | decode_create_session_maxsz) | ||
625 | #define NFS4_enc_get_lease_time_sz (compound_encode_hdr_maxsz + \ | 658 | #define NFS4_enc_get_lease_time_sz (compound_encode_hdr_maxsz + \ |
626 | encode_sequence_maxsz + \ | 659 | encode_sequence_maxsz + \ |
627 | encode_putrootfh_maxsz + \ | 660 | encode_putrootfh_maxsz + \ |
@@ -712,6 +745,7 @@ static void encode_compound_hdr(struct xdr_stream *xdr, | |||
712 | 745 | ||
713 | static void encode_nops(struct compound_hdr *hdr) | 746 | static void encode_nops(struct compound_hdr *hdr) |
714 | { | 747 | { |
748 | BUG_ON(hdr->nops > NFS4_MAX_OPS); | ||
715 | *hdr->nops_p = htonl(hdr->nops); | 749 | *hdr->nops_p = htonl(hdr->nops); |
716 | } | 750 | } |
717 | 751 | ||
@@ -1513,6 +1547,68 @@ static void encode_exchange_id(struct xdr_stream *xdr, | |||
1513 | hdr->nops++; | 1547 | hdr->nops++; |
1514 | hdr->replen += decode_exchange_id_maxsz; | 1548 | hdr->replen += decode_exchange_id_maxsz; |
1515 | } | 1549 | } |
1550 | |||
1551 | static void encode_create_session(struct xdr_stream *xdr, | ||
1552 | struct nfs41_create_session_args *args, | ||
1553 | struct compound_hdr *hdr) | ||
1554 | { | ||
1555 | __be32 *p; | ||
1556 | char machine_name[NFS4_MAX_MACHINE_NAME_LEN]; | ||
1557 | uint32_t len; | ||
1558 | struct nfs_client *clp = args->client; | ||
1559 | |||
1560 | RESERVE_SPACE(4); | ||
1561 | WRITE32(OP_CREATE_SESSION); | ||
1562 | |||
1563 | RESERVE_SPACE(8); | ||
1564 | WRITE64(clp->cl_ex_clid); | ||
1565 | |||
1566 | RESERVE_SPACE(8); | ||
1567 | WRITE32(clp->cl_seqid); /*Sequence id */ | ||
1568 | WRITE32(args->flags); /*flags */ | ||
1569 | |||
1570 | RESERVE_SPACE(2*28); /* 2 channel_attrs */ | ||
1571 | /* Fore Channel */ | ||
1572 | WRITE32(args->fc_attrs.headerpadsz); /* header padding size */ | ||
1573 | WRITE32(args->fc_attrs.max_rqst_sz); /* max req size */ | ||
1574 | WRITE32(args->fc_attrs.max_resp_sz); /* max resp size */ | ||
1575 | WRITE32(args->fc_attrs.max_resp_sz_cached); /* Max resp sz cached */ | ||
1576 | WRITE32(args->fc_attrs.max_ops); /* max operations */ | ||
1577 | WRITE32(args->fc_attrs.max_reqs); /* max requests */ | ||
1578 | WRITE32(0); /* rdmachannel_attrs */ | ||
1579 | |||
1580 | /* Back Channel */ | ||
1581 | WRITE32(args->fc_attrs.headerpadsz); /* header padding size */ | ||
1582 | WRITE32(args->bc_attrs.max_rqst_sz); /* max req size */ | ||
1583 | WRITE32(args->bc_attrs.max_resp_sz); /* max resp size */ | ||
1584 | WRITE32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */ | ||
1585 | WRITE32(args->bc_attrs.max_ops); /* max operations */ | ||
1586 | WRITE32(args->bc_attrs.max_reqs); /* max requests */ | ||
1587 | WRITE32(0); /* rdmachannel_attrs */ | ||
1588 | |||
1589 | RESERVE_SPACE(4); | ||
1590 | WRITE32(args->cb_program); /* cb_program */ | ||
1591 | |||
1592 | RESERVE_SPACE(4); /* # of security flavors */ | ||
1593 | WRITE32(1); | ||
1594 | |||
1595 | RESERVE_SPACE(4); | ||
1596 | WRITE32(RPC_AUTH_UNIX); /* auth_sys */ | ||
1597 | |||
1598 | /* authsys_parms rfc1831 */ | ||
1599 | RESERVE_SPACE(4); | ||
1600 | WRITE32((u32)clp->cl_boot_time.tv_nsec); /* stamp */ | ||
1601 | len = scnprintf(machine_name, sizeof(machine_name), "%s", | ||
1602 | clp->cl_ipaddr); | ||
1603 | RESERVE_SPACE(16 + len); | ||
1604 | WRITE32(len); | ||
1605 | WRITEMEM(machine_name, len); | ||
1606 | WRITE32(0); /* UID */ | ||
1607 | WRITE32(0); /* GID */ | ||
1608 | WRITE32(0); /* No more gids */ | ||
1609 | hdr->nops++; | ||
1610 | hdr->replen += decode_create_session_maxsz; | ||
1611 | } | ||
1516 | #endif /* CONFIG_NFS_V4_1 */ | 1612 | #endif /* CONFIG_NFS_V4_1 */ |
1517 | 1613 | ||
1518 | static void encode_sequence(struct xdr_stream *xdr, | 1614 | static void encode_sequence(struct xdr_stream *xdr, |
@@ -2241,6 +2337,24 @@ static int nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, uint32_t *p, | |||
2241 | } | 2337 | } |
2242 | 2338 | ||
2243 | /* | 2339 | /* |
2340 | * a CREATE_SESSION request | ||
2341 | */ | ||
2342 | static int nfs4_xdr_enc_create_session(struct rpc_rqst *req, uint32_t *p, | ||
2343 | struct nfs41_create_session_args *args) | ||
2344 | { | ||
2345 | struct xdr_stream xdr; | ||
2346 | struct compound_hdr hdr = { | ||
2347 | .minorversion = args->client->cl_minorversion, | ||
2348 | }; | ||
2349 | |||
2350 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | ||
2351 | encode_compound_hdr(&xdr, req, &hdr); | ||
2352 | encode_create_session(&xdr, args, &hdr); | ||
2353 | encode_nops(&hdr); | ||
2354 | return 0; | ||
2355 | } | ||
2356 | |||
2357 | /* | ||
2244 | * a GET_LEASE_TIME request | 2358 | * a GET_LEASE_TIME request |
2245 | */ | 2359 | */ |
2246 | static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p, | 2360 | static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p, |
@@ -4021,6 +4135,59 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
4021 | 4135 | ||
4022 | return 0; | 4136 | return 0; |
4023 | } | 4137 | } |
4138 | |||
4139 | static int decode_chan_attrs(struct xdr_stream *xdr, | ||
4140 | struct nfs4_channel_attrs *attrs) | ||
4141 | { | ||
4142 | __be32 *p; | ||
4143 | u32 nr_attrs; | ||
4144 | |||
4145 | READ_BUF(28); | ||
4146 | READ32(attrs->headerpadsz); | ||
4147 | READ32(attrs->max_rqst_sz); | ||
4148 | READ32(attrs->max_resp_sz); | ||
4149 | READ32(attrs->max_resp_sz_cached); | ||
4150 | READ32(attrs->max_ops); | ||
4151 | READ32(attrs->max_reqs); | ||
4152 | READ32(nr_attrs); | ||
4153 | if (unlikely(nr_attrs > 1)) { | ||
4154 | printk(KERN_WARNING "%s: Invalid rdma channel attrs count %u\n", | ||
4155 | __func__, nr_attrs); | ||
4156 | return -EINVAL; | ||
4157 | } | ||
4158 | if (nr_attrs == 1) | ||
4159 | READ_BUF(4); /* skip rdma_attrs */ | ||
4160 | return 0; | ||
4161 | } | ||
4162 | |||
4163 | static int decode_create_session(struct xdr_stream *xdr, | ||
4164 | struct nfs41_create_session_res *res) | ||
4165 | { | ||
4166 | __be32 *p; | ||
4167 | int status; | ||
4168 | struct nfs_client *clp = res->client; | ||
4169 | struct nfs4_session *session = clp->cl_session; | ||
4170 | |||
4171 | status = decode_op_hdr(xdr, OP_CREATE_SESSION); | ||
4172 | |||
4173 | if (status) | ||
4174 | return status; | ||
4175 | |||
4176 | /* sessionid */ | ||
4177 | READ_BUF(NFS4_MAX_SESSIONID_LEN); | ||
4178 | COPYMEM(&session->sess_id, NFS4_MAX_SESSIONID_LEN); | ||
4179 | |||
4180 | /* seqid, flags */ | ||
4181 | READ_BUF(8); | ||
4182 | READ32(clp->cl_seqid); | ||
4183 | READ32(session->flags); | ||
4184 | |||
4185 | /* Channel attributes */ | ||
4186 | status = decode_chan_attrs(xdr, &session->fc_attrs); | ||
4187 | if (!status) | ||
4188 | status = decode_chan_attrs(xdr, &session->bc_attrs); | ||
4189 | return status; | ||
4190 | } | ||
4024 | #endif /* CONFIG_NFS_V4_1 */ | 4191 | #endif /* CONFIG_NFS_V4_1 */ |
4025 | 4192 | ||
4026 | static int decode_sequence(struct xdr_stream *xdr, | 4193 | static int decode_sequence(struct xdr_stream *xdr, |
@@ -4939,6 +5106,23 @@ static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p, | |||
4939 | } | 5106 | } |
4940 | 5107 | ||
4941 | /* | 5108 | /* |
5109 | * a CREATE_SESSION request | ||
5110 | */ | ||
5111 | static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, uint32_t *p, | ||
5112 | struct nfs41_create_session_res *res) | ||
5113 | { | ||
5114 | struct xdr_stream xdr; | ||
5115 | struct compound_hdr hdr; | ||
5116 | int status; | ||
5117 | |||
5118 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | ||
5119 | status = decode_compound_hdr(&xdr, &hdr); | ||
5120 | if (!status) | ||
5121 | status = decode_create_session(&xdr, res); | ||
5122 | return status; | ||
5123 | } | ||
5124 | |||
5125 | /* | ||
4942 | * a GET_LEASE_TIME request | 5126 | * a GET_LEASE_TIME request |
4943 | */ | 5127 | */ |
4944 | static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p, | 5128 | static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p, |
@@ -5131,6 +5315,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
5131 | PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), | 5315 | PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), |
5132 | #if defined(CONFIG_NFS_V4_1) | 5316 | #if defined(CONFIG_NFS_V4_1) |
5133 | PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), | 5317 | PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), |
5318 | PROC(CREATE_SESSION, enc_create_session, dec_create_session), | ||
5134 | PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time), | 5319 | PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time), |
5135 | #endif /* CONFIG_NFS_V4_1 */ | 5320 | #endif /* CONFIG_NFS_V4_1 */ |
5136 | }; | 5321 | }; |