From 7c17aa2eb0e9c6c42b49f4d617e17aaff2cea7c6 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 25 Oct 2010 23:05:00 -0400 Subject: [PATCH] Windows: Fix math error in rx_Writev processing LICENSE MIT Reviewed-on: http://gerrit.openafs.org/3148 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman (cherry picked from commit e848f3c2160745228e0f770f8daf4fffcca7507a) Change-Id: I5f31ae8500ace8e5a95f21510cb7c3eaae547aee Reviewed-on: http://gerrit.openafs.org/3152 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/WINNT/afsd/cm_dcache.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/WINNT/afsd/cm_dcache.c b/src/WINNT/afsd/cm_dcache.c index 75fb05c82..c9b1762a9 100644 --- a/src/WINNT/afsd/cm_dcache.c +++ b/src/WINNT/afsd/cm_dcache.c @@ -194,7 +194,7 @@ long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags, } if (code == 0) { - afs_uint32 buf_offset; + afs_uint32 buf_offset = 0, bytes_copied = 0; /* write the data from the the list of buffers */ qdp = NULL; @@ -210,7 +210,8 @@ long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags, break; } - for ( iov = voffset = vlen = 0; vlen < vbytes; vlen += wbytes) { + for ( iov = voffset = vlen = 0; + vlen < vbytes && iov < tnio; vlen += wbytes) { if (qdp == NULL) { qdp = biod.bufListEndp; buf_offset = offsetp->LowPart % cm_data.buf_blockSize; @@ -227,29 +228,42 @@ long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags, wbytes = cm_data.buf_blockSize - buf_offset; vleft = tiov[iov].iov_len - voffset; - while (wbytes > vleft) { + while (wbytes > vleft && iov < tnio) { memcpy(tiov[iov].iov_base + voffset, bufferp, vleft); + bytes_copied += vleft; vlen += vleft; wbytes -= vleft; bufferp += vleft; + buf_offset += vleft; iov++; voffset = 0; vleft = tiov[iov].iov_len; } - memcpy(tiov[iov].iov_base + voffset, bufferp, wbytes); - if (tiov[iov].iov_len == voffset + wbytes) { - iov++; - voffset = 0; - vleft = tiov[iov].iov_len; + if (iov < tnio) { + memcpy(tiov[iov].iov_base + voffset, bufferp, wbytes); + bytes_copied += wbytes; + if (tiov[iov].iov_len == voffset + wbytes) { + iov++; + voffset = 0; + vleft = (iov < tnio) ? tiov[iov].iov_len : 0; + } else { + voffset += wbytes; + vleft -= wbytes; + } + bufferp += wbytes; + buf_offset += wbytes; } else { - voffset += wbytes; - vleft -= wbytes; + voffset = vleft = 0; } - buf_offset += wbytes; } + osi_assertx(iov == tnio, "incorrect iov count"); + osi_assertx(vlen == vbytes, "bytes_copied != vbytes"); + osi_assertx(bufp->offset.QuadPart + buf_offset == biod.offset.QuadPart + bytes_copied, + "begin and end offsets don't match"); + temp = rx_Writev(rxcallp, tiov, tnio, vbytes); if (temp != vbytes) { osi_Log3(afsd_logp, "rx_Writev failed bp 0x%p, %d != %d", bufp, temp, vbytes); -- 2.39.5