static status_t cd_write(void* cookie, off_t pos, const void* buffer, size_t* _length) { cd_handle* handle = (cd_handle*)cookie; size_t length = *_length; if (handle->info->capacity == 0) return B_DEV_NO_MEDIA; IORequest request; status_t status = request.Init(pos, (addr_t)buffer, length, true, 0); if (status != B_OK) return status; status = handle->info->io_scheduler->ScheduleRequest(&request); if (status != B_OK) return status; status = request.Wait(0, 0); if (status == B_OK) *_length = length; else dprintf("cd_write(): request.Wait() returned: %s\n", strerror(status)); return status; }
static status_t das_write(void* cookie, off_t pos, const void* buffer, size_t* _length) { das_handle* handle = (das_handle*)cookie; size_t length = *_length; IORequest request; status_t status = request.Init(pos, (void*)buffer, length, true, 0); if (status != B_OK) return status; status = handle->info->io_scheduler->ScheduleRequest(&request); if (status != B_OK) return status; status = request.Wait(0, 0); if (status == B_OK) *_length = length; else dprintf("das_write(): request.Wait() returned: %s\n", strerror(status)); return status; }
status_t vfs_asynchronous_write_pages(struct vnode* vnode, void* cookie, off_t pos, const generic_io_vec* vecs, size_t count, generic_size_t numBytes, uint32 flags, AsyncIOCallback* callback) { IORequest* request = IORequest::Create((flags & B_VIP_IO_REQUEST) != 0); if (request == NULL) { callback->IOFinished(B_NO_MEMORY, true, 0); return B_NO_MEMORY; } status_t status = request->Init(pos, vecs, count, numBytes, true, flags | B_DELETE_IO_REQUEST); if (status != B_OK) { delete request; callback->IOFinished(status, true, 0); return status; } request->SetFinishedCallback(&AsyncIOCallback::IORequestCallback, callback); return vfs_vnode_io(vnode, cookie, request); }
status_t IORequest::CreateSubRequest(off_t parentOffset, off_t offset, size_t length, IORequest*& _subRequest) { ASSERT(parentOffset >= fOffset && length <= fLength && parentOffset - fOffset <= fLength - length); // find start vec size_t vecOffset = parentOffset - fOffset; iovec* vecs = fBuffer->Vecs(); int32 vecCount = fBuffer->VecCount(); int32 startVec = 0; for (; startVec < vecCount; startVec++) { const iovec& vec = vecs[startVec]; if (vecOffset < vec.iov_len) break; vecOffset -= vec.iov_len; } // count vecs size_t currentVecOffset = vecOffset; int32 endVec = startVec; size_t remainingLength = length; for (; endVec < vecCount; endVec++) { const iovec& vec = vecs[endVec]; if (vec.iov_len - currentVecOffset >= remainingLength) break; remainingLength -= vec.iov_len - currentVecOffset; currentVecOffset = 0; } // create subrequest IORequest* subRequest = Create((fFlags & B_VIP_IO_REQUEST) != 0); if (subRequest == NULL) return B_NO_MEMORY; status_t error = subRequest->Init(offset, vecOffset, vecs + startVec, endVec - startVec + 1, length, fIsWrite, fFlags & ~B_DELETE_IO_REQUEST); if (error != B_OK) { delete subRequest; return error; } subRequest->fRelativeParentOffset = parentOffset - fOffset; subRequest->fTeam = fTeam; subRequest->fThread = fThread; _subRequest = subRequest; subRequest->SetParent(this); MutexLocker _(fLock); fChildren.Add(subRequest); fPendingChildren++; TRACE("IORequest::CreateSubRequest(): request: %p, subrequest: %p\n", this, subRequest); return B_OK; }