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:
Ingo Weinhold 2007-03-31 22:44:01 +00:00
parent 08e7fb4054
commit 57a860987a

View File

@ -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)); TRACE(("FILE VEC [%lu] length %Ld\n", fileVecIndex, fileLeft));
// process the complete fileVec
while (fileLeft > 0) { while (fileLeft > 0) {
iovec tempVecs[MAX_TEMP_IO_VECS]; 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); // assign what is left of the current fileVec to the tempVecs
tempVecs[0].iov_len = size; while (size < fileLeft && i < count
&& tempCount < MAX_TEMP_IO_VECS) {
if (size >= fileLeft) // try to satisfy one iovec per iteration (or as much as
vecOffset += size; // possible)
else
vecOffset = 0;
while (size < fileLeft && ++i < count
&& tempCount < MAX_TEMP_IO_VECS) {
TRACE(("fill vec %ld, offset = %lu, size = %lu\n", TRACE(("fill vec %ld, offset = %lu, size = %lu\n",
i, vecOffset, size)); i, vecOffset, size));
tempVecs[tempCount].iov_base = vecs[i].iov_base; // bytes left of the current iovec
size_t vecLeft = vecs[i].iov_len - vecOffset;
// is this iovec larger than the file_io_vec? if (vecLeft == 0) {
if (vecs[i].iov_len + size > fileLeft) { i++;
size += tempVecs[tempCount].iov_len vecOffset = 0;
= vecOffset = fileLeft - size; continue;
tempCount++;
break;
} }
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++; tempCount++;
size += tempVecSize;
vecOffset += tempVecSize;
} }
size_t bytes = size; 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) if (status < B_OK)
return status; return status;
totalSize += size; totalSize += bytes;
bytesLeft -= size; bytesLeft -= size;
fileOffset += size; fileOffset += size;
fileLeft -= size; fileLeft -= size;
//dprintf("-> file left = %Lu\n", fileLeft); //dprintf("-> file left = %Lu\n", fileLeft);
if (size != bytes) { if (size != bytes || i >= count) {
// there are no more bytes, let's bail out // there are no more bytes or iovecs, let's bail out
*_numBytes = totalSize; *_numBytes = totalSize;
return B_OK; return B_OK;
} }
} }
} }
*_numBytes = totalSize;
return B_OK; return B_OK;
} }