static status_t synchronous_io(io_request* request, DoIO& io) { TRACE_RIO("[%" B_PRId32 "] synchronous_io(request: %p (offset: %" B_PRIdOFF ", length: %" B_PRIuGENADDR "))\n", find_thread(NULL), request, request->Offset(), request->Length()); IOBuffer* buffer = request->Buffer(); iovec vector; void* virtualVecCookie = NULL; off_t offset = request->Offset(); generic_size_t length = request->Length(); for (; length > 0 && buffer->GetNextVirtualVec(virtualVecCookie, vector) == B_OK;) { void* vecBase = (void*)(addr_t)vector.iov_base; size_t vecLength = min_c(vector.iov_len, length); TRACE_RIO("[%ld] I/O: offset: %lld, vecBase: %p, length: %lu\n", find_thread(NULL), offset, vecBase, vecLength); size_t transferred = vecLength; status_t error = io.IO(offset, vecBase, &transferred); if (error != B_OK) { TRACE_RIO("[%ld] I/O failed: %#lx\n", find_thread(NULL), error); buffer->FreeVirtualVecCookie(virtualVecCookie); request->SetStatusAndNotify(error); return error; } offset += transferred; length -= transferred; if (transferred != vecLength) break; } TRACE_RIO("[%ld] synchronous_io() succeeded\n", find_thread(NULL)); buffer->FreeVirtualVecCookie(virtualVecCookie); request->SetTransferredBytes(length > 0, request->Length() - length); request->SetStatusAndNotify(B_OK); return B_OK; }
static status_t do_synchronous_iterative_vnode_io(struct vnode* vnode, void* openCookie, io_request* request, iterative_io_get_vecs getVecs, iterative_io_finished finished, void* cookie) { IOBuffer* buffer = request->Buffer(); VnodeIO io(request->IsWrite(), vnode, openCookie); iovec vector; void* virtualVecCookie = NULL; off_t offset = request->Offset(); generic_size_t length = request->Length(); status_t error = B_OK; for (; error == B_OK && length > 0 && buffer->GetNextVirtualVec(virtualVecCookie, vector) == B_OK;) { uint8* vecBase = (uint8*)vector.iov_base; generic_size_t vecLength = min_c(vector.iov_len, length); while (error == B_OK && vecLength > 0) { file_io_vec fileVecs[8]; size_t fileVecCount = 8; error = getVecs(cookie, request, offset, vecLength, fileVecs, &fileVecCount); if (error != B_OK || fileVecCount == 0) break; for (size_t i = 0; i < fileVecCount; i++) { const file_io_vec& fileVec = fileVecs[i]; size_t toTransfer = min_c(fileVec.length, (off_t)length); size_t transferred = toTransfer; error = io.IO(fileVec.offset, vecBase, &transferred); if (error != B_OK) break; offset += transferred; length -= transferred; vecBase += transferred; vecLength -= transferred; if (transferred != toTransfer) break; } } } buffer->FreeVirtualVecCookie(virtualVecCookie); bool partial = length > 0; size_t bytesTransferred = request->Length() - length; request->SetTransferredBytes(partial, bytesTransferred); finished(cookie, request, error, partial, bytesTransferred); request->SetStatusAndNotify(error); return error; }