aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2016-05-04 10:53:47 -0400
committerJ. Bruce Fields <bfields@redhat.com>2016-05-13 15:53:06 -0400
commitd9e4084f6c9746e51a78a4d7ebf4983023289b32 (patch)
tree3ed63cefa263b7fcd983e2f00d63b2ca83354bc0
parent84f225c23d8906c9371d0749e062975c018ef6c4 (diff)
svcrdma: Generalize svc_rdma_xdr_decode_req()
Clean up: Pass in just the piece of the svc_rqst that is needed here. While we're in the area, add an informative documenting comment. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--include/linux/sunrpc/svc_rdma.h2
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_marshal.c32
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c2
3 files changed, 24 insertions, 12 deletions
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index 3081339968c3..d6917b896d3a 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -199,7 +199,7 @@ extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt,
199 struct xdr_buf *rcvbuf); 199 struct xdr_buf *rcvbuf);
200 200
201/* svc_rdma_marshal.c */ 201/* svc_rdma_marshal.c */
202extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg *, struct svc_rqst *); 202extern int svc_rdma_xdr_decode_req(struct xdr_buf *);
203extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *, 203extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *,
204 struct rpcrdma_msg *, 204 struct rpcrdma_msg *,
205 enum rpcrdma_errcode, __be32 *); 205 enum rpcrdma_errcode, __be32 *);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_marshal.c b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
index 765bca47c74d..0ba9887f3e22 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_marshal.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
@@ -145,19 +145,32 @@ static __be32 *decode_reply_array(__be32 *va, __be32 *vaend)
145 return (__be32 *)&ary->wc_array[nchunks]; 145 return (__be32 *)&ary->wc_array[nchunks];
146} 146}
147 147
148int svc_rdma_xdr_decode_req(struct rpcrdma_msg *rmsgp, struct svc_rqst *rqstp) 148/**
149 * svc_rdma_xdr_decode_req - Parse incoming RPC-over-RDMA header
150 * @rq_arg: Receive buffer
151 *
152 * On entry, xdr->head[0].iov_base points to first byte in the
153 * RPC-over-RDMA header.
154 *
155 * On successful exit, head[0] points to first byte past the
156 * RPC-over-RDMA header. For RDMA_MSG, this is the RPC message.
157 * The length of the RPC-over-RDMA header is returned.
158 */
159int svc_rdma_xdr_decode_req(struct xdr_buf *rq_arg)
149{ 160{
161 struct rpcrdma_msg *rmsgp;
150 __be32 *va, *vaend; 162 __be32 *va, *vaend;
151 unsigned int len; 163 unsigned int len;
152 u32 hdr_len; 164 u32 hdr_len;
153 165
154 /* Verify that there's enough bytes for header + something */ 166 /* Verify that there's enough bytes for header + something */
155 if (rqstp->rq_arg.len <= RPCRDMA_HDRLEN_ERR) { 167 if (rq_arg->len <= RPCRDMA_HDRLEN_ERR) {
156 dprintk("svcrdma: header too short = %d\n", 168 dprintk("svcrdma: header too short = %d\n",
157 rqstp->rq_arg.len); 169 rq_arg->len);
158 return -EINVAL; 170 return -EINVAL;
159 } 171 }
160 172
173 rmsgp = (struct rpcrdma_msg *)rq_arg->head[0].iov_base;
161 if (rmsgp->rm_vers != rpcrdma_version) { 174 if (rmsgp->rm_vers != rpcrdma_version) {
162 dprintk("%s: bad version %u\n", __func__, 175 dprintk("%s: bad version %u\n", __func__,
163 be32_to_cpu(rmsgp->rm_vers)); 176 be32_to_cpu(rmsgp->rm_vers));
@@ -189,10 +202,10 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg *rmsgp, struct svc_rqst *rqstp)
189 be32_to_cpu(rmsgp->rm_body.rm_padded.rm_thresh); 202 be32_to_cpu(rmsgp->rm_body.rm_padded.rm_thresh);
190 203
191 va = &rmsgp->rm_body.rm_padded.rm_pempty[4]; 204 va = &rmsgp->rm_body.rm_padded.rm_pempty[4];
192 rqstp->rq_arg.head[0].iov_base = va; 205 rq_arg->head[0].iov_base = va;
193 len = (u32)((unsigned long)va - (unsigned long)rmsgp); 206 len = (u32)((unsigned long)va - (unsigned long)rmsgp);
194 rqstp->rq_arg.head[0].iov_len -= len; 207 rq_arg->head[0].iov_len -= len;
195 if (len > rqstp->rq_arg.len) 208 if (len > rq_arg->len)
196 return -EINVAL; 209 return -EINVAL;
197 return len; 210 return len;
198 default: 211 default:
@@ -205,7 +218,7 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg *rmsgp, struct svc_rqst *rqstp)
205 * chunk list and a reply chunk list. 218 * chunk list and a reply chunk list.
206 */ 219 */
207 va = &rmsgp->rm_body.rm_chunks[0]; 220 va = &rmsgp->rm_body.rm_chunks[0];
208 vaend = (__be32 *)((unsigned long)rmsgp + rqstp->rq_arg.len); 221 vaend = (__be32 *)((unsigned long)rmsgp + rq_arg->len);
209 va = decode_read_list(va, vaend); 222 va = decode_read_list(va, vaend);
210 if (!va) { 223 if (!va) {
211 dprintk("svcrdma: failed to decode read list\n"); 224 dprintk("svcrdma: failed to decode read list\n");
@@ -222,10 +235,9 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg *rmsgp, struct svc_rqst *rqstp)
222 return -EINVAL; 235 return -EINVAL;
223 } 236 }
224 237
225 rqstp->rq_arg.head[0].iov_base = va; 238 rq_arg->head[0].iov_base = va;
226 hdr_len = (unsigned long)va - (unsigned long)rmsgp; 239 hdr_len = (unsigned long)va - (unsigned long)rmsgp;
227 rqstp->rq_arg.head[0].iov_len -= hdr_len; 240 rq_arg->head[0].iov_len -= hdr_len;
228
229 return hdr_len; 241 return hdr_len;
230} 242}
231 243
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 1b72f351fbd3..c984b0aaecb1 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -636,7 +636,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
636 636
637 /* Decode the RDMA header. */ 637 /* Decode the RDMA header. */
638 rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; 638 rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base;
639 ret = svc_rdma_xdr_decode_req(rmsgp, rqstp); 639 ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg);
640 if (ret < 0) 640 if (ret < 0)
641 goto out_err; 641 goto out_err;
642 if (ret == 0) 642 if (ret == 0)