* 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
This commit is contained in:
Ingo Weinhold 2009-03-16 03:30:52 +00:00
parent 6747f715cf
commit 0c9a35e882

View File

@ -14,6 +14,9 @@
#include <NodeMonitor.h>
#include <AutoDeleter.h>
// 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);
}