Пример #1
0
	status_t ReadData(io_request* request)
	{
		off_t offset = io_request_offset(request);
		size_t size = io_request_length(request);

		if (offset < 0 || (uint64)offset > fData->UncompressedSize())
			RETURN_ERROR(B_BAD_VALUE);

		size_t toRead = std::min((uint64)size,
			fData->UncompressedSize() - offset);

		if (toRead > 0) {
			IORequestOutput output(request);
			MutexLocker locker(fLock);
			status_t error = fReader->ReadDataToOutput(offset, toRead, &output);
			if (error != B_OK)
				RETURN_ERROR(error);
		}

		return B_OK;
	}
Пример #2
0
void
WorkQueue::JobIO(IORequestArgs* args)
{
	ASSERT(args != NULL);

	uint64 offset = io_request_offset(args->fRequest);
	uint64 length = io_request_length(args->fRequest);

	size_t bufferLength = min_c(MAX_BUFFER_SIZE, length);
	char* buffer = reinterpret_cast<char*>(malloc(bufferLength));
	if (buffer == NULL) {
		notify_io_request(args->fRequest, B_NO_MEMORY);
		args->fInode->EndAIOOp();
		return;
	}

	status_t result;
	if (io_request_is_write(args->fRequest)) {
		if (offset + length > args->fInode->MaxFileSize())
				length = args->fInode->MaxFileSize() - offset;

		uint64 position = 0;
		do {
			size_t size = 0;
			size_t thisBufferLength = min_c(bufferLength, length - position);

			result = read_from_io_request(args->fRequest, buffer,
				thisBufferLength);

			while (size < thisBufferLength && result == B_OK) {
				size_t bytesWritten = thisBufferLength - size;
				result = args->fInode->WriteDirect(NULL,
					offset + position + size, buffer + size, &bytesWritten);
				size += bytesWritten;
			}

			position += thisBufferLength;
		} while (position < length && result == B_OK);
	} else {
		bool eof = false;
		uint64 position = 0;
		do {
			size_t size = 0;
			size_t thisBufferLength = min_c(bufferLength, length - position);

			do {
				size_t bytesRead = thisBufferLength - size;
				result = args->fInode->ReadDirect(NULL,
					offset + position + size, buffer + size, &bytesRead, &eof);
				if (result != B_OK)
					break;

				result = write_to_io_request(args->fRequest, buffer + size,
					bytesRead);
				if (result != B_OK)
					break;

				size += bytesRead;
			} while (size < length && result == B_OK && !eof);

			position += thisBufferLength;
		} while (position < length && result == B_OK && !eof);
	}

	free(buffer);

	notify_io_request(args->fRequest, result);
	args->fInode->EndAIOOp();
}