int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req, struct svc_rqst *rqstp) { struct rpcrdma_msg *rmsgp = NULL; u32 *va; u32 *vaend; u32 hdr_len; rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; /* Verify that there's enough bytes for header + something */ if (rqstp->rq_arg.len <= RPCRDMA_HDRLEN_MIN) { // dprintk("svcrdma: header too short = %d\n", ; return -EINVAL; } /* Decode the header */ rmsgp->rm_xid = ntohl(rmsgp->rm_xid); rmsgp->rm_vers = ntohl(rmsgp->rm_vers); rmsgp->rm_credit = ntohl(rmsgp->rm_credit); rmsgp->rm_type = ntohl(rmsgp->rm_type); if (rmsgp->rm_vers != RPCRDMA_VERSION) return -ENOSYS; /* Pull in the extra for the padded case and bump our pointer */ if (rmsgp->rm_type == RDMA_MSGP) { int hdrlen; rmsgp->rm_body.rm_padded.rm_align = ntohl(rmsgp->rm_body.rm_padded.rm_align); rmsgp->rm_body.rm_padded.rm_thresh = ntohl(rmsgp->rm_body.rm_padded.rm_thresh); va = &rmsgp->rm_body.rm_padded.rm_pempty[4]; rqstp->rq_arg.head[0].iov_base = va; hdrlen = (u32)((unsigned long)va - (unsigned long)rmsgp); rqstp->rq_arg.head[0].iov_len -= hdrlen; if (hdrlen > rqstp->rq_arg.len) return -EINVAL; return hdrlen; } /* The chunk list may contain either a read chunk list or a write * chunk list and a reply chunk list. */ va = &rmsgp->rm_body.rm_chunks[0]; vaend = (u32 *)((unsigned long)rmsgp + rqstp->rq_arg.len); va = decode_read_list(va, vaend); if (!va) return -EINVAL; va = decode_write_list(va, vaend); if (!va) return -EINVAL; va = decode_reply_array(va, vaend); if (!va) return -EINVAL; rqstp->rq_arg.head[0].iov_base = va; hdr_len = (unsigned long)va - (unsigned long)rmsgp; rqstp->rq_arg.head[0].iov_len -= hdr_len; *rdma_req = rmsgp; return hdr_len; }
int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req, struct svc_rqst *rqstp) { struct rpcrdma_msg *rmsgp = NULL; u32 *va; u32 *vaend; u32 hdr_len; rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; if (rqstp->rq_arg.len <= RPCRDMA_HDRLEN_MIN) { dprintk("svcrdma: header too short = %d\n", rqstp->rq_arg.len); return -EINVAL; } rmsgp->rm_xid = ntohl(rmsgp->rm_xid); rmsgp->rm_vers = ntohl(rmsgp->rm_vers); rmsgp->rm_credit = ntohl(rmsgp->rm_credit); rmsgp->rm_type = ntohl(rmsgp->rm_type); if (rmsgp->rm_vers != RPCRDMA_VERSION) return -ENOSYS; if (rmsgp->rm_type == RDMA_MSGP) { int hdrlen; rmsgp->rm_body.rm_padded.rm_align = ntohl(rmsgp->rm_body.rm_padded.rm_align); rmsgp->rm_body.rm_padded.rm_thresh = ntohl(rmsgp->rm_body.rm_padded.rm_thresh); va = &rmsgp->rm_body.rm_padded.rm_pempty[4]; rqstp->rq_arg.head[0].iov_base = va; hdrlen = (u32)((unsigned long)va - (unsigned long)rmsgp); rqstp->rq_arg.head[0].iov_len -= hdrlen; if (hdrlen > rqstp->rq_arg.len) return -EINVAL; return hdrlen; } va = &rmsgp->rm_body.rm_chunks[0]; vaend = (u32 *)((unsigned long)rmsgp + rqstp->rq_arg.len); va = decode_read_list(va, vaend); if (!va) return -EINVAL; va = decode_write_list(va, vaend); if (!va) return -EINVAL; va = decode_reply_array(va, vaend); if (!va) return -EINVAL; rqstp->rq_arg.head[0].iov_base = va; hdr_len = (unsigned long)va - (unsigned long)rmsgp; rqstp->rq_arg.head[0].iov_len -= hdr_len; *rdma_req = rmsgp; return hdr_len; }