Commit 30b7e246 authored by Chuck Lever's avatar Chuck Lever Committed by J. Bruce Fields

svcrdma: Keep rpcrdma_msg fields in network byte-order

Fields in struct rpcrdma_msg are __be32. Don't byte-swap these
fields when decoding RPC calls and then swap them back for the
reply. For the most part, they can be left alone.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 70747c25
...@@ -184,7 +184,7 @@ struct svcxprt_rdma { ...@@ -184,7 +184,7 @@ struct svcxprt_rdma {
extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg **, struct svc_rqst *); extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg **, struct svc_rqst *);
extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *, extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *,
struct rpcrdma_msg *, struct rpcrdma_msg *,
enum rpcrdma_errcode, u32 *); enum rpcrdma_errcode, __be32 *);
extern void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *, int); extern void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *, int);
extern void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *, int); extern void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *, int);
extern void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *, int, extern void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *, int,
......
...@@ -50,12 +50,12 @@ ...@@ -50,12 +50,12 @@
/* /*
* Decodes a read chunk list. The expected format is as follows: * Decodes a read chunk list. The expected format is as follows:
* descrim : xdr_one * descrim : xdr_one
* position : u32 offset into XDR stream * position : __be32 offset into XDR stream
* handle : u32 RKEY * handle : __be32 RKEY
* . . . * . . .
* end-of-list: xdr_zero * end-of-list: xdr_zero
*/ */
static u32 *decode_read_list(u32 *va, u32 *vaend) static __be32 *decode_read_list(__be32 *va, __be32 *vaend)
{ {
struct rpcrdma_read_chunk *ch = (struct rpcrdma_read_chunk *)va; struct rpcrdma_read_chunk *ch = (struct rpcrdma_read_chunk *)va;
...@@ -67,20 +67,20 @@ static u32 *decode_read_list(u32 *va, u32 *vaend) ...@@ -67,20 +67,20 @@ static u32 *decode_read_list(u32 *va, u32 *vaend)
} }
ch++; ch++;
} }
return (u32 *)&ch->rc_position; return &ch->rc_position;
} }
/* /*
* Decodes a write chunk list. The expected format is as follows: * Decodes a write chunk list. The expected format is as follows:
* descrim : xdr_one * descrim : xdr_one
* nchunks : <count> * nchunks : <count>
* handle : u32 RKEY ---+ * handle : __be32 RKEY ---+
* length : u32 <len of segment> | * length : __be32 <len of segment> |
* offset : remove va + <count> * offset : remove va + <count>
* . . . | * . . . |
* ---+ * ---+
*/ */
static u32 *decode_write_list(u32 *va, u32 *vaend) static __be32 *decode_write_list(__be32 *va, __be32 *vaend)
{ {
unsigned long start, end; unsigned long start, end;
int nchunks; int nchunks;
...@@ -90,14 +90,14 @@ static u32 *decode_write_list(u32 *va, u32 *vaend) ...@@ -90,14 +90,14 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
/* Check for not write-array */ /* Check for not write-array */
if (ary->wc_discrim == xdr_zero) if (ary->wc_discrim == xdr_zero)
return (u32 *)&ary->wc_nchunks; return &ary->wc_nchunks;
if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) > if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) >
(unsigned long)vaend) { (unsigned long)vaend) {
dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend); dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend);
return NULL; return NULL;
} }
nchunks = ntohl(ary->wc_nchunks); nchunks = be32_to_cpu(ary->wc_nchunks);
start = (unsigned long)&ary->wc_array[0]; start = (unsigned long)&ary->wc_array[0];
end = (unsigned long)vaend; end = (unsigned long)vaend;
...@@ -112,10 +112,10 @@ static u32 *decode_write_list(u32 *va, u32 *vaend) ...@@ -112,10 +112,10 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
* rs_length is the 2nd 4B field in wc_target and taking its * rs_length is the 2nd 4B field in wc_target and taking its
* address skips the list terminator * address skips the list terminator
*/ */
return (u32 *)&ary->wc_array[nchunks].wc_target.rs_length; return &ary->wc_array[nchunks].wc_target.rs_length;
} }
static u32 *decode_reply_array(u32 *va, u32 *vaend) static __be32 *decode_reply_array(__be32 *va, __be32 *vaend)
{ {
unsigned long start, end; unsigned long start, end;
int nchunks; int nchunks;
...@@ -124,14 +124,14 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend) ...@@ -124,14 +124,14 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
/* Check for no reply-array */ /* Check for no reply-array */
if (ary->wc_discrim == xdr_zero) if (ary->wc_discrim == xdr_zero)
return (u32 *)&ary->wc_nchunks; return &ary->wc_nchunks;
if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) > if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) >
(unsigned long)vaend) { (unsigned long)vaend) {
dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend); dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend);
return NULL; return NULL;
} }
nchunks = ntohl(ary->wc_nchunks); nchunks = be32_to_cpu(ary->wc_nchunks);
start = (unsigned long)&ary->wc_array[0]; start = (unsigned long)&ary->wc_array[0];
end = (unsigned long)vaend; end = (unsigned long)vaend;
...@@ -142,15 +142,14 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend) ...@@ -142,15 +142,14 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
ary, nchunks, vaend); ary, nchunks, vaend);
return NULL; return NULL;
} }
return (u32 *)&ary->wc_array[nchunks]; return (__be32 *)&ary->wc_array[nchunks];
} }
int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req, int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
struct svc_rqst *rqstp) struct svc_rqst *rqstp)
{ {
struct rpcrdma_msg *rmsgp = NULL; struct rpcrdma_msg *rmsgp = NULL;
u32 *va; __be32 *va, *vaend;
u32 *vaend;
u32 hdr_len; u32 hdr_len;
rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base;
...@@ -162,22 +161,17 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req, ...@@ -162,22 +161,17 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
return -EINVAL; return -EINVAL;
} }
/* Decode the header */ if (rmsgp->rm_vers != rpcrdma_version)
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; return -ENOSYS;
/* Pull in the extra for the padded case and bump our pointer */ /* Pull in the extra for the padded case and bump our pointer */
if (rmsgp->rm_type == RDMA_MSGP) { if (rmsgp->rm_type == rdma_msgp) {
int hdrlen; int hdrlen;
rmsgp->rm_body.rm_padded.rm_align = rmsgp->rm_body.rm_padded.rm_align =
ntohl(rmsgp->rm_body.rm_padded.rm_align); be32_to_cpu(rmsgp->rm_body.rm_padded.rm_align);
rmsgp->rm_body.rm_padded.rm_thresh = rmsgp->rm_body.rm_padded.rm_thresh =
ntohl(rmsgp->rm_body.rm_padded.rm_thresh); be32_to_cpu(rmsgp->rm_body.rm_padded.rm_thresh);
va = &rmsgp->rm_body.rm_padded.rm_pempty[4]; va = &rmsgp->rm_body.rm_padded.rm_pempty[4];
rqstp->rq_arg.head[0].iov_base = va; rqstp->rq_arg.head[0].iov_base = va;
...@@ -192,7 +186,7 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req, ...@@ -192,7 +186,7 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
* chunk list and a reply chunk list. * chunk list and a reply chunk list.
*/ */
va = &rmsgp->rm_body.rm_chunks[0]; va = &rmsgp->rm_body.rm_chunks[0];
vaend = (u32 *)((unsigned long)rmsgp + rqstp->rq_arg.len); vaend = (__be32 *)((unsigned long)rmsgp + rqstp->rq_arg.len);
va = decode_read_list(va, vaend); va = decode_read_list(va, vaend);
if (!va) if (!va)
return -EINVAL; return -EINVAL;
...@@ -213,18 +207,18 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req, ...@@ -213,18 +207,18 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
int svc_rdma_xdr_encode_error(struct svcxprt_rdma *xprt, int svc_rdma_xdr_encode_error(struct svcxprt_rdma *xprt,
struct rpcrdma_msg *rmsgp, struct rpcrdma_msg *rmsgp,
enum rpcrdma_errcode err, u32 *va) enum rpcrdma_errcode err, __be32 *va)
{ {
u32 *startp = va; __be32 *startp = va;
*va++ = htonl(rmsgp->rm_xid); *va++ = rmsgp->rm_xid;
*va++ = htonl(rmsgp->rm_vers); *va++ = rmsgp->rm_vers;
*va++ = htonl(xprt->sc_max_requests); *va++ = cpu_to_be32(xprt->sc_max_requests);
*va++ = htonl(RDMA_ERROR); *va++ = rdma_error;
*va++ = htonl(err); *va++ = cpu_to_be32(err);
if (err == ERR_VERS) { if (err == ERR_VERS) {
*va++ = htonl(RPCRDMA_VERSION); *va++ = rpcrdma_version;
*va++ = htonl(RPCRDMA_VERSION); *va++ = rpcrdma_version;
} }
return (int)((unsigned long)va - (unsigned long)startp); return (int)((unsigned long)va - (unsigned long)startp);
...@@ -241,7 +235,7 @@ int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *rmsgp) ...@@ -241,7 +235,7 @@ int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *rmsgp)
&rmsgp->rm_body.rm_chunks[1]; &rmsgp->rm_body.rm_chunks[1];
if (wr_ary->wc_discrim) if (wr_ary->wc_discrim)
wr_ary = (struct rpcrdma_write_array *) wr_ary = (struct rpcrdma_write_array *)
&wr_ary->wc_array[ntohl(wr_ary->wc_nchunks)]. &wr_ary->wc_array[be32_to_cpu(wr_ary->wc_nchunks)].
wc_target.rs_length; wc_target.rs_length;
else else
wr_ary = (struct rpcrdma_write_array *) wr_ary = (struct rpcrdma_write_array *)
...@@ -250,7 +244,7 @@ int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *rmsgp) ...@@ -250,7 +244,7 @@ int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *rmsgp)
/* skip reply array */ /* skip reply array */
if (wr_ary->wc_discrim) if (wr_ary->wc_discrim)
wr_ary = (struct rpcrdma_write_array *) wr_ary = (struct rpcrdma_write_array *)
&wr_ary->wc_array[ntohl(wr_ary->wc_nchunks)]; &wr_ary->wc_array[be32_to_cpu(wr_ary->wc_nchunks)];
else else
wr_ary = (struct rpcrdma_write_array *) wr_ary = (struct rpcrdma_write_array *)
&wr_ary->wc_nchunks; &wr_ary->wc_nchunks;
...@@ -269,7 +263,7 @@ void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *rmsgp, int chunks) ...@@ -269,7 +263,7 @@ void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *rmsgp, int chunks)
ary = (struct rpcrdma_write_array *) ary = (struct rpcrdma_write_array *)
&rmsgp->rm_body.rm_chunks[1]; &rmsgp->rm_body.rm_chunks[1];
ary->wc_discrim = xdr_one; ary->wc_discrim = xdr_one;
ary->wc_nchunks = htonl(chunks); ary->wc_nchunks = cpu_to_be32(chunks);
/* write-list terminator */ /* write-list terminator */
ary->wc_array[chunks].wc_target.rs_handle = xdr_zero; ary->wc_array[chunks].wc_target.rs_handle = xdr_zero;
...@@ -282,7 +276,7 @@ void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *ary, ...@@ -282,7 +276,7 @@ void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *ary,
int chunks) int chunks)
{ {
ary->wc_discrim = xdr_one; ary->wc_discrim = xdr_one;
ary->wc_nchunks = htonl(chunks); ary->wc_nchunks = cpu_to_be32(chunks);
} }
void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *ary, void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *ary,
...@@ -294,7 +288,7 @@ void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *ary, ...@@ -294,7 +288,7 @@ void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *ary,
struct rpcrdma_segment *seg = &ary->wc_array[chunk_no].wc_target; struct rpcrdma_segment *seg = &ary->wc_array[chunk_no].wc_target;
seg->rs_handle = rs_handle; seg->rs_handle = rs_handle;
seg->rs_offset = rs_offset; seg->rs_offset = rs_offset;
seg->rs_length = htonl(write_len); seg->rs_length = cpu_to_be32(write_len);
} }
void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *xprt, void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *xprt,
...@@ -302,10 +296,10 @@ void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *xprt, ...@@ -302,10 +296,10 @@ void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *xprt,
struct rpcrdma_msg *rdma_resp, struct rpcrdma_msg *rdma_resp,
enum rpcrdma_proc rdma_type) enum rpcrdma_proc rdma_type)
{ {
rdma_resp->rm_xid = htonl(rdma_argp->rm_xid); rdma_resp->rm_xid = rdma_argp->rm_xid;
rdma_resp->rm_vers = htonl(rdma_argp->rm_vers); rdma_resp->rm_vers = rdma_argp->rm_vers;
rdma_resp->rm_credit = htonl(xprt->sc_max_requests); rdma_resp->rm_credit = cpu_to_be32(xprt->sc_max_requests);
rdma_resp->rm_type = htonl(rdma_type); rdma_resp->rm_type = cpu_to_be32(rdma_type);
/* Encode <nul> chunks lists */ /* Encode <nul> chunks lists */
rdma_resp->rm_body.rm_chunks[0] = xdr_zero; rdma_resp->rm_body.rm_chunks[0] = xdr_zero;
......
...@@ -85,7 +85,7 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp, ...@@ -85,7 +85,7 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
/* RDMA_NOMSG: RDMA READ data should land just after RDMA RECV data */ /* RDMA_NOMSG: RDMA READ data should land just after RDMA RECV data */
rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base;
if (be32_to_cpu(rmsgp->rm_type) == RDMA_NOMSG) if (rmsgp->rm_type == rdma_nomsg)
rqstp->rq_arg.pages = &rqstp->rq_pages[0]; rqstp->rq_arg.pages = &rqstp->rq_pages[0];
else else
rqstp->rq_arg.pages = &rqstp->rq_pages[1]; rqstp->rq_arg.pages = &rqstp->rq_pages[1];
......
...@@ -1319,7 +1319,7 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp, ...@@ -1319,7 +1319,7 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp,
struct ib_send_wr err_wr; struct ib_send_wr err_wr;
struct page *p; struct page *p;
struct svc_rdma_op_ctxt *ctxt; struct svc_rdma_op_ctxt *ctxt;
u32 *va; __be32 *va;
int length; int length;
int ret; int ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment