forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
svc_rdma_marshal.c has one remaining exported function -- svc_rdma_xdr_decode_req -- and it has a single call site. Take the same approach as the sendto path, and move this function into the source file where it is called. This is a refactoring change only. Signed-off-by: Chuck Lever <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]>
- Loading branch information
1 parent
107c1d0
commit a80a323
Showing
4 changed files
with
128 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* | ||
* Copyright (c) 2016, 2017 Oracle. All rights reserved. | ||
* Copyright (c) 2014 Open Grid Computing, Inc. All rights reserved. | ||
* Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. | ||
* | ||
|
@@ -40,6 +41,7 @@ | |
* Author: Tom Tucker <[email protected]> | ||
*/ | ||
|
||
#include <linux/sunrpc/xdr.h> | ||
#include <linux/sunrpc/debug.h> | ||
#include <linux/sunrpc/rpc_rdma.h> | ||
#include <linux/spinlock.h> | ||
|
@@ -115,6 +117,130 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp, | |
rqstp->rq_arg.tail[0].iov_len = 0; | ||
} | ||
|
||
static __be32 *xdr_check_read_list(__be32 *p, __be32 *end) | ||
{ | ||
__be32 *next; | ||
|
||
while (*p++ != xdr_zero) { | ||
next = p + rpcrdma_readchunk_maxsz - 1; | ||
if (next > end) | ||
return NULL; | ||
p = next; | ||
} | ||
return p; | ||
} | ||
|
||
static __be32 *xdr_check_write_list(__be32 *p, __be32 *end) | ||
{ | ||
__be32 *next; | ||
|
||
while (*p++ != xdr_zero) { | ||
next = p + 1 + be32_to_cpup(p) * rpcrdma_segment_maxsz; | ||
if (next > end) | ||
return NULL; | ||
p = next; | ||
} | ||
return p; | ||
} | ||
|
||
static __be32 *xdr_check_reply_chunk(__be32 *p, __be32 *end) | ||
{ | ||
__be32 *next; | ||
|
||
if (*p++ != xdr_zero) { | ||
next = p + 1 + be32_to_cpup(p) * rpcrdma_segment_maxsz; | ||
if (next > end) | ||
return NULL; | ||
p = next; | ||
} | ||
return p; | ||
} | ||
|
||
/* On entry, xdr->head[0].iov_base points to first byte in the | ||
* RPC-over-RDMA header. | ||
* | ||
* On successful exit, head[0] points to first byte past the | ||
* RPC-over-RDMA header. For RDMA_MSG, this is the RPC message. | ||
* The length of the RPC-over-RDMA header is returned. | ||
* | ||
* Assumptions: | ||
* - The transport header is entirely contained in the head iovec. | ||
*/ | ||
static int svc_rdma_xdr_decode_req(struct xdr_buf *rq_arg) | ||
{ | ||
__be32 *p, *end, *rdma_argp; | ||
unsigned int hdr_len; | ||
char *proc; | ||
|
||
/* Verify that there's enough bytes for header + something */ | ||
if (rq_arg->len <= RPCRDMA_HDRLEN_ERR) | ||
goto out_short; | ||
|
||
rdma_argp = rq_arg->head[0].iov_base; | ||
if (*(rdma_argp + 1) != rpcrdma_version) | ||
goto out_version; | ||
|
||
switch (*(rdma_argp + 3)) { | ||
case rdma_msg: | ||
proc = "RDMA_MSG"; | ||
break; | ||
case rdma_nomsg: | ||
proc = "RDMA_NOMSG"; | ||
break; | ||
|
||
case rdma_done: | ||
goto out_drop; | ||
|
||
case rdma_error: | ||
goto out_drop; | ||
|
||
default: | ||
goto out_proc; | ||
} | ||
|
||
end = (__be32 *)((unsigned long)rdma_argp + rq_arg->len); | ||
p = xdr_check_read_list(rdma_argp + 4, end); | ||
if (!p) | ||
goto out_inval; | ||
p = xdr_check_write_list(p, end); | ||
if (!p) | ||
goto out_inval; | ||
p = xdr_check_reply_chunk(p, end); | ||
if (!p) | ||
goto out_inval; | ||
if (p > end) | ||
goto out_inval; | ||
|
||
rq_arg->head[0].iov_base = p; | ||
hdr_len = (unsigned long)p - (unsigned long)rdma_argp; | ||
rq_arg->head[0].iov_len -= hdr_len; | ||
dprintk("svcrdma: received %s request for XID 0x%08x, hdr_len=%u\n", | ||
proc, be32_to_cpup(rdma_argp), hdr_len); | ||
return hdr_len; | ||
|
||
out_short: | ||
dprintk("svcrdma: header too short = %d\n", rq_arg->len); | ||
return -EINVAL; | ||
|
||
out_version: | ||
dprintk("svcrdma: bad xprt version: %u\n", | ||
be32_to_cpup(rdma_argp + 1)); | ||
return -EPROTONOSUPPORT; | ||
|
||
out_drop: | ||
dprintk("svcrdma: dropping RDMA_DONE/ERROR message\n"); | ||
return 0; | ||
|
||
out_proc: | ||
dprintk("svcrdma: bad rdma procedure (%u)\n", | ||
be32_to_cpup(rdma_argp + 3)); | ||
return -EINVAL; | ||
|
||
out_inval: | ||
dprintk("svcrdma: failed to parse transport header\n"); | ||
return -EINVAL; | ||
} | ||
|
||
/* Issue an RDMA_READ using the local lkey to map the data sink */ | ||
int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt, | ||
struct svc_rqst *rqstp, | ||
|