DMAResource::TranslateNext(): Fixed several bugs that could cause too
many bytes to be read/written, which, among other things, could trigger an assert in the IORequest code: * In case of a partial (i.e. non-block-aligned) begin, transferLeft was not adjusted correctly. * The main loop was lacking a transferLeft check. * Main loop: When finally using a bounce buffer, the unrestricted vec length was used as base length for the bounce buffer. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27042 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
27a11ab8b0
commit
ff388d5189
@ -483,13 +483,21 @@ DMAResource::TranslateNext(IORequest* request, IOOperation* operation)
|
||||
|
||||
dmaLength += length;
|
||||
|
||||
vecOffset += length - partialBegin;
|
||||
size_t transferred = length - partialBegin;
|
||||
vecOffset += transferred;
|
||||
offset -= partialBegin;
|
||||
|
||||
if (transferLeft > transferred)
|
||||
transferLeft -= transferred;
|
||||
else
|
||||
transferLeft = 0;
|
||||
|
||||
TRACE(" partial begin, using bounce buffer: offset: %lld, length: "
|
||||
"%lu\n", offset, length);
|
||||
}
|
||||
|
||||
for (uint32 i = vecIndex; i < vecIndex + segmentCount;) {
|
||||
for (uint32 i = vecIndex;
|
||||
i < vecIndex + segmentCount && transferLeft > 0;) {
|
||||
if (dmaBuffer->VecCount() >= fRestrictions.max_segment_count)
|
||||
break;
|
||||
|
||||
@ -501,9 +509,10 @@ DMAResource::TranslateNext(IORequest* request, IOOperation* operation)
|
||||
}
|
||||
|
||||
addr_t base = (addr_t)vec.iov_base + vecOffset;
|
||||
size_t length = vec.iov_len - vecOffset;
|
||||
if (length > transferLeft)
|
||||
length = transferLeft;
|
||||
size_t maxLength = vec.iov_len - vecOffset;
|
||||
if (maxLength > transferLeft)
|
||||
maxLength = transferLeft;
|
||||
size_t length = maxLength;
|
||||
|
||||
// Cut the vec according to transfer size, segment size, and boundary.
|
||||
|
||||
@ -540,7 +549,7 @@ DMAResource::TranslateNext(IORequest* request, IOOperation* operation)
|
||||
|
||||
// If length is 0, use bounce buffer for complete vec.
|
||||
if (length == 0) {
|
||||
length = vec.iov_len - vecOffset;
|
||||
length = maxLength;
|
||||
useBounceBufferSize = length;
|
||||
TRACE(" vec %lu: 0 length, using bounce buffer: %lu\n", i,
|
||||
useBounceBufferSize);
|
||||
@ -567,7 +576,7 @@ DMAResource::TranslateNext(IORequest* request, IOOperation* operation)
|
||||
|
||||
dmaLength += length;
|
||||
vecOffset += length;
|
||||
transferLeft -= length;
|
||||
transferLeft -= min_c(length, transferLeft);
|
||||
}
|
||||
|
||||
// If we're writing partially, we always need to have a block sized bounce
|
||||
|
Loading…
Reference in New Issue
Block a user