From 97b7c9a09199e3597c55bb03c4da1a0fb03c4c23 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 5 Mar 2009 21:10:43 +0000 Subject: [PATCH] Handle file cache related requests in the kernel. The actual calls to the file cache are missing yet -- requires some refactoring in Volume. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29402 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/userlandfs/private/Requests.h | 1 + .../kernel_add_on/KernelRequestHandler.cpp | 238 +++++++++++++++++- .../kernel_add_on/KernelRequestHandler.h | 8 + .../userlandfs/kernel_add_on/Volume.cpp | 65 +++++ .../userlandfs/kernel_add_on/Volume.h | 12 + .../userlandfs/server/kernel_emu.cpp | 6 +- 6 files changed, 315 insertions(+), 15 deletions(-) diff --git a/headers/private/userlandfs/private/Requests.h b/headers/private/userlandfs/private/Requests.h index 2e7fb80b97..b2e3f2692a 100644 --- a/headers/private/userlandfs/private/Requests.h +++ b/headers/private/userlandfs/private/Requests.h @@ -1678,6 +1678,7 @@ public: status_t GetAddressInfos(AddressInfo* infos, int32* count); Address buffer; + size_t bytesRead; }; // FileCacheWriteRequest 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 045b30b80c..919eb3c5b2 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 @@ -9,6 +9,7 @@ #include "KernelRequestHandler.h" #include "RequestPort.h" #include "Requests.h" +#include "SingleReplyRequestHandler.h" #include "Volume.h" #include @@ -84,6 +85,21 @@ KernelRequestHandler::HandleRequest(Request* request) return _HandleRequest((UnremoveVNodeRequest*)request); case GET_VNODE_REMOVED_REQUEST: return _HandleRequest((GetVNodeRemovedRequest*)request); + // file cache + case FILE_CACHE_CREATE_REQUEST: + return _HandleRequest((FileCacheCreateRequest*)request); + case FILE_CACHE_DELETE_REQUEST: + return _HandleRequest((FileCacheDeleteRequest*)request); + case FILE_CACHE_SET_ENABLED_REQUEST: + return _HandleRequest((FileCacheSetEnabledRequest*)request); + case FILE_CACHE_SET_SIZE_REQUEST: + return _HandleRequest((FileCacheSetSizeRequest*)request); + case FILE_CACHE_SYNC_REQUEST: + return _HandleRequest((FileCacheSyncRequest*)request); + case FILE_CACHE_READ_REQUEST: + return _HandleRequest((FileCacheReadRequest*)request); + case FILE_CACHE_WRITE_REQUEST: + return _HandleRequest((FileCacheWriteRequest*)request); } PRINT(("KernelRequestHandler::HandleRequest(): unexpected request: %lu\n", request->GetType())); @@ -97,7 +113,7 @@ request->GetType())); status_t KernelRequestHandler::_HandleRequest(NotifyListenerRequest* request) { - // check and executed the request + // check and execute the request status_t result = B_OK; if (fVolume && request->device != fVolume->GetID()) result = B_BAD_VALUE; @@ -210,7 +226,7 @@ KernelRequestHandler::_HandleRequest(NotifyListenerRequest* request) status_t KernelRequestHandler::_HandleRequest(NotifySelectEventRequest* request) { - // check and executed the request + // check and execute the request status_t result = B_OK; if (fFileSystem->KnowsSelectSyncEntry(request->sync)) { if (request->unspecifiedEvent) { @@ -244,7 +260,7 @@ KernelRequestHandler::_HandleRequest(NotifySelectEventRequest* request) status_t KernelRequestHandler::_HandleRequest(NotifyQueryRequest* request) { - // check and executed the request + // check and execute the request status_t result = B_OK; if (fVolume && request->device != fVolume->GetID()) result = B_BAD_VALUE; @@ -308,7 +324,7 @@ KernelRequestHandler::_HandleRequest(NotifyQueryRequest* request) status_t KernelRequestHandler::_HandleRequest(GetVNodeRequest* request) { - // check and executed the request + // check and execute the request Volume* volume = NULL; status_t result = _GetVolume(request->nsid, &volume); VolumePutter _(volume); @@ -331,7 +347,7 @@ KernelRequestHandler::_HandleRequest(GetVNodeRequest* request) status_t KernelRequestHandler::_HandleRequest(PutVNodeRequest* request) { - // check and executed the request + // check and execute the request Volume* volume = NULL; status_t result = _GetVolume(request->nsid, &volume); VolumePutter _(volume); @@ -353,7 +369,7 @@ KernelRequestHandler::_HandleRequest(PutVNodeRequest* request) status_t KernelRequestHandler::_HandleRequest(AcquireVNodeRequest* request) { - // check and executed the request + // check and execute the request Volume* volume = NULL; status_t result = _GetVolume(request->nsid, &volume); VolumePutter _(volume); @@ -377,7 +393,7 @@ KernelRequestHandler::_HandleRequest(AcquireVNodeRequest* request) status_t KernelRequestHandler::_HandleRequest(NewVNodeRequest* request) { - // check and executed the request + // check and execute the request Volume* volume = NULL; status_t result = _GetVolume(request->nsid, &volume); VolumePutter _(volume); @@ -398,7 +414,7 @@ KernelRequestHandler::_HandleRequest(NewVNodeRequest* request) status_t KernelRequestHandler::_HandleRequest(PublishVNodeRequest* request) { - // check and executed the request + // check and execute the request Volume* volume = NULL; status_t result = _GetVolume(request->nsid, &volume); VolumePutter _(volume); @@ -424,7 +440,7 @@ KernelRequestHandler::_HandleRequest(PublishVNodeRequest* request) status_t KernelRequestHandler::_HandleRequest(RemoveVNodeRequest* request) { - // check and executed the request + // check and execute the request Volume* volume = NULL; status_t result = _GetVolume(request->nsid, &volume); VolumePutter _(volume); @@ -445,7 +461,7 @@ KernelRequestHandler::_HandleRequest(RemoveVNodeRequest* request) status_t KernelRequestHandler::_HandleRequest(UnremoveVNodeRequest* request) { - // check and executed the request + // check and execute the request Volume* volume = NULL; status_t result = _GetVolume(request->nsid, &volume); VolumePutter _(volume); @@ -466,7 +482,7 @@ KernelRequestHandler::_HandleRequest(UnremoveVNodeRequest* request) status_t KernelRequestHandler::_HandleRequest(GetVNodeRemovedRequest* request) { - // check and executed the request + // check and execute the request Volume* volume = NULL; status_t result = _GetVolume(request->nsid, &volume); VolumePutter _(volume); @@ -488,6 +504,206 @@ KernelRequestHandler::_HandleRequest(GetVNodeRemovedRequest* request) return fPort->SendRequest(&allocator); } + +// _HandleRequest +status_t +KernelRequestHandler::_HandleRequest(FileCacheCreateRequest* request) +{ + // check and execute the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + + if (result == B_OK) + result = volume->CreateFileCache(request->vnid, request->size); + + // prepare the reply + RequestAllocator allocator(fPort->GetPort()); + FileCacheCreateReply* 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(FileCacheDeleteRequest* request) +{ + // check and execute the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + + if (result == B_OK) + result = volume->DeleteFileCache(request->vnid); + + // prepare the reply + RequestAllocator allocator(fPort->GetPort()); + FileCacheDeleteReply* 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(FileCacheSetEnabledRequest* request) +{ + // check and execute the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + + if (result == B_OK) + result = volume->SetFileCacheEnabled(request->vnid, request->enabled); + + // prepare the reply + RequestAllocator allocator(fPort->GetPort()); + FileCacheSetEnabledReply* 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(FileCacheSetSizeRequest* request) +{ + // check and execute the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + + if (result == B_OK) + result = volume->SetFileCacheSize(request->vnid, request->size); + + // prepare the reply + RequestAllocator allocator(fPort->GetPort()); + FileCacheSetSizeReply* 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(FileCacheSyncRequest* request) +{ + // check and execute the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + + if (result == B_OK) + result = volume->SyncFileCache(request->vnid); + + // prepare the reply + RequestAllocator allocator(fPort->GetPort()); + FileCacheSyncReply* 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(FileCacheReadRequest* 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()); + FileCacheReadReply* 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->ReadFileCache(request->vnid, request->cookie, + request->pos, buffer, &size); + } + + // prepare the reply + reply->error = result; + reply->bytesRead = size; + + // send the reply + if (reply->error == B_OK && reply->bytesRead > 0) { + SingleReplyRequestHandler handler(RECEIPT_ACK_REPLY); + return fPort->SendRequest(&allocator, &handler); + } + + return fPort->SendRequest(&allocator); +} + + +// _HandleRequest +status_t +KernelRequestHandler::_HandleRequest(FileCacheWriteRequest* request) +{ + // check and execute the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + + size_t size = 0; + if (result == B_OK) { + size = request->buffer.GetSize(); + result = volume->WriteFileCache(request->vnid, request->cookie, + request->pos, request->buffer.GetData(), &size); + } + + // prepare the reply + RequestAllocator allocator(fPort->GetPort()); + FileCacheWriteReply* reply; + status_t error = AllocateRequest(allocator, &reply); + if (error != B_OK) + return error; + reply->error = result; + reply->bytesWritten = size; + + // send the reply + return fPort->SendRequest(&allocator); +} + + // _GetVolume status_t KernelRequestHandler::_GetVolume(dev_t id, Volume** volume) 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 e3aa140bda..35168876b4 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 @@ -65,6 +65,14 @@ private: status_t _HandleRequest(RemoveVNodeRequest* request); status_t _HandleRequest(UnremoveVNodeRequest* request); status_t _HandleRequest(GetVNodeRemovedRequest* request); + // file cache + status_t _HandleRequest(FileCacheCreateRequest* request); + status_t _HandleRequest(FileCacheDeleteRequest* request); + status_t _HandleRequest(FileCacheSetEnabledRequest* request); + status_t _HandleRequest(FileCacheSetSizeRequest* request); + status_t _HandleRequest(FileCacheSyncRequest* request); + status_t _HandleRequest(FileCacheReadRequest* request); + status_t _HandleRequest(FileCacheWriteRequest* 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 32a83e18f3..d6fbf1e5df 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 @@ -240,6 +240,71 @@ PRINT(("get_vnode_removed(%ld, %lld, %p)\n", GetID(), vnid, removed)); } +// CreateFileCache +status_t +Volume::CreateFileCache(ino_t vnodeID, off_t size) +{ + // TODO: Implement! + return B_NOT_SUPPORTED; +} + + +// DeleteFileCache +status_t +Volume::DeleteFileCache(ino_t vnodeID) +{ + // TODO: Implement! + return B_NOT_SUPPORTED; +} + + +// SetFileCacheEnabled +status_t +Volume::SetFileCacheEnabled(ino_t vnodeID, bool enabled) +{ + // TODO: Implement! + return B_NOT_SUPPORTED; +} + + +// SetFileCacheSize +status_t +Volume::SetFileCacheSize(ino_t vnodeID, off_t size) +{ + // TODO: Implement! + return B_NOT_SUPPORTED; +} + + +// SyncFileCache +status_t +Volume::SyncFileCache(ino_t vnodeID) +{ + // TODO: Implement! + return B_NOT_SUPPORTED; +} + + +// ReadFileCache +status_t +Volume::ReadFileCache(ino_t vnodeID, void* cookie, + off_t offset, void* buffer, size_t* _size) +{ + // TODO: Implement! + return B_NOT_SUPPORTED; +} + + +// WriteFileCache +status_t +Volume::WriteFileCache(ino_t vnodeID, void* cookie, + off_t offset, const void *buffer, size_t *_size) +{ + // TODO: Implement! + return B_NOT_SUPPORTED; +} + + // #pragma mark - FS 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 28badd10ec..ae3ab579fc 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 @@ -57,6 +57,18 @@ public: status_t UnremoveVNode(ino_t vnid); status_t GetVNodeRemoved(ino_t vnid, bool* removed); + status_t CreateFileCache(ino_t vnodeID, off_t size); + status_t DeleteFileCache(ino_t vnodeID); + status_t SetFileCacheEnabled(ino_t vnodeID, + bool enabled); + status_t SetFileCacheSize(ino_t vnodeID, off_t size); + status_t SyncFileCache(ino_t vnodeID); + status_t ReadFileCache(ino_t vnodeID, void* cookie, + off_t offset, void* buffer, size_t* _size); + status_t WriteFileCache(ino_t vnodeID, void* cookie, + off_t offset, const void *buffer, + size_t *_size); + // FS status_t Mount(const char* device, uint32 flags, const char* parameters); 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 481ea06f42..34ea17351c 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 @@ -764,7 +764,6 @@ UserlandFS::KernelEmu::file_cache_read(dev_t mountID, ino_t vnodeID, request->nsid = mountID; request->vnid = vnodeID; request->cookie = cookie; - // TODO: cookie can only be NULL! request->pos = offset; request->size = *_size; @@ -780,7 +779,7 @@ UserlandFS::KernelEmu::file_cache_read(dev_t mountID, ino_t vnodeID, if (reply->error != B_OK) return reply->error; - if (reply->buffer.GetSize() > 0) { + if (reply->bytesRead > 0) { memcpy(bufferBase, reply->buffer.GetData(), reply->buffer.GetSize()); // send receipt-ack @@ -790,7 +789,7 @@ UserlandFS::KernelEmu::file_cache_read(dev_t mountID, ino_t vnodeID, port->SendRequest(&receiptAckAllocator); } - *_size = reply->buffer.GetSize(); + *_size = reply->bytesRead; return B_OK; } @@ -818,7 +817,6 @@ UserlandFS::KernelEmu::file_cache_write(dev_t mountID, ino_t vnodeID, request->nsid = mountID; request->vnid = vnodeID; request->cookie = cookie; - // TODO: cookie can only be NULL! request->pos = offset; error = allocator.AllocateData(request->buffer, buffer, *_size, 1, false);