A few more changes to pages_io():
* Added a few comments. * Simplified the nested while loops by dropping the special handling for the first iovec and restructuring the innermost loop. This also rules out the possibility of a zero-length temporary vec. IMHO the readability has improved quite a bit (YMMV :-). Hopefully without introducing new bugs; please review! * Corrected computation of totalSize in case less than size has been read/written. * Also set *_numBytes in case all fileVecs have been processed. Only relevant in case the request extends beyond the end of file. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20483 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
08e7fb4054
commit
57a860987a
53
src/system/kernel/cache/file_cache.cpp
vendored
53
src/system/kernel/cache/file_cache.cpp
vendored
@ -415,37 +415,41 @@ pages_io(file_cache_ref *ref, off_t offset, const iovec *vecs, size_t count,
|
||||
|
||||
TRACE(("FILE VEC [%lu] length %Ld\n", fileVecIndex, fileLeft));
|
||||
|
||||
// process the complete fileVec
|
||||
while (fileLeft > 0) {
|
||||
iovec tempVecs[MAX_TEMP_IO_VECS];
|
||||
uint32 tempCount = 1;
|
||||
uint32 tempCount = 0;
|
||||
|
||||
size = min_c(vecs[i].iov_len - vecOffset, fileLeft);
|
||||
// size tracks how much of what is left of the current fileVec
|
||||
// (fileLeft) has been assigned to tempVecs
|
||||
size = 0;
|
||||
|
||||
tempVecs[0].iov_base = (void *)((addr_t)vecs[i].iov_base + vecOffset);
|
||||
tempVecs[0].iov_len = size;
|
||||
|
||||
if (size >= fileLeft)
|
||||
vecOffset += size;
|
||||
else
|
||||
vecOffset = 0;
|
||||
|
||||
while (size < fileLeft && ++i < count
|
||||
&& tempCount < MAX_TEMP_IO_VECS) {
|
||||
// assign what is left of the current fileVec to the tempVecs
|
||||
while (size < fileLeft && i < count
|
||||
&& tempCount < MAX_TEMP_IO_VECS) {
|
||||
// try to satisfy one iovec per iteration (or as much as
|
||||
// possible)
|
||||
TRACE(("fill vec %ld, offset = %lu, size = %lu\n",
|
||||
i, vecOffset, size));
|
||||
|
||||
tempVecs[tempCount].iov_base = vecs[i].iov_base;
|
||||
|
||||
// is this iovec larger than the file_io_vec?
|
||||
if (vecs[i].iov_len + size > fileLeft) {
|
||||
size += tempVecs[tempCount].iov_len
|
||||
= vecOffset = fileLeft - size;
|
||||
tempCount++;
|
||||
break;
|
||||
// bytes left of the current iovec
|
||||
size_t vecLeft = vecs[i].iov_len - vecOffset;
|
||||
if (vecLeft == 0) {
|
||||
i++;
|
||||
vecOffset = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
size += tempVecs[tempCount].iov_len = vecs[i].iov_len;
|
||||
// actually available bytes
|
||||
size_t tempVecSize = min_c(vecLeft, fileLeft - size);
|
||||
|
||||
tempVecs[tempCount].iov_base
|
||||
= (void *)((addr_t)vecs[i].iov_base + vecOffset);
|
||||
tempVecs[tempCount].iov_len = tempVecSize;
|
||||
tempCount++;
|
||||
|
||||
size += tempVecSize;
|
||||
vecOffset += tempVecSize;
|
||||
}
|
||||
|
||||
size_t bytes = size;
|
||||
@ -459,20 +463,21 @@ pages_io(file_cache_ref *ref, off_t offset, const iovec *vecs, size_t count,
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
totalSize += size;
|
||||
totalSize += bytes;
|
||||
bytesLeft -= size;
|
||||
fileOffset += size;
|
||||
fileLeft -= size;
|
||||
//dprintf("-> file left = %Lu\n", fileLeft);
|
||||
|
||||
if (size != bytes) {
|
||||
// there are no more bytes, let's bail out
|
||||
if (size != bytes || i >= count) {
|
||||
// there are no more bytes or iovecs, let's bail out
|
||||
*_numBytes = totalSize;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*_numBytes = totalSize;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user