summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_rw.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c
index 8dae418d15b4..b4cb4f991235 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_rw.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c
@@ -1009,17 +1009,20 @@ static int svc_rdma_read_chunk_range(struct svc_rqst *rqstp,
const struct svc_rdma_segment *segment;
int ret;
+ if (!length)
+ return 0;
+
ret = -EINVAL;
pcl_for_each_segment(segment, chunk) {
struct svc_rdma_segment dummy;
- if (offset > segment->rs_length) {
+ if (offset >= segment->rs_length) {
offset -= segment->rs_length;
continue;
}
dummy.rs_handle = segment->rs_handle;
- dummy.rs_length = min_t(u32, length, segment->rs_length) - offset;
+ dummy.rs_length = min_t(u32, length, segment->rs_length - offset);
dummy.rs_offset = segment->rs_offset + offset;
ret = svc_rdma_build_read_segment(rqstp, head, &dummy);
@@ -1028,6 +1031,8 @@ static int svc_rdma_read_chunk_range(struct svc_rqst *rqstp,
head->rc_readbytes += dummy.rs_length;
length -= dummy.rs_length;
+ if (!length)
+ break;
offset = 0;
}
return ret;