From 0c9a35e88281fad617eae5909d306aadf5d60e39 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 16 Mar 2009 03:30:52 +0000 Subject: [PATCH] * FileCacheReadRequest: Implemented work-around for the problem that file_cache_read() will reenter the file system which will overwrite the buffer associated with the port, so we can't allocate space in the buffer before calling it. * FileCacheWriteRequest still has a similar problem, though it's probably better to rethink the kernel-userland communication completely. BFS basically seems to work in userland, now. Didn't really test write operations though. They will probably run into problems due to the issue above. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29555 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel_add_on/KernelRequestHandler.cpp | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) 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 a64c884fda..e431d4a08d 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 @@ -14,6 +14,9 @@ #include +#include + + // VolumePutter class VolumePutter { public: @@ -644,6 +647,10 @@ KernelRequestHandler::_HandleRequest(FileCacheReadRequest* request) size_t size = request->size; +// TODO: Allocating the reply and the buffer first now would save an allocation +// and copying the buffer, but since Volume::ReadFileCache() will reenter the +// file system (io() hook) our allocation would be overwritten. +#if 0 // allocate the reply RequestAllocator allocator(fPort->GetPort()); FileCacheReadReply* reply; @@ -662,6 +669,31 @@ KernelRequestHandler::_HandleRequest(FileCacheReadRequest* request) result = volume->ReadFileCache(request->vnid, request->cookie, request->pos, buffer, &size); } +#else + // allocate a buffer + void* buffer = malloc(size); + // TODO: Limit size! + if (buffer == NULL) + result = B_NO_MEMORY; + MemoryDeleter _2(buffer); + + // execute the request + if (result == B_OK) { + result = volume->ReadFileCache(request->vnid, request->cookie, + request->pos, buffer, &size); + } + + // allocate the reply + RequestAllocator allocator(fPort->GetPort()); + FileCacheReadReply* reply; + status_t error = AllocateRequest(allocator, &reply); + if (error != B_OK) + RETURN_ERROR(error); + + error = allocator.AllocateData(reply->buffer, buffer, size, 1, false); + if (error != B_OK) + return error; +#endif // prepare the reply reply->error = result; @@ -689,6 +721,8 @@ KernelRequestHandler::_HandleRequest(FileCacheWriteRequest* request) size_t size = 0; if (result == B_OK) { size = request->buffer.GetSize(); +// TODO: WriteFileCache() will reenter the file system (io() hook) which will +// overwrite the request and the buffer! result = volume->WriteFileCache(request->vnid, request->cookie, request->pos, request->buffer.GetData(), &size); }