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; }
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(); }