From 8af6418b5c35c7c7b4a008783ffde29448b01f99 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 19 Nov 2009 16:26:40 +0000 Subject: [PATCH] Implemented support for the recently introduced I/O request calls io_request_{offset,length}(), {read_from,write_to}_io_request(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34137 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel_add_on/KernelRequestHandler.cpp | 70 ++++++++++++++++ .../kernel_add_on/KernelRequestHandler.h | 4 + .../userlandfs/kernel_add_on/Volume.cpp | 29 +++++++ .../userlandfs/kernel_add_on/Volume.h | 4 + .../userlandfs/private/Requests.cpp | 24 ++++++ .../server/haiku/haiku_kernel_emu.cpp | 38 ++++++++- .../userlandfs/server/kernel_emu.cpp | 84 +++++++++++++++++++ .../userlandfs/server/kernel_emu.h | 4 + 8 files changed, 256 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp index c7fe751a3a..48ab78d3de 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp @@ -106,6 +106,10 @@ KernelRequestHandler::HandleRequest(Request* request) // I/O case DO_ITERATIVE_FD_IO_REQUEST: return _HandleRequest((DoIterativeFDIORequest*)request); + case READ_FROM_IO_REQUEST_REQUEST: + return _HandleRequest((ReadFromIORequestRequest*)request); + case WRITE_TO_IO_REQUEST_REQUEST: + return _HandleRequest((WriteToIORequestRequest*)request); case NOTIFY_IO_REQUEST_REQUEST: return _HandleRequest((NotifyIORequestRequest*)request); } @@ -747,6 +751,72 @@ KernelRequestHandler::_HandleRequest(DoIterativeFDIORequest* request) } +status_t +KernelRequestHandler::_HandleRequest(ReadFromIORequestRequest* request) +{ + // check the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + + size_t size = request->size; + + // allocate the reply + RequestAllocator allocator(fPort->GetPort()); + ReadFromIORequestReply* reply; + status_t error = AllocateRequest(allocator, &reply); + if (error != B_OK) + RETURN_ERROR(error); + + void* buffer; + if (result == B_OK) { + result = allocator.AllocateAddress(reply->buffer, size, 1, &buffer, + true); + } + + // execute the request + if (result == B_OK) + result = volume->ReadFromIORequest(request->request, buffer, size); + + // prepare the reply + reply->error = result; + + // send the reply + if (reply->error == B_OK && size > 0) { + SingleReplyRequestHandler handler(RECEIPT_ACK_REPLY); + return fPort->SendRequest(&allocator, &handler); + } + + return fPort->SendRequest(&allocator); +} + + +status_t +KernelRequestHandler::_HandleRequest(WriteToIORequestRequest* request) +{ + // check and execute the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + + if (result == B_OK) { + result = volume->WriteToIORequest(request->request, + request->buffer.GetData(), request->buffer.GetSize()); + } + + // prepare the reply + RequestAllocator allocator(fPort->GetPort()); + WriteToIORequestReply* reply; + status_t error = AllocateRequest(allocator, &reply); + if (error != B_OK) + return error; + reply->error = result; + + // send the reply + return fPort->SendRequest(&allocator); +} + + // _HandleRequest status_t KernelRequestHandler::_HandleRequest(NotifyIORequestRequest* request) diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h index 8b94df7992..cb1e4a7f5e 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h @@ -75,6 +75,10 @@ private: status_t _HandleRequest(FileCacheWriteRequest* request); // I/O status_t _HandleRequest(DoIterativeFDIORequest* request); + status_t _HandleRequest( + ReadFromIORequestRequest* request); + status_t _HandleRequest( + WriteToIORequestRequest* request); status_t _HandleRequest(NotifyIORequestRequest* request); status_t _GetVolume(dev_t id, Volume** volume); diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp index 73cfa12d1a..2d8e49cc2f 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp @@ -690,6 +690,32 @@ Volume::WriteFileCache(ino_t vnodeID, void* cookie, } +status_t +Volume::ReadFromIORequest(int32 requestID, void* buffer, size_t size) +{ + // get the request + io_request* request; + status_t error = _FindIORequest(requestID, &request); + if (error != B_OK) + RETURN_ERROR(error); + + return read_from_io_request(request, buffer, size); +} + + +status_t +Volume::WriteToIORequest(int32 requestID, const void* buffer, size_t size) +{ + // get the request + io_request* request; + status_t error = _FindIORequest(requestID, &request); + if (error != B_OK) + RETURN_ERROR(error); + + return write_to_io_request(request, buffer, size); +} + + // DoIterativeFDIO status_t Volume::DoIterativeFDIO(int fd, int32 requestID, void* clientCookie, @@ -838,6 +864,8 @@ Volume::Unmount() while (info != NULL) { IORequestInfo* nextInfo = info->structLink; delete info; + // TODO: We should probably also notify the request, if that + // hasn't happened yet. info = nextInfo; } delete fIORequestInfosByStruct; @@ -1199,6 +1227,7 @@ Volume::DoIO(void* _node, void* cookie, io_request* ioRequest) request->request = requestID; request->offset = ioRequest->Offset(); request->length = ioRequest->Length(); + request->isWrite = ioRequest->IsWrite(); // send the request KernelRequestHandler handler(this, DO_IO_REPLY); diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h index d7ab9ded49..d7ec67f9a2 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h @@ -75,6 +75,10 @@ public: status_t DoIterativeFDIO(int fd, int32 requestID, void* cookie, const file_io_vec* vecs, uint32 vecCount); + status_t ReadFromIORequest(int32 requestID, void* buffer, + size_t size); + status_t WriteToIORequest(int32 requestID, + const void* buffer, size_t size); status_t NotifyIORequest(int32 requestID, status_t status); diff --git a/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp b/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp index 67b35a556d..023fcc2288 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp @@ -313,6 +313,22 @@ FileCacheWriteRequest::GetAddressInfos(AddressInfo* infos, int32* count) return B_OK; } +// ReadFromIORequestReply +status_t +ReadFromIORequestReply::GetAddressInfos(AddressInfo* infos, int32* count) +{ + ADD_ADDRESS(buffer); + return B_OK; +} + +// WriteToIORequestRequest +status_t +WriteToIORequestRequest::GetAddressInfos(AddressInfo* infos, int32* count) +{ + ADD_ADDRESS(buffer); + return B_OK; +} + // #pragma mark - @@ -720,10 +736,14 @@ UserlandFSUtil::is_kernel_request(uint32 type) return true; // I/O case DO_ITERATIVE_FD_IO_REQUEST: + case READ_FROM_IO_REQUEST_REQUEST: + case WRITE_TO_IO_REQUEST_REQUEST: case NOTIFY_IO_REQUEST_REQUEST: return false; case DO_ITERATIVE_FD_IO_REPLY: case NOTIFY_IO_REQUEST_REPLY: + case READ_FROM_IO_REQUEST_REPLY: + case WRITE_TO_IO_REQUEST_REPLY: return true; // general reply @@ -964,9 +984,13 @@ UserlandFSUtil::is_userland_request(uint32 type) // I/O case DO_ITERATIVE_FD_IO_REQUEST: case NOTIFY_IO_REQUEST_REQUEST: + case READ_FROM_IO_REQUEST_REQUEST: + case WRITE_TO_IO_REQUEST_REQUEST: return true; case DO_ITERATIVE_FD_IO_REPLY: case NOTIFY_IO_REQUEST_REPLY: + case READ_FROM_IO_REQUEST_REPLY: + case WRITE_TO_IO_REQUEST_REPLY: return false; // general reply diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/haiku/haiku_kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/haiku/haiku_kernel_emu.cpp index 87ca31898b..ba8f6a7d35 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/haiku/haiku_kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/haiku/haiku_kernel_emu.cpp @@ -319,10 +319,46 @@ io_request_is_write(const io_request* request) } +off_t +io_request_offset(const io_request* request) +{ + return ((HaikuKernelIORequest*)request)->offset; +} + + +off_t +io_request_length(const io_request* request) +{ + return ((HaikuKernelIORequest*)request)->length; +} + + +status_t +read_from_io_request(io_request* _request, void* buffer, size_t size) +{ + HaikuKernelIORequest* request = (HaikuKernelIORequest*)_request; + + // send the request + return UserlandFS::KernelEmu::read_from_io_request(request->volume->GetID(), + request->id, buffer, size); +} + + +status_t +write_to_io_request(io_request* _request, const void* buffer, size_t size) +{ + HaikuKernelIORequest* request = (HaikuKernelIORequest*)_request; + + // send the request + return UserlandFS::KernelEmu::write_to_io_request(request->volume->GetID(), + request->id, buffer, size); +} + + void notify_io_request(io_request* _request, status_t status) { - HaikuKernelIORequest* request = (HaikuKernelIORequest*)request; + HaikuKernelIORequest* request = (HaikuKernelIORequest*)_request; // send the request UserlandFS::KernelEmu::notify_io_request(request->volume->GetID(), diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp index 7588582d6f..187ba7fc6c 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp @@ -890,6 +890,90 @@ UserlandFS::KernelEmu::do_iterative_fd_io(dev_t volumeID, int fd, } +status_t +UserlandFS::KernelEmu::read_from_io_request(dev_t volumeID, int32 requestID, + void* buffer, size_t size) +{ + // get the request port and the file system + RequestPort* port; + FileSystem* fileSystem; + status_t error = get_port_and_fs(&port, &fileSystem); + if (error != B_OK) + return error; + + // prepare the request + RequestAllocator allocator(port->GetPort()); + ReadFromIORequestRequest* request; + error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->nsid = volumeID; + request->request = requestID; + request->size = size; + + // send the request + UserlandRequestHandler handler(fileSystem, READ_FROM_IO_REQUEST_REPLY); + ReadFromIORequestReply* reply; + error = port->SendRequest(&allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + if (reply->error != B_OK) + return reply->error; + + memcpy(buffer, reply->buffer.GetData(), reply->buffer.GetSize()); + + // send receipt-ack + RequestAllocator receiptAckAllocator(port->GetPort()); + ReceiptAckReply* receiptAck; + if (AllocateRequest(receiptAckAllocator, &receiptAck) == B_OK) + port->SendRequest(&receiptAckAllocator); + + return B_OK; +} + + +status_t +UserlandFS::KernelEmu::write_to_io_request(dev_t volumeID, int32 requestID, + const void* buffer, size_t size) +{ + // get the request port and the file system + RequestPort* port; + FileSystem* fileSystem; + status_t error = get_port_and_fs(&port, &fileSystem); + if (error != B_OK) + return error; + + // prepare the request + RequestAllocator allocator(port->GetPort()); + WriteToIORequestRequest* request; + error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->nsid = volumeID; + request->request = requestID; + + error = allocator.AllocateData(request->buffer, buffer, size, 1, false); + if (error != B_OK) + return error; + + // send the request + UserlandRequestHandler handler(fileSystem, WRITE_TO_IO_REQUEST_REPLY); + FileCacheWriteReply* reply; + error = port->SendRequest(&allocator, &handler, (Request**)&reply); + if (error != B_OK) + return error; + RequestReleaser requestReleaser(port, reply); + + // process the reply + return reply->error; +} + + status_t UserlandFS::KernelEmu::notify_io_request(dev_t volumeID, int32 requestID, status_t status) diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h index 0bc3a2d580..a759c9437e 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h @@ -50,6 +50,10 @@ status_t file_cache_write(dev_t mountID, ino_t vnodeID, void *cookie, status_t do_iterative_fd_io(dev_t volumeID, int fd, int32 requestID, void* cookie, const file_io_vec* vecs, uint32 vecCount); +status_t read_from_io_request(dev_t volumeID, int32 requestID, void* buffer, + size_t size); +status_t write_to_io_request(dev_t volumeID, int32 requestID, const void* buffer, + size_t size); status_t notify_io_request(dev_t volumeID, int32 requestID, status_t status); void kernel_debugger(const char *message);