Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

svcrdma: Clean up svc_rdma_build_read_chunk()

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>

authored by

Chuck Lever and committed by
J. Bruce Fields
7075a867 afea5657

+5 -3
+5 -3
net/sunrpc/xprtrdma/svc_rdma_rw.c
··· 660 660 return -EIO; 661 661 } 662 662 663 + /* Walk the segments in the Read chunk starting at @p and construct 664 + * RDMA Read operations to pull the chunk to the server. 665 + */ 663 666 static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, 664 667 struct svc_rdma_read_info *info, 665 668 __be32 *p) 666 669 { 667 670 int ret; 668 671 672 + ret = -EINVAL; 669 673 info->ri_chunklen = 0; 670 - while (*p++ != xdr_zero) { 674 + while (*p++ != xdr_zero && be32_to_cpup(p++) == info->ri_position) { 671 675 u32 rs_handle, rs_length; 672 676 u64 rs_offset; 673 677 674 - if (be32_to_cpup(p++) != info->ri_position) 675 - break; 676 678 rs_handle = be32_to_cpup(p++); 677 679 rs_length = be32_to_cpup(p++); 678 680 p = xdr_decode_hyper(p, &rs_offset);