aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2015-06-04 11:21:10 -0400
committerJ. Bruce Fields <bfields@redhat.com>2015-06-04 16:55:59 -0400
commit30b7e246a6222f1fbad39b1451273375306fe1e2 (patch)
treef53c5110827f9b16c3e8e0c56eae5f653fc03eaf
parent70747c25a701b563a54c20c4a77efe8292aad151 (diff)
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: 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.c84
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c2
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c2
4 files changed, 42 insertions, 48 deletions
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index 8ad9b6d9d4e0..c03ca0a1b743 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -184,7 +184,7 @@ struct svcxprt_rdma {
184extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg **, struct svc_rqst *); 184extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg **, struct svc_rqst *);
185extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *, 185extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *,
186 struct rpcrdma_msg *, 186 struct rpcrdma_msg *,
187 enum rpcrdma_errcode, u32 *); 187 enum rpcrdma_errcode, __be32 *);
188extern void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *, int); 188extern void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *, int);
189extern void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *, int); 189extern void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *, int);
190extern void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *, int, 190extern void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *, int,
diff --git a/net/sunrpc/xprtrdma/svc_rdma_marshal.c b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
index 45e22c9549d2..e2fca7617242 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_marshal.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
@@ -50,12 +50,12 @@
50/* 50/*
51 * Decodes a read chunk list. The expected format is as follows: 51 * Decodes a read chunk list. The expected format is as follows:
52 * descrim : xdr_one 52 * descrim : xdr_one
53 * position : u32 offset into XDR stream 53 * position : __be32 offset into XDR stream
54 * handle : u32 RKEY 54 * handle : __be32 RKEY
55 * . . . 55 * . . .
56 * end-of-list: xdr_zero 56 * end-of-list: xdr_zero
57 */ 57 */
58static u32 *decode_read_list(u32 *va, u32 *vaend) 58static __be32 *decode_read_list(__be32 *va, __be32 *vaend)
59{ 59{
60 struct rpcrdma_read_chunk *ch = (struct rpcrdma_read_chunk *)va; 60 struct rpcrdma_read_chunk *ch = (struct rpcrdma_read_chunk *)va;
61 61
@@ -67,20 +67,20 @@ static u32 *decode_read_list(u32 *va, u32 *vaend)
67 } 67 }
68 ch++; 68 ch++;
69 } 69 }
70 return (u32 *)&ch->rc_position; 70 return &ch->rc_position;
71} 71}
72 72
73/* 73/*
74 * Decodes a write chunk list. The expected format is as follows: 74 * Decodes a write chunk list. The expected format is as follows:
75 * descrim : xdr_one 75 * descrim : xdr_one
76 * nchunks : <count> 76 * nchunks : <count>
77 * handle : u32 RKEY ---+ 77 * handle : __be32 RKEY ---+
78 * length : u32 <len of segment> | 78 * length : __be32 <len of segment> |
79 * offset : remove va + <count> 79 * offset : remove va + <count>
80 * . . . | 80 * . . . |
81 * ---+ 81 * ---+
82 */ 82 */
83static u32 *decode_write_list(u32 *va, u32 *vaend) 83static __be32 *decode_write_list(__be32 *va, __be32 *vaend)
84{ 84{
85 unsigned long start, end; 85 unsigned long start, end;
86 int nchunks; 86 int nchunks;
@@ -90,14 +90,14 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
90 90
91 /* Check for not write-array */ 91 /* Check for not write-array */
92 if (ary->wc_discrim == xdr_zero) 92 if (ary->wc_discrim == xdr_zero)
93 return (u32 *)&ary->wc_nchunks; 93 return &ary->wc_nchunks;
94 94
95 if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) > 95 if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) >
96 (unsigned long)vaend) { 96 (unsigned long)vaend) {
97 dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend); 97 dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend);
98 return NULL; 98 return NULL;
99 } 99 }
100 nchunks = ntohl(ary->wc_nchunks); 100 nchunks = be32_to_cpu(ary->wc_nchunks);
101 101
102 start = (unsigned long)&ary->wc_array[0]; 102 start = (unsigned long)&ary->wc_array[0];
103 end = (unsigned long)vaend; 103 end = (unsigned long)vaend;
@@ -112,10 +112,10 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
112 * rs_length is the 2nd 4B field in wc_target and taking its 112 * rs_length is the 2nd 4B field in wc_target and taking its
113 * address skips the list terminator 113 * address skips the list terminator
114 */ 114 */
115 return (u32 *)&ary->wc_array[nchunks].wc_target.rs_length; 115 return &ary->wc_array[nchunks].wc_target.rs_length;
116} 116}
117 117
118static u32 *decode_reply_array(u32 *va, u32 *vaend) 118static __be32 *decode_reply_array(__be32 *va, __be32 *vaend)
119{ 119{
120 unsigned long start, end; 120 unsigned long start, end;
121 int nchunks; 121 int nchunks;
@@ -124,14 +124,14 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
124 124
125 /* Check for no reply-array */ 125 /* Check for no reply-array */
126 if (ary->wc_discrim == xdr_zero) 126 if (ary->wc_discrim == xdr_zero)
127 return (u32 *)&ary->wc_nchunks; 127 return &ary->wc_nchunks;
128 128
129 if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) > 129 if ((unsigned long)ary + sizeof(struct rpcrdma_write_array) >
130 (unsigned long)vaend) { 130 (unsigned long)vaend) {
131 dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend); 131 dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend);
132 return NULL; 132 return NULL;
133 } 133 }
134 nchunks = ntohl(ary->wc_nchunks); 134 nchunks = be32_to_cpu(ary->wc_nchunks);
135 135
136 start = (unsigned long)&ary->wc_array[0]; 136 start = (unsigned long)&ary->wc_array[0];
137 end = (unsigned long)vaend; 137 end = (unsigned long)vaend;
@@ -142,15 +142,14 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
142 ary, nchunks, vaend); 142 ary, nchunks, vaend);
143 return NULL; 143 return NULL;
144 } 144 }
145 return (u32 *)&ary->wc_array[nchunks]; 145 return (__be32 *)&ary->wc_array[nchunks];
146} 146}
147 147
148int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req, 148int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
149 struct svc_rqst *rqstp) 149 struct svc_rqst *rqstp)
150{ 150{
151 struct rpcrdma_msg *rmsgp = NULL; 151 struct rpcrdma_msg *rmsgp = NULL;
152 u32 *va; 152 __be32 *va, *vaend;
153 u32 *vaend;
154 u32 hdr_len; 153 u32 hdr_len;
155 154
156 rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; 155 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 return -EINVAL; 161 return -EINVAL;
163 } 162 }
164 163
165 /* Decode the header */ 164 if (rmsgp->rm_vers != rpcrdma_version)
166 rmsgp->rm_xid = ntohl(rmsgp->rm_xid);
167 rmsgp->rm_vers = ntohl(rmsgp->rm_vers);
168 rmsgp->rm_credit = ntohl(rmsgp->rm_credit);
169 rmsgp->rm_type = ntohl(rmsgp->rm_type);
170
171 if (rmsgp->rm_vers != RPCRDMA_VERSION)
172 return -ENOSYS; 165 return -ENOSYS;
173 166
174 /* Pull in the extra for the padded case and bump our pointer */ 167 /* Pull in the extra for the padded case and bump our pointer */
175 if (rmsgp->rm_type == RDMA_MSGP) { 168 if (rmsgp->rm_type == rdma_msgp) {
176 int hdrlen; 169 int hdrlen;
170
177 rmsgp->rm_body.rm_padded.rm_align = 171 rmsgp->rm_body.rm_padded.rm_align =
178 ntohl(rmsgp->rm_body.rm_padded.rm_align); 172 be32_to_cpu(rmsgp->rm_body.rm_padded.rm_align);
179 rmsgp->rm_body.rm_padded.rm_thresh = 173 rmsgp->rm_body.rm_padded.rm_thresh =
180 ntohl(rmsgp->rm_body.rm_padded.rm_thresh); 174 be32_to_cpu(rmsgp->rm_body.rm_padded.rm_thresh);
181 175
182 va = &rmsgp->rm_body.rm_padded.rm_pempty[4]; 176 va = &rmsgp->rm_body.rm_padded.rm_pempty[4];
183 rqstp->rq_arg.head[0].iov_base = va; 177 rqstp->rq_arg.head[0].iov_base = va;
@@ -192,7 +186,7 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
192 * chunk list and a reply chunk list. 186 * chunk list and a reply chunk list.
193 */ 187 */
194 va = &rmsgp->rm_body.rm_chunks[0]; 188 va = &rmsgp->rm_body.rm_chunks[0];
195 vaend = (u32 *)((unsigned long)rmsgp + rqstp->rq_arg.len); 189 vaend = (__be32 *)((unsigned long)rmsgp + rqstp->rq_arg.len);
196 va = decode_read_list(va, vaend); 190 va = decode_read_list(va, vaend);
197 if (!va) 191 if (!va)
198 return -EINVAL; 192 return -EINVAL;
@@ -213,18 +207,18 @@ int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
213 207
214int svc_rdma_xdr_encode_error(struct svcxprt_rdma *xprt, 208int svc_rdma_xdr_encode_error(struct svcxprt_rdma *xprt,
215 struct rpcrdma_msg *rmsgp, 209 struct rpcrdma_msg *rmsgp,
216 enum rpcrdma_errcode err, u32 *va) 210 enum rpcrdma_errcode err, __be32 *va)
217{ 211{
218 u32 *startp = va; 212 __be32 *startp = va;
219 213
220 *va++ = htonl(rmsgp->rm_xid); 214 *va++ = rmsgp->rm_xid;
221 *va++ = htonl(rmsgp->rm_vers); 215 *va++ = rmsgp->rm_vers;
222 *va++ = htonl(xprt->sc_max_requests); 216 *va++ = cpu_to_be32(xprt->sc_max_requests);
223 *va++ = htonl(RDMA_ERROR); 217 *va++ = rdma_error;
224 *va++ = htonl(err); 218 *va++ = cpu_to_be32(err);
225 if (err == ERR_VERS) { 219 if (err == ERR_VERS) {
226 *va++ = htonl(RPCRDMA_VERSION); 220 *va++ = rpcrdma_version;
227 *va++ = htonl(RPCRDMA_VERSION); 221 *va++ = rpcrdma_version;
228 } 222 }
229 223
230 return (int)((unsigned long)va - (unsigned long)startp); 224 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 &rmsgp->rm_body.rm_chunks[1]; 235 &rmsgp->rm_body.rm_chunks[1];
242 if (wr_ary->wc_discrim) 236 if (wr_ary->wc_discrim)
243 wr_ary = (struct rpcrdma_write_array *) 237 wr_ary = (struct rpcrdma_write_array *)
244 &wr_ary->wc_array[ntohl(wr_ary->wc_nchunks)]. 238 &wr_ary->wc_array[be32_to_cpu(wr_ary->wc_nchunks)].
245 wc_target.rs_length; 239 wc_target.rs_length;
246 else 240 else
247 wr_ary = (struct rpcrdma_write_array *) 241 wr_ary = (struct rpcrdma_write_array *)
@@ -250,7 +244,7 @@ int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *rmsgp)
250 /* skip reply array */ 244 /* skip reply array */
251 if (wr_ary->wc_discrim) 245 if (wr_ary->wc_discrim)
252 wr_ary = (struct rpcrdma_write_array *) 246 wr_ary = (struct rpcrdma_write_array *)
253 &wr_ary->wc_array[ntohl(wr_ary->wc_nchunks)]; 247 &wr_ary->wc_array[be32_to_cpu(wr_ary->wc_nchunks)];
254 else 248 else
255 wr_ary = (struct rpcrdma_write_array *) 249 wr_ary = (struct rpcrdma_write_array *)
256 &wr_ary->wc_nchunks; 250 &wr_ary->wc_nchunks;
@@ -269,7 +263,7 @@ void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *rmsgp, int chunks)
269 ary = (struct rpcrdma_write_array *) 263 ary = (struct rpcrdma_write_array *)
270 &rmsgp->rm_body.rm_chunks[1]; 264 &rmsgp->rm_body.rm_chunks[1];
271 ary->wc_discrim = xdr_one; 265 ary->wc_discrim = xdr_one;
272 ary->wc_nchunks = htonl(chunks); 266 ary->wc_nchunks = cpu_to_be32(chunks);
273 267
274 /* write-list terminator */ 268 /* write-list terminator */
275 ary->wc_array[chunks].wc_target.rs_handle = xdr_zero; 269 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 int chunks) 276 int chunks)
283{ 277{
284 ary->wc_discrim = xdr_one; 278 ary->wc_discrim = xdr_one;
285 ary->wc_nchunks = htonl(chunks); 279 ary->wc_nchunks = cpu_to_be32(chunks);
286} 280}
287 281
288void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *ary, 282void 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 struct rpcrdma_segment *seg = &ary->wc_array[chunk_no].wc_target; 288 struct rpcrdma_segment *seg = &ary->wc_array[chunk_no].wc_target;
295 seg->rs_handle = rs_handle; 289 seg->rs_handle = rs_handle;
296 seg->rs_offset = rs_offset; 290 seg->rs_offset = rs_offset;
297 seg->rs_length = htonl(write_len); 291 seg->rs_length = cpu_to_be32(write_len);
298} 292}
299 293
300void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *xprt, 294void 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 struct rpcrdma_msg *rdma_resp, 296 struct rpcrdma_msg *rdma_resp,
303 enum rpcrdma_proc rdma_type) 297 enum rpcrdma_proc rdma_type)
304{ 298{
305 rdma_resp->rm_xid = htonl(rdma_argp->rm_xid); 299 rdma_resp->rm_xid = rdma_argp->rm_xid;
306 rdma_resp->rm_vers = htonl(rdma_argp->rm_vers); 300 rdma_resp->rm_vers = rdma_argp->rm_vers;
307 rdma_resp->rm_credit = htonl(xprt->sc_max_requests); 301 rdma_resp->rm_credit = cpu_to_be32(xprt->sc_max_requests);
308 rdma_resp->rm_type = htonl(rdma_type); 302 rdma_resp->rm_type = cpu_to_be32(rdma_type);
309 303
310 /* Encode <nul> chunks lists */ 304 /* Encode <nul> chunks lists */
311 rdma_resp->rm_body.rm_chunks[0] = xdr_zero; 305 rdma_resp->rm_body.rm_chunks[0] = xdr_zero;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index f9f13a32ddb8..ac93ce01a729 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -85,7 +85,7 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
85 85
86 /* RDMA_NOMSG: RDMA READ data should land just after RDMA RECV data */ 86 /* RDMA_NOMSG: RDMA READ data should land just after RDMA RECV data */
87 rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; 87 rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base;
88 if (be32_to_cpu(rmsgp->rm_type) == RDMA_NOMSG) 88 if (rmsgp->rm_type == rdma_nomsg)
89 rqstp->rq_arg.pages = &rqstp->rq_pages[0]; 89 rqstp->rq_arg.pages = &rqstp->rq_pages[0];
90 else 90 else
91 rqstp->rq_arg.pages = &rqstp->rq_pages[1]; 91 rqstp->rq_arg.pages = &rqstp->rq_pages[1];
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index f609c1c2d38d..be084938e3ff 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -1319,7 +1319,7 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp,
1319 struct ib_send_wr err_wr; 1319 struct ib_send_wr err_wr;
1320 struct page *p; 1320 struct page *p;
1321 struct svc_rdma_op_ctxt *ctxt; 1321 struct svc_rdma_op_ctxt *ctxt;
1322 u32 *va; 1322 __be32 *va;
1323 int length; 1323 int length;
1324 int ret; 1324 int ret;
1325 1325