Beispiel #1
0
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;
}
Beispiel #2
0
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;
}