old interface is completely done in userland ATM. It becomes more and more obvious that we probably need to provide the kernel add-on with a bit more information about what the client FS interface supports in the first place, so we can save unnecessary trips to the userland. Opening/closing attributes for a FS using the old style interface could be handled completely in the kernel add-on, for instance (even if we lose a bit of accuracy wrt to open modes etc.). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20258 a95241bf-73f2-0310-859d-f6bbb57e9c96
2192 lines
52 KiB
C++
2192 lines
52 KiB
C++
// UserlandRequestHandler.cpp
|
|
|
|
#include "UserlandRequestHandler.h"
|
|
|
|
#include "AutoDeleter.h"
|
|
#include "Compatibility.h"
|
|
#include "Debug.h"
|
|
#include "FileSystem.h"
|
|
#include "RequestPort.h"
|
|
#include "Requests.h"
|
|
#include "RequestThread.h"
|
|
#include "SingleReplyRequestHandler.h"
|
|
#include "Volume.h"
|
|
|
|
// constructor
|
|
UserlandRequestHandler::UserlandRequestHandler(FileSystem* fileSystem)
|
|
: RequestHandler(),
|
|
fFileSystem(fileSystem),
|
|
fExpectReply(false),
|
|
fExpectedReply(0)
|
|
{
|
|
}
|
|
|
|
// constructor
|
|
UserlandRequestHandler::UserlandRequestHandler(FileSystem* fileSystem,
|
|
uint32 expectedReply)
|
|
: RequestHandler(),
|
|
fFileSystem(fileSystem),
|
|
fExpectReply(true),
|
|
fExpectedReply(expectedReply)
|
|
{
|
|
}
|
|
|
|
// destructor
|
|
UserlandRequestHandler::~UserlandRequestHandler()
|
|
{
|
|
}
|
|
|
|
// HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::HandleRequest(Request* request)
|
|
{
|
|
if (fExpectReply && request->GetType() == fExpectedReply) {
|
|
fDone = true;
|
|
return B_OK;
|
|
}
|
|
switch (request->GetType()) {
|
|
// FS
|
|
case MOUNT_VOLUME_REQUEST:
|
|
return _HandleRequest((MountVolumeRequest*)request);
|
|
case UNMOUNT_VOLUME_REQUEST:
|
|
return _HandleRequest((UnmountVolumeRequest*)request);
|
|
case SYNC_VOLUME_REQUEST:
|
|
return _HandleRequest((SyncVolumeRequest*)request);
|
|
case READ_FS_INFO_REQUEST:
|
|
return _HandleRequest((ReadFSInfoRequest*)request);
|
|
case WRITE_FS_INFO_REQUEST:
|
|
return _HandleRequest((WriteFSInfoRequest*)request);
|
|
|
|
// vnodes
|
|
case LOOKUP_REQUEST:
|
|
return _HandleRequest((LookupRequest*)request);
|
|
case READ_VNODE_REQUEST:
|
|
return _HandleRequest((ReadVNodeRequest*)request);
|
|
case WRITE_VNODE_REQUEST:
|
|
return _HandleRequest((WriteVNodeRequest*)request);
|
|
case FS_REMOVE_VNODE_REQUEST:
|
|
return _HandleRequest((FSRemoveVNodeRequest*)request);
|
|
|
|
// nodes
|
|
case IOCTL_REQUEST:
|
|
return _HandleRequest((IOCtlRequest*)request);
|
|
case SET_FLAGS_REQUEST:
|
|
return _HandleRequest((SetFlagsRequest*)request);
|
|
case SELECT_REQUEST:
|
|
return _HandleRequest((SelectRequest*)request);
|
|
case DESELECT_REQUEST:
|
|
return _HandleRequest((DeselectRequest*)request);
|
|
case FSYNC_REQUEST:
|
|
return _HandleRequest((FSyncRequest*)request);
|
|
case READ_SYMLINK_REQUEST:
|
|
return _HandleRequest((ReadSymlinkRequest*)request);
|
|
case CREATE_SYMLINK_REQUEST:
|
|
return _HandleRequest((CreateSymlinkRequest*)request);
|
|
case LINK_REQUEST:
|
|
return _HandleRequest((LinkRequest*)request);
|
|
case UNLINK_REQUEST:
|
|
return _HandleRequest((UnlinkRequest*)request);
|
|
case RENAME_REQUEST:
|
|
return _HandleRequest((RenameRequest*)request);
|
|
case ACCESS_REQUEST:
|
|
return _HandleRequest((AccessRequest*)request);
|
|
case READ_STAT_REQUEST:
|
|
return _HandleRequest((ReadStatRequest*)request);
|
|
case WRITE_STAT_REQUEST:
|
|
return _HandleRequest((WriteStatRequest*)request);
|
|
|
|
// files
|
|
case CREATE_REQUEST:
|
|
return _HandleRequest((CreateRequest*)request);
|
|
case OPEN_REQUEST:
|
|
return _HandleRequest((OpenRequest*)request);
|
|
case CLOSE_REQUEST:
|
|
return _HandleRequest((CloseRequest*)request);
|
|
case FREE_COOKIE_REQUEST:
|
|
return _HandleRequest((FreeCookieRequest*)request);
|
|
case READ_REQUEST:
|
|
return _HandleRequest((ReadRequest*)request);
|
|
case WRITE_REQUEST:
|
|
return _HandleRequest((WriteRequest*)request);
|
|
|
|
// directories
|
|
case CREATE_DIR_REQUEST:
|
|
return _HandleRequest((CreateDirRequest*)request);
|
|
case REMOVE_DIR_REQUEST:
|
|
return _HandleRequest((RemoveDirRequest*)request);
|
|
case OPEN_DIR_REQUEST:
|
|
return _HandleRequest((OpenDirRequest*)request);
|
|
case CLOSE_DIR_REQUEST:
|
|
return _HandleRequest((CloseDirRequest*)request);
|
|
case FREE_DIR_COOKIE_REQUEST:
|
|
return _HandleRequest((FreeDirCookieRequest*)request);
|
|
case READ_DIR_REQUEST:
|
|
return _HandleRequest((ReadDirRequest*)request);
|
|
case REWIND_DIR_REQUEST:
|
|
return _HandleRequest((RewindDirRequest*)request);
|
|
|
|
// attribute directories
|
|
case OPEN_ATTR_DIR_REQUEST:
|
|
return _HandleRequest((OpenAttrDirRequest*)request);
|
|
case CLOSE_ATTR_DIR_REQUEST:
|
|
return _HandleRequest((CloseAttrDirRequest*)request);
|
|
case FREE_ATTR_DIR_COOKIE_REQUEST:
|
|
return _HandleRequest((FreeAttrDirCookieRequest*)request);
|
|
case READ_ATTR_DIR_REQUEST:
|
|
return _HandleRequest((ReadAttrDirRequest*)request);
|
|
case REWIND_ATTR_DIR_REQUEST:
|
|
return _HandleRequest((RewindAttrDirRequest*)request);
|
|
|
|
// attributes
|
|
case CREATE_ATTR_REQUEST:
|
|
return _HandleRequest((CreateAttrRequest*)request);
|
|
case OPEN_ATTR_REQUEST:
|
|
return _HandleRequest((OpenAttrRequest*)request);
|
|
case CLOSE_ATTR_REQUEST:
|
|
return _HandleRequest((CloseAttrRequest*)request);
|
|
case FREE_ATTR_COOKIE_REQUEST:
|
|
return _HandleRequest((FreeAttrCookieRequest*)request);
|
|
case READ_ATTR_REQUEST:
|
|
return _HandleRequest((ReadAttrRequest*)request);
|
|
case WRITE_ATTR_REQUEST:
|
|
return _HandleRequest((WriteAttrRequest*)request);
|
|
case READ_ATTR_STAT_REQUEST:
|
|
return _HandleRequest((ReadAttrStatRequest*)request);
|
|
case RENAME_ATTR_REQUEST:
|
|
return _HandleRequest((RenameAttrRequest*)request);
|
|
case REMOVE_ATTR_REQUEST:
|
|
return _HandleRequest((RemoveAttrRequest*)request);
|
|
|
|
// indices
|
|
case OPEN_INDEX_DIR_REQUEST:
|
|
return _HandleRequest((OpenIndexDirRequest*)request);
|
|
case CLOSE_INDEX_DIR_REQUEST:
|
|
return _HandleRequest((CloseIndexDirRequest*)request);
|
|
case FREE_INDEX_DIR_COOKIE_REQUEST:
|
|
return _HandleRequest((FreeIndexDirCookieRequest*)request);
|
|
case READ_INDEX_DIR_REQUEST:
|
|
return _HandleRequest((ReadIndexDirRequest*)request);
|
|
case REWIND_INDEX_DIR_REQUEST:
|
|
return _HandleRequest((RewindIndexDirRequest*)request);
|
|
case CREATE_INDEX_REQUEST:
|
|
return _HandleRequest((CreateIndexRequest*)request);
|
|
case REMOVE_INDEX_REQUEST:
|
|
return _HandleRequest((RemoveIndexRequest*)request);
|
|
case READ_INDEX_STAT_REQUEST:
|
|
return _HandleRequest((ReadIndexStatRequest*)request);
|
|
|
|
// queries
|
|
case OPEN_QUERY_REQUEST:
|
|
return _HandleRequest((OpenQueryRequest*)request);
|
|
case CLOSE_QUERY_REQUEST:
|
|
return _HandleRequest((CloseQueryRequest*)request);
|
|
case FREE_QUERY_COOKIE_REQUEST:
|
|
return _HandleRequest((FreeQueryCookieRequest*)request);
|
|
case READ_QUERY_REQUEST:
|
|
return _HandleRequest((ReadQueryRequest*)request);
|
|
}
|
|
PRINT(("UserlandRequestHandler::HandleRequest(): unexpected request: %lu\n",
|
|
request->GetType()));
|
|
return B_BAD_DATA;
|
|
}
|
|
|
|
|
|
// #pragma mark - FS
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(MountVolumeRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
|
|
// if the device path is relative, make it absolute by appending the
|
|
// provided CWD
|
|
const char* device = (const char*)request->device.GetData();
|
|
char stackDevice[B_PATH_NAME_LENGTH];
|
|
if (result == B_OK) {
|
|
if (device && device[0] != '/') {
|
|
if (const char* cwd = (const char*)request->cwd.GetData()) {
|
|
int32 deviceLen = strlen(device);
|
|
int32 cwdLen = strlen(cwd);
|
|
if (cwdLen + 1 + deviceLen < (int32)sizeof(stackDevice)) {
|
|
strcpy(stackDevice, cwd);
|
|
strcat(stackDevice, "/");
|
|
strcat(stackDevice, device);
|
|
device = stackDevice;
|
|
} else
|
|
result = B_NAME_TOO_LONG;
|
|
} else
|
|
result = B_BAD_VALUE;
|
|
}
|
|
}
|
|
|
|
// create the volume
|
|
Volume* volume = NULL;
|
|
if (result == B_OK)
|
|
result = fFileSystem->CreateVolume(&volume, request->nsid);
|
|
|
|
// mount it
|
|
vnode_id rootID;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Mount(device, request->flags,
|
|
(const char*)request->parameters.GetData(), &rootID);
|
|
if (result != B_OK)
|
|
fFileSystem->DeleteVolume(volume);
|
|
}
|
|
if (result != B_OK)
|
|
volume = NULL;
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
MountVolumeReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
reply->error = result;
|
|
reply->volume = volume;
|
|
reply->rootID = rootID;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(UnmountVolumeRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Unmount();
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
UnmountVolumeReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(SyncVolumeRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Sync();
|
|
}
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
SyncVolumeReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadFSInfoRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
fs_info info;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadFSInfo(&info);
|
|
}
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadFSInfoReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
reply->error = result;
|
|
reply->info = info;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(WriteFSInfoRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->WriteFSInfo(&request->info, request->mask);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
WriteFSInfoReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
|
|
// #pragma mark - vnodes
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(LookupRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
vnode_id vnid = 0;
|
|
int type = 0;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Lookup(request->node,
|
|
(const char*)request->entryName.GetData(), &vnid, &type);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
LookupReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->vnid = vnid;
|
|
reply->type = type;
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadVNodeRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_vnode node;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadVNode(request->vnid, request->reenter, &node);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadVNodeReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->node = node;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(WriteVNodeRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->WriteVNode(request->node, request->reenter);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
WriteVNodeReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(FSRemoveVNodeRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->RemoveVNode(request->node, request->reenter);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
FSRemoveVNodeReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
|
|
// #pragma mark - nodes
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(IOCtlRequest* request)
|
|
{
|
|
// get the request parameters
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
void* buffer = request->bufferParameter;
|
|
size_t len = request->lenParameter;
|
|
bool isBuffer = request->isBuffer;
|
|
int32 bufferSize = 0;
|
|
int32 writeSize = request->writeSize;
|
|
if (isBuffer) {
|
|
buffer = request->buffer.GetData();
|
|
bufferSize = request->buffer.GetSize();
|
|
}
|
|
|
|
// allocate the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
IOCtlReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
// allocate the writable buffer for the call
|
|
void* writeBuffer = NULL;
|
|
if (result == B_OK && isBuffer && writeSize > 0) {
|
|
if (writeSize < bufferSize)
|
|
writeSize = bufferSize;
|
|
result = allocator.AllocateAddress(reply->buffer, writeSize, 8,
|
|
(void**)&writeBuffer, true);
|
|
if (result == B_OK && bufferSize > 0)
|
|
memcpy(writeBuffer, buffer, bufferSize);
|
|
buffer = writeBuffer;
|
|
}
|
|
|
|
// execute the request
|
|
status_t ioctlError = B_OK;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
ioctlError = volume->IOCtl(request->node, request->fileCookie,
|
|
request->command, buffer, len);
|
|
}
|
|
|
|
// reconstruct the reply, in case it has been overwritten
|
|
reply = new(reply) IOCtlReply;
|
|
|
|
// send the reply
|
|
reply->error = result;
|
|
reply->ioctlError = ioctlError;
|
|
return _SendReply(allocator, (result == B_OK && writeBuffer));
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(SetFlagsRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->SetFlags(request->node, request->fileCookie,
|
|
request->flags);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
SetFlagsReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(SelectRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Select(request->node, request->fileCookie,
|
|
request->event, request->ref, request->sync);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
SelectReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(DeselectRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Deselect(request->node, request->fileCookie,
|
|
request->event, request->sync);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
DeselectReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(FSyncRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->FSync(request->node);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
FSyncReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadSymlinkRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
void* node = request->node;
|
|
size_t bufferSize = request->size;
|
|
|
|
// allocate the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadSymlinkReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
char* buffer;
|
|
if (result == B_OK) {
|
|
result = allocator.AllocateAddress(reply->buffer, bufferSize, 1,
|
|
(void**)&buffer, true);
|
|
}
|
|
|
|
// execute the request
|
|
size_t bytesRead;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadSymlink(node, buffer, bufferSize, &bytesRead);
|
|
}
|
|
|
|
// reconstruct the reply, in case it has been overwritten
|
|
reply = new(reply) ReadSymlinkReply;
|
|
|
|
// send the reply
|
|
reply->error = result;
|
|
reply->bytesRead = bytesRead;
|
|
return _SendReply(allocator, (result == B_OK));
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CreateSymlinkRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CreateSymlink(request->node,
|
|
(const char*)request->name.GetData(),
|
|
(const char*)request->target.GetData(), request->mode);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CreateSymlinkReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(LinkRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Link(request->node,
|
|
(const char*)request->name.GetData(), request->target);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
LinkReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(UnlinkRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Unlink(request->node,
|
|
(const char*)request->name.GetData());
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
UnlinkReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(RenameRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Rename(request->oldDir,
|
|
(const char*)request->oldName.GetData(), request->newDir,
|
|
(const char*)request->newName.GetData());
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
RenameReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(AccessRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Access(request->node, request->mode);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
AccessReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadStatRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
struct stat st;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadStat(request->node, &st);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadStatReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->st = st;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(WriteStatRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->WriteStat(request->node, &request->st, request->mask);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
WriteStatReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
|
|
// #pragma mark - files
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CreateRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
vnode_id vnid;
|
|
fs_cookie fileCookie;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Create(request->node,
|
|
(const char*)request->name.GetData(), request->openMode,
|
|
request->mode, &fileCookie, &vnid);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CreateReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->vnid = vnid;
|
|
reply->fileCookie = fileCookie;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(OpenRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie fileCookie;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Open(request->node, request->openMode, &fileCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
OpenReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->fileCookie = fileCookie;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CloseRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Close(request->node, request->fileCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CloseReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(FreeCookieRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->FreeCookie(request->node, request->fileCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
FreeCookieReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_vnode node = request->node;
|
|
fs_cookie fileCookie = request->fileCookie;
|
|
off_t pos = request->pos;
|
|
size_t size = request->size;
|
|
|
|
// allocate the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadReply* 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
|
|
size_t bytesRead;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Read(node, fileCookie, pos, buffer, size, &bytesRead);
|
|
}
|
|
|
|
// reconstruct the reply, in case it has been overwritten
|
|
reply = new(reply) ReadReply;
|
|
|
|
// send the reply
|
|
reply->error = result;
|
|
reply->bytesRead = bytesRead;
|
|
return _SendReply(allocator, (result == B_OK));
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(WriteRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
size_t bytesWritten;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->Write(request->node, request->fileCookie,
|
|
request->pos, request->buffer.GetData(), request->buffer.GetSize(),
|
|
&bytesWritten);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
WriteReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->bytesWritten = bytesWritten;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
|
|
// #pragma mark - directories
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CreateDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
vnode_id newDir = 0;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CreateDir(request->node,
|
|
(const char*)request->name.GetData(), request->mode, &newDir);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CreateDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->newDir = newDir;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(RemoveDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->RemoveDir(request->node,
|
|
(const char*)request->name.GetData());
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
RemoveDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(OpenDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie dirCookie = NULL;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->OpenDir(request->node, &dirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
OpenDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->dirCookie = dirCookie;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CloseDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CloseDir(request->node, request->dirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CloseDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(FreeDirCookieRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->FreeDirCookie(request->node, request->dirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
FreeDirCookieReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadDirRequest* request)
|
|
{
|
|
// check the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_vnode node = request->node;
|
|
fs_vnode dirCookie = request->dirCookie;
|
|
size_t bufferSize = request->bufferSize;
|
|
uint32 count = request->count;
|
|
|
|
// allocate the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadDirReply* 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, bufferSize, 1,
|
|
&buffer, true);
|
|
}
|
|
|
|
// execute the request
|
|
uint32 countRead;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadDir(node, dirCookie, buffer, bufferSize, count,
|
|
&countRead);
|
|
}
|
|
|
|
D(
|
|
if (result == B_OK && countRead > 0) {
|
|
dirent* entry = (dirent*)buffer;
|
|
PRINT((" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld, d_pino: %Ld, "
|
|
"d_reclen: %hu, d_name: %.32s\n",
|
|
entry->d_dev, entry->d_pdev, entry->d_ino, entry->d_pino,
|
|
entry->d_reclen, entry->d_name));
|
|
}
|
|
)
|
|
|
|
// reconstruct the reply, in case it has been overwritten
|
|
reply = new(reply) ReadDirReply;
|
|
|
|
// send the reply
|
|
reply->error = result;
|
|
reply->count = countRead;
|
|
return _SendReply(allocator, (result == B_OK));
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(RewindDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->RewindDir(request->node, request->dirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
RewindDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
|
|
// #pragma mark - attribute directories
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(OpenAttrDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie attrDirCookie;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->OpenAttrDir(request->node, &attrDirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
OpenAttrDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->attrDirCookie = attrDirCookie;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CloseAttrDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CloseAttrDir(request->node, request->attrDirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CloseAttrDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(FreeAttrDirCookieRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->FreeAttrDirCookie(request->node,
|
|
request->attrDirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
FreeAttrDirCookieReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadAttrDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_vnode node = request->node;
|
|
fs_cookie attrDirCookie = request->attrDirCookie;
|
|
size_t bufferSize = request->bufferSize;
|
|
uint32 count = request->count;
|
|
|
|
// allocate the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadAttrDirReply* 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, bufferSize, 1,
|
|
&buffer, true);
|
|
}
|
|
|
|
// execute the request
|
|
uint32 countRead;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadAttrDir(node, attrDirCookie, buffer, bufferSize,
|
|
count, &countRead);
|
|
}
|
|
|
|
// reconstruct the reply, in case it has been overwritten
|
|
reply = new(reply) ReadAttrDirReply;
|
|
|
|
// send the reply
|
|
reply->error = result;
|
|
reply->count = countRead;
|
|
return _SendReply(allocator, (result == B_OK));
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(RewindAttrDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->RewindAttrDir(request->node, request->attrDirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
RewindAttrDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
|
|
// #pragma mark - attributes
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CreateAttrRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie attrCookie;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CreateAttr(request->node,
|
|
(const char*)request->name.GetData(), request->type,
|
|
request->openMode, &attrCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CreateAttrReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->attrCookie = attrCookie;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(OpenAttrRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie attrCookie;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->OpenAttr(request->node,
|
|
(const char*)request->name.GetData(), request->openMode,
|
|
&attrCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
OpenAttrReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->attrCookie = attrCookie;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CloseAttrRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CloseAttr(request->node, request->attrCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CloseAttrReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(FreeAttrCookieRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->FreeAttrCookie(request->node, request->attrCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
FreeAttrCookieReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadAttrRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
void* node = request->node;
|
|
fs_cookie attrCookie = request->attrCookie;
|
|
off_t pos = request->pos;
|
|
size_t size = request->size;
|
|
|
|
// allocate the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadAttrReply* 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
|
|
size_t bytesRead;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadAttr(node, attrCookie, pos, buffer, size,
|
|
&bytesRead);
|
|
}
|
|
|
|
// reconstruct the reply, in case it has been overwritten
|
|
reply = new(reply) ReadAttrReply;
|
|
|
|
// send the reply
|
|
reply->error = result;
|
|
reply->bytesRead = bytesRead;
|
|
return _SendReply(allocator, (result == B_OK));
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(WriteAttrRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
size_t bytesWritten;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->WriteAttr(request->node, request->attrCookie,
|
|
request->pos, request->buffer.GetData(), request->buffer.GetSize(),
|
|
&bytesWritten);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
WriteAttrReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->bytesWritten = bytesWritten;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadAttrStatRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
struct stat st;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadAttrStat(request->node, request->attrCookie,
|
|
&st);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadAttrStatReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->st = st;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(RenameAttrRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->RenameAttr(
|
|
request->oldNode, (const char*)request->oldName.GetData(),
|
|
request->newNode, (const char*)request->newName.GetData());
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
RenameAttrReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(RemoveAttrRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->RemoveAttr(request->node,
|
|
(const char*)request->name.GetData());
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
RemoveAttrReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
|
|
// #pragma mark - indices
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(OpenIndexDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie indexDirCookie;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->OpenIndexDir(&indexDirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
OpenIndexDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->indexDirCookie = indexDirCookie;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CloseIndexDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CloseIndexDir(request->indexDirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CloseIndexDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(FreeIndexDirCookieRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->FreeIndexDirCookie(request->indexDirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
FreeIndexDirCookieReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadIndexDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie indexDirCookie = request->indexDirCookie;
|
|
size_t bufferSize = request->bufferSize;
|
|
uint32 count = request->count;
|
|
|
|
// allocate the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadIndexDirReply* 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, bufferSize, 1,
|
|
&buffer, true);
|
|
}
|
|
|
|
// execute the request
|
|
uint32 countRead;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadIndexDir(indexDirCookie, buffer, bufferSize,
|
|
count, &countRead);
|
|
}
|
|
|
|
// reconstruct the reply, in case it has been overwritten
|
|
reply = new(reply) ReadIndexDirReply;
|
|
|
|
// send the reply
|
|
reply->error = result;
|
|
reply->count = countRead;
|
|
return _SendReply(allocator, (result == B_OK));
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(RewindIndexDirRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->RewindIndexDir(request->indexDirCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
RewindIndexDirReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CreateIndexRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CreateIndex((const char*)request->name.GetData(),
|
|
request->type, request->flags);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CreateIndexReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(RemoveIndexRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->RemoveIndex((const char*)request->name.GetData());
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
RemoveIndexReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadIndexStatRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
struct stat st;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadIndexStat((const char*)request->name.GetData(),
|
|
&st);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadIndexStatReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->st = st;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
|
|
// #pragma mark - queries
|
|
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(OpenQueryRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie queryCookie;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->OpenQuery((const char*)request->queryString.GetData(),
|
|
request->flags, request->port, request->token, &queryCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
OpenQueryReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
reply->queryCookie = queryCookie;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(CloseQueryRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->CloseQuery(request->queryCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
CloseQueryReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(FreeQueryCookieRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->FreeQueryCookie(request->queryCookie);
|
|
}
|
|
|
|
// prepare the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
FreeQueryCookieReply* reply;
|
|
status_t error = AllocateRequest(allocator, &reply);
|
|
if (error != B_OK)
|
|
RETURN_ERROR(error);
|
|
|
|
reply->error = result;
|
|
|
|
// send the reply
|
|
return _SendReply(allocator, false);
|
|
}
|
|
|
|
// _HandleRequest
|
|
status_t
|
|
UserlandRequestHandler::_HandleRequest(ReadQueryRequest* request)
|
|
{
|
|
// check and execute the request
|
|
status_t result = B_OK;
|
|
Volume* volume = (Volume*)request->volume;
|
|
if (!volume)
|
|
result = B_BAD_VALUE;
|
|
|
|
fs_cookie queryCookie = request->queryCookie;
|
|
size_t bufferSize = request->bufferSize;
|
|
uint32 count = request->count;
|
|
|
|
// allocate the reply
|
|
RequestAllocator allocator(fPort->GetPort());
|
|
ReadQueryReply* 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, bufferSize, 1,
|
|
&buffer, true);
|
|
}
|
|
|
|
// execute the request
|
|
uint32 countRead;
|
|
if (result == B_OK) {
|
|
RequestThreadContext context(volume);
|
|
result = volume->ReadQuery(queryCookie, buffer, bufferSize,
|
|
count, &countRead);
|
|
}
|
|
|
|
// reconstruct the reply, in case it has been overwritten
|
|
reply = new(reply) ReadQueryReply;
|
|
|
|
// send the reply
|
|
reply->error = result;
|
|
reply->count = countRead;
|
|
return _SendReply(allocator, (result == B_OK));
|
|
}
|
|
|
|
|
|
// #pragma mark - other
|
|
|
|
|
|
// _SendReply
|
|
status_t
|
|
UserlandRequestHandler::_SendReply(RequestAllocator& allocator,
|
|
bool expectsReceipt)
|
|
{
|
|
if (expectsReceipt) {
|
|
SingleReplyRequestHandler handler(RECEIPT_ACK_REPLY);
|
|
return fPort->SendRequest(&allocator, &handler);
|
|
} else
|
|
return fPort->SendRequest(&allocator);
|
|
}
|
|
|