svcrdma: Clean up svc_rdma_build_read_chunk()
authorChuck Lever <chuck.lever@oracle.com>
Tue, 1 Aug 2017 16:00:14 +0000 (12:00 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 25 Aug 2017 02:13:50 +0000 (22:13 -0400)
Dan Carpenter <dan.carpenter@oracle.com> observed that the while()
loop in svc_rdma_build_read_chunk() does not document the assumption
that the loop interior is always executed at least once.

Defensive: the function now returns -EINVAL if this assumption
fails.

Suggested-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
net/sunrpc/xprtrdma/svc_rdma_rw.c

index 933f79b..1f34fae 100644 (file)
@@ -660,19 +660,21 @@ out_initerr:
        return -EIO;
 }
 
+/* Walk the segments in the Read chunk starting at @p and construct
+ * RDMA Read operations to pull the chunk to the server.
+ */
 static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp,
                                     struct svc_rdma_read_info *info,
                                     __be32 *p)
 {
        int ret;
 
+       ret = -EINVAL;
        info->ri_chunklen = 0;
-       while (*p++ != xdr_zero) {
+       while (*p++ != xdr_zero && be32_to_cpup(p++) == info->ri_position) {
                u32 rs_handle, rs_length;
                u64 rs_offset;
 
-               if (be32_to_cpup(p++) != info->ri_position)
-                       break;
                rs_handle = be32_to_cpup(p++);
                rs_length = be32_to_cpup(p++);
                p = xdr_decode_hyper(p, &rs_offset);