2007-02-24 00:30:19 +00:00
|
|
|
// kernel_emu.cpp
|
|
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
#include "kernel_emu.h"
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
2009-03-15 18:24:14 +00:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
2009-03-01 14:51:05 +00:00
|
|
|
#include "FileSystem.h"
|
2007-02-24 00:30:19 +00:00
|
|
|
#include "RequestPort.h"
|
|
|
|
|
#include "Requests.h"
|
|
|
|
|
#include "RequestThread.h"
|
|
|
|
|
#include "UserlandFSServer.h"
|
|
|
|
|
#include "UserlandRequestHandler.h"
|
2009-03-01 14:51:05 +00:00
|
|
|
#include "Volume.h"
|
2007-02-24 00:30:19 +00:00
|
|
|
|
2007-02-28 04:54:13 +00:00
|
|
|
|
|
|
|
|
// Taken from the Haiku Storage Kit (storage_support.cpp)
|
2007-02-24 00:30:19 +00:00
|
|
|
/*! The length of the first component is returned as well as the index at
|
|
|
|
|
which the next one starts. These values are only valid, if the function
|
|
|
|
|
returns \c B_OK.
|
|
|
|
|
\param path the path to be parsed
|
|
|
|
|
\param length the variable the length of the first component is written
|
|
|
|
|
into
|
|
|
|
|
\param nextComponent the variable the index of the next component is
|
|
|
|
|
written into. \c 0 is returned, if there is no next component.
|
|
|
|
|
\return \c B_OK, if \a path is not \c NULL, \c B_BAD_VALUE otherwise
|
|
|
|
|
*/
|
2007-02-28 04:54:13 +00:00
|
|
|
static status_t
|
2007-02-24 00:30:19 +00:00
|
|
|
parse_first_path_component(const char *path, int32& length,
|
|
|
|
|
int32& nextComponent)
|
|
|
|
|
{
|
|
|
|
|
status_t error = (path ? B_OK : B_BAD_VALUE);
|
|
|
|
|
if (error == B_OK) {
|
|
|
|
|
int32 i = 0;
|
|
|
|
|
// find first '/' or end of name
|
|
|
|
|
for (; path[i] != '/' && path[i] != '\0'; i++);
|
|
|
|
|
// handle special case "/..." (absolute path)
|
|
|
|
|
if (i == 0 && path[i] != '\0')
|
|
|
|
|
i = 1;
|
|
|
|
|
length = i;
|
|
|
|
|
// find last '/' or end of name
|
|
|
|
|
for (; path[i] == '/' && path[i] != '\0'; i++);
|
|
|
|
|
if (path[i] == '\0') // this covers "" as well
|
|
|
|
|
nextComponent = 0;
|
|
|
|
|
else
|
|
|
|
|
nextComponent = i;
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// new_path
|
|
|
|
|
int
|
2007-02-28 04:54:13 +00:00
|
|
|
UserlandFS::KernelEmu::new_path(const char *path, char **copy)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// check errors and special cases
|
|
|
|
|
if (!copy)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
if (!path) {
|
|
|
|
|
*copy = NULL;
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
int32 len = strlen(path);
|
|
|
|
|
if (len < 1)
|
|
|
|
|
return B_ENTRY_NOT_FOUND;
|
|
|
|
|
bool appendDot = (path[len - 1] == '/');
|
|
|
|
|
if (appendDot)
|
|
|
|
|
len++;
|
|
|
|
|
if (len >= B_PATH_NAME_LENGTH)
|
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
|
// check the path components
|
|
|
|
|
const char *remainder = path;
|
|
|
|
|
int32 length, nextComponent;
|
|
|
|
|
do {
|
|
|
|
|
status_t error
|
|
|
|
|
= parse_first_path_component(remainder, length, nextComponent);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
if (length >= B_FILE_NAME_LENGTH)
|
|
|
|
|
error = B_NAME_TOO_LONG;
|
|
|
|
|
remainder += nextComponent;
|
|
|
|
|
} while (nextComponent != 0);
|
|
|
|
|
// clone the path
|
|
|
|
|
char *copiedPath = (char*)malloc(len + 1);
|
|
|
|
|
if (!copiedPath)
|
|
|
|
|
return B_NO_MEMORY;
|
|
|
|
|
strcpy(copiedPath, path);
|
|
|
|
|
// append a dot, if desired
|
|
|
|
|
if (appendDot) {
|
|
|
|
|
copiedPath[len] = '.';
|
|
|
|
|
copiedPath[len] = '\0';
|
|
|
|
|
}
|
|
|
|
|
*copy = copiedPath;
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// free_path
|
|
|
|
|
void
|
2007-02-28 04:54:13 +00:00
|
|
|
UserlandFS::KernelEmu::free_path(char *p)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
free(p);
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// #pragma mark -
|
|
|
|
|
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// get_port_and_fs
|
2007-02-28 04:54:13 +00:00
|
|
|
static status_t
|
2007-02-26 16:26:02 +00:00
|
|
|
get_port_and_fs(RequestPort** port, FileSystem** fileSystem)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request thread
|
|
|
|
|
RequestThread* thread = RequestThread::GetCurrentThread();
|
|
|
|
|
if (thread) {
|
|
|
|
|
*port = thread->GetPort();
|
|
|
|
|
*fileSystem = thread->GetFileSystem();
|
|
|
|
|
} else {
|
|
|
|
|
*port = UserlandFSServer::GetNotificationRequestPort();
|
|
|
|
|
*fileSystem = UserlandFSServer::GetFileSystem();
|
|
|
|
|
if (!*port || !*fileSystem)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
}
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// notify_listener
|
2007-02-28 22:07:40 +00:00
|
|
|
status_t
|
2007-03-02 00:41:09 +00:00
|
|
|
UserlandFS::KernelEmu::notify_listener(int32 operation, uint32 details,
|
2007-06-21 19:50:57 +00:00
|
|
|
dev_t device, ino_t oldDirectory, ino_t directory,
|
|
|
|
|
ino_t node, const char* oldName, const char* name)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
|
|
|
|
NotifyListenerRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-03-02 00:41:09 +00:00
|
|
|
request->operation = operation;
|
|
|
|
|
request->details = details;
|
|
|
|
|
request->device = device;
|
|
|
|
|
request->oldDirectory = oldDirectory;
|
|
|
|
|
request->directory = directory;
|
|
|
|
|
request->node = node;
|
|
|
|
|
error = allocator.AllocateString(request->oldName, oldName);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-24 00:30:19 +00:00
|
|
|
error = allocator.AllocateString(request->name, name);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, NOTIFY_LISTENER_REPLY);
|
|
|
|
|
NotifyListenerReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// process the reply
|
|
|
|
|
if (reply->error != B_OK)
|
|
|
|
|
return reply->error;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// notify_select_event
|
2007-03-06 02:39:34 +00:00
|
|
|
status_t
|
2007-10-02 19:47:31 +00:00
|
|
|
UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint8 event,
|
|
|
|
|
bool unspecifiedEvent)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
2007-03-06 02:39:34 +00:00
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
|
|
|
|
NotifySelectEventRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
2007-03-06 02:39:34 +00:00
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
request->sync = sync;
|
2007-02-28 22:07:40 +00:00
|
|
|
request->event = event;
|
2007-03-02 00:41:09 +00:00
|
|
|
request->unspecifiedEvent = unspecifiedEvent;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, NOTIFY_SELECT_EVENT_REPLY);
|
|
|
|
|
NotifySelectEventReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
2007-03-06 02:39:34 +00:00
|
|
|
return error;
|
2007-02-24 00:30:19 +00:00
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-03-06 02:39:34 +00:00
|
|
|
// process the reply
|
|
|
|
|
if (reply->error != B_OK)
|
|
|
|
|
return reply->error;
|
|
|
|
|
return error;
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// send_notification
|
2007-02-28 22:07:40 +00:00
|
|
|
status_t
|
2007-03-02 00:41:09 +00:00
|
|
|
UserlandFS::KernelEmu::notify_query(port_id targetPort, int32 token,
|
2007-06-21 19:50:57 +00:00
|
|
|
int32 operation, dev_t device, ino_t directory, const char* name,
|
|
|
|
|
ino_t node)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
2007-03-02 00:41:09 +00:00
|
|
|
NotifyQueryRequest* request;
|
2007-02-24 00:30:19 +00:00
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
request->port = targetPort;
|
|
|
|
|
request->token = token;
|
2007-03-02 00:41:09 +00:00
|
|
|
request->operation = operation;
|
|
|
|
|
request->device = device;
|
|
|
|
|
request->directory = directory;
|
|
|
|
|
request->node = node;
|
2007-02-24 00:30:19 +00:00
|
|
|
error = allocator.AllocateString(request->name, name);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
2007-03-02 00:41:09 +00:00
|
|
|
UserlandRequestHandler handler(fileSystem, NOTIFY_QUERY_REPLY);
|
|
|
|
|
NotifyQueryReply* reply;
|
2007-02-24 00:30:19 +00:00
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// process the reply
|
|
|
|
|
if (reply->error != B_OK)
|
|
|
|
|
return reply->error;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// #pragma mark -
|
|
|
|
|
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// get_vnode
|
2007-02-28 22:07:40 +00:00
|
|
|
status_t
|
2009-02-26 00:09:43 +00:00
|
|
|
UserlandFS::KernelEmu::get_vnode(dev_t nsid, ino_t vnid, void** node)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
|
|
|
|
GetVNodeRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
request->nsid = nsid;
|
|
|
|
|
request->vnid = vnid;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, GET_VNODE_REPLY);
|
|
|
|
|
GetVNodeReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// process the reply
|
|
|
|
|
if (reply->error != B_OK)
|
|
|
|
|
return reply->error;
|
2009-02-26 00:09:43 +00:00
|
|
|
*node = reply->node;
|
2007-02-24 00:30:19 +00:00
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// put_vnode
|
2007-02-28 22:07:40 +00:00
|
|
|
status_t
|
2007-06-21 19:50:57 +00:00
|
|
|
UserlandFS::KernelEmu::put_vnode(dev_t nsid, ino_t vnid)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
|
|
|
|
PutVNodeRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
request->nsid = nsid;
|
|
|
|
|
request->vnid = vnid;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, PUT_VNODE_REPLY);
|
|
|
|
|
PutVNodeReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// process the reply
|
|
|
|
|
if (reply->error != B_OK)
|
|
|
|
|
return reply->error;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-27 11:38:26 +00:00
|
|
|
// acquire_vnode
|
|
|
|
|
status_t
|
2009-03-04 00:01:27 +00:00
|
|
|
UserlandFS::KernelEmu::acquire_vnode(dev_t nsid, ino_t vnid)
|
2009-02-27 11:38:26 +00:00
|
|
|
{
|
2009-03-04 00:01:27 +00:00
|
|
|
// 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());
|
|
|
|
|
AcquireVNodeRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = nsid;
|
|
|
|
|
request->vnid = vnid;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, ACQUIRE_VNODE_REPLY);
|
|
|
|
|
AcquireVNodeReply* 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;
|
|
|
|
|
return error;
|
2009-02-27 11:38:26 +00:00
|
|
|
}
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// new_vnode
|
2007-02-28 22:07:40 +00:00
|
|
|
status_t
|
2009-03-17 18:51:43 +00:00
|
|
|
UserlandFS::KernelEmu::new_vnode(dev_t nsid, ino_t vnid, void* data,
|
|
|
|
|
const FSVNodeCapabilities& capabilities)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
|
|
|
|
NewVNodeRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
request->nsid = nsid;
|
|
|
|
|
request->vnid = vnid;
|
|
|
|
|
request->node = data;
|
2009-03-17 18:51:43 +00:00
|
|
|
request->capabilities = capabilities;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, NEW_VNODE_REPLY);
|
|
|
|
|
NewVNodeReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// process the reply
|
|
|
|
|
if (reply->error != B_OK)
|
|
|
|
|
return reply->error;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-28 22:07:40 +00:00
|
|
|
// publish_vnode
|
|
|
|
|
status_t
|
2009-02-26 00:09:43 +00:00
|
|
|
UserlandFS::KernelEmu::publish_vnode(dev_t nsid, ino_t vnid, void* data,
|
2009-03-17 18:51:43 +00:00
|
|
|
int type, uint32 flags, const FSVNodeCapabilities& capabilities)
|
2007-02-28 22:07:40 +00:00
|
|
|
{
|
2007-03-01 04:56:08 +00:00
|
|
|
// 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());
|
|
|
|
|
PublishVNodeRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = nsid;
|
|
|
|
|
request->vnid = vnid;
|
|
|
|
|
request->node = data;
|
2009-02-26 00:09:43 +00:00
|
|
|
request->type = type;
|
|
|
|
|
request->flags = flags;
|
2009-03-17 18:51:43 +00:00
|
|
|
request->capabilities = capabilities;
|
2007-03-01 04:56:08 +00:00
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, PUBLISH_VNODE_REPLY);
|
|
|
|
|
PublishVNodeReply* 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;
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
2009-03-01 14:51:05 +00:00
|
|
|
|
|
|
|
|
// publish_vnode
|
|
|
|
|
status_t
|
2009-03-17 18:51:43 +00:00
|
|
|
UserlandFS::KernelEmu::publish_vnode(dev_t nsid, ino_t vnid, void* data,
|
|
|
|
|
const FSVNodeCapabilities& capabilities)
|
2009-03-01 14:51:05 +00:00
|
|
|
{
|
|
|
|
|
// get the volume
|
|
|
|
|
Volume* volume = FileSystem::GetInstance()->VolumeWithID(nsid);
|
|
|
|
|
if (volume == NULL)
|
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
|
|
// stat() the node to get its type
|
|
|
|
|
int type;
|
|
|
|
|
status_t error = volume->GetVNodeType(data, &type);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
// publish the node
|
2009-03-17 18:51:43 +00:00
|
|
|
return UserlandFS::KernelEmu::publish_vnode(nsid, vnid, data, type, 0,
|
|
|
|
|
capabilities);
|
2009-03-01 14:51:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// remove_vnode
|
2007-02-28 22:07:40 +00:00
|
|
|
status_t
|
2007-06-21 19:50:57 +00:00
|
|
|
UserlandFS::KernelEmu::remove_vnode(dev_t nsid, ino_t vnid)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
|
|
|
|
RemoveVNodeRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
request->nsid = nsid;
|
|
|
|
|
request->vnid = vnid;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, REMOVE_VNODE_REPLY);
|
|
|
|
|
RemoveVNodeReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// process the reply
|
|
|
|
|
if (reply->error != B_OK)
|
|
|
|
|
return reply->error;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// unremove_vnode
|
2007-02-28 22:07:40 +00:00
|
|
|
status_t
|
2007-06-21 19:50:57 +00:00
|
|
|
UserlandFS::KernelEmu::unremove_vnode(dev_t nsid, ino_t vnid)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
|
|
|
|
UnremoveVNodeRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
request->nsid = nsid;
|
|
|
|
|
request->vnid = vnid;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, UNREMOVE_VNODE_REPLY);
|
|
|
|
|
UnremoveVNodeReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// process the reply
|
|
|
|
|
if (reply->error != B_OK)
|
|
|
|
|
return reply->error;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-02 00:41:09 +00:00
|
|
|
// get_vnode_removed
|
2007-02-28 22:07:40 +00:00
|
|
|
status_t
|
2007-06-21 19:50:57 +00:00
|
|
|
UserlandFS::KernelEmu::get_vnode_removed(dev_t nsid, ino_t vnid,
|
2007-03-02 00:41:09 +00:00
|
|
|
bool* removed)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
// get the request port and the file system
|
|
|
|
|
RequestPort* port;
|
2007-02-26 16:26:02 +00:00
|
|
|
FileSystem* fileSystem;
|
2007-02-24 00:30:19 +00:00
|
|
|
status_t error = get_port_and_fs(&port, &fileSystem);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
2007-03-02 00:41:09 +00:00
|
|
|
GetVNodeRemovedRequest* request;
|
2007-02-24 00:30:19 +00:00
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
request->nsid = nsid;
|
|
|
|
|
request->vnid = vnid;
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// send the request
|
2007-03-02 00:41:09 +00:00
|
|
|
UserlandRequestHandler handler(fileSystem, GET_VNODE_REMOVED_REPLY);
|
|
|
|
|
GetVNodeRemovedReply* reply;
|
2007-02-24 00:30:19 +00:00
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
2007-02-28 22:07:40 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// process the reply
|
2007-03-02 00:41:09 +00:00
|
|
|
*removed = reply->removed;
|
|
|
|
|
return reply->error;
|
2007-02-24 00:30:19 +00:00
|
|
|
}
|
|
|
|
|
|
2009-03-05 00:43:06 +00:00
|
|
|
|
|
|
|
|
// #pragma mark - file cache
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file_cache_create
|
|
|
|
|
status_t
|
|
|
|
|
UserlandFS::KernelEmu::file_cache_create(dev_t mountID, ino_t vnodeID,
|
|
|
|
|
off_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)
|
2009-03-16 03:16:36 +00:00
|
|
|
RETURN_ERROR(error);
|
2009-03-05 00:43:06 +00:00
|
|
|
|
|
|
|
|
// prepare the request
|
|
|
|
|
RequestAllocator allocator(port->GetPort());
|
|
|
|
|
FileCacheCreateRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
2009-03-16 03:16:36 +00:00
|
|
|
RETURN_ERROR(error);
|
2009-03-05 00:43:06 +00:00
|
|
|
|
|
|
|
|
request->nsid = mountID;
|
|
|
|
|
request->vnid = vnodeID;
|
|
|
|
|
request->size = size;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, FILE_CACHE_CREATE_REPLY);
|
|
|
|
|
FileCacheCreateReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
2009-03-16 03:16:36 +00:00
|
|
|
RETURN_ERROR(error);
|
2009-03-05 00:43:06 +00:00
|
|
|
RequestReleaser requestReleaser(port, reply);
|
|
|
|
|
|
|
|
|
|
// process the reply
|
2009-03-16 03:16:36 +00:00
|
|
|
RETURN_ERROR(reply->error);
|
2009-03-05 00:43:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file_cache_delete
|
|
|
|
|
status_t
|
|
|
|
|
UserlandFS::KernelEmu::file_cache_delete(dev_t mountID, ino_t vnodeID)
|
|
|
|
|
{
|
|
|
|
|
// 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());
|
|
|
|
|
FileCacheDeleteRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = mountID;
|
|
|
|
|
request->vnid = vnodeID;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, FILE_CACHE_DELETE_REPLY);
|
|
|
|
|
FileCacheDeleteReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
|
|
|
|
|
|
|
|
|
// process the reply
|
|
|
|
|
return reply->error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file_cache_set_enable
|
|
|
|
|
status_t
|
|
|
|
|
UserlandFS::KernelEmu::file_cache_set_enabled(dev_t mountID, ino_t vnodeID,
|
|
|
|
|
bool enabled)
|
|
|
|
|
{
|
|
|
|
|
// 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());
|
|
|
|
|
FileCacheSetEnabledRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = mountID;
|
|
|
|
|
request->vnid = vnodeID;
|
|
|
|
|
request->enabled = enabled;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, FILE_CACHE_SET_ENABLED_REPLY);
|
|
|
|
|
FileCacheSetEnabledReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
|
|
|
|
|
|
|
|
|
// process the reply
|
|
|
|
|
return reply->error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file_cache_set_size
|
|
|
|
|
status_t
|
|
|
|
|
UserlandFS::KernelEmu::file_cache_set_size(dev_t mountID, ino_t vnodeID,
|
|
|
|
|
off_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());
|
|
|
|
|
FileCacheSetSizeRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = mountID;
|
|
|
|
|
request->vnid = vnodeID;
|
|
|
|
|
request->size = size;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, FILE_CACHE_SET_SIZE_REPLY);
|
|
|
|
|
FileCacheSetSizeReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
|
|
|
|
|
|
|
|
|
// process the reply
|
|
|
|
|
return reply->error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file_cache_sync
|
|
|
|
|
status_t
|
|
|
|
|
UserlandFS::KernelEmu::file_cache_sync(dev_t mountID, ino_t vnodeID)
|
|
|
|
|
{
|
|
|
|
|
// 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());
|
|
|
|
|
FileCacheSyncRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = mountID;
|
|
|
|
|
request->vnid = vnodeID;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, FILE_CACHE_SYNC_REPLY);
|
|
|
|
|
FileCacheSyncReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
|
|
|
|
|
|
|
|
|
// process the reply
|
|
|
|
|
return reply->error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file_cache_read
|
|
|
|
|
status_t
|
|
|
|
|
UserlandFS::KernelEmu::file_cache_read(dev_t mountID, ino_t vnodeID,
|
|
|
|
|
void *cookie, off_t offset, void *bufferBase, 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());
|
|
|
|
|
FileCacheReadRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = mountID;
|
|
|
|
|
request->vnid = vnodeID;
|
|
|
|
|
request->cookie = cookie;
|
|
|
|
|
request->pos = offset;
|
|
|
|
|
request->size = *_size;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, FILE_CACHE_READ_REPLY);
|
|
|
|
|
FileCacheReadReply* 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;
|
|
|
|
|
|
2009-03-05 21:10:43 +00:00
|
|
|
if (reply->bytesRead > 0) {
|
2009-03-05 00:43:06 +00:00
|
|
|
memcpy(bufferBase, reply->buffer.GetData(), reply->buffer.GetSize());
|
|
|
|
|
|
|
|
|
|
// send receipt-ack
|
|
|
|
|
RequestAllocator receiptAckAllocator(port->GetPort());
|
|
|
|
|
ReceiptAckReply* receiptAck;
|
|
|
|
|
if (AllocateRequest(receiptAckAllocator, &receiptAck) == B_OK)
|
|
|
|
|
port->SendRequest(&receiptAckAllocator);
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-05 21:10:43 +00:00
|
|
|
*_size = reply->bytesRead;
|
2009-03-05 00:43:06 +00:00
|
|
|
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// file_cache_write
|
|
|
|
|
status_t
|
|
|
|
|
UserlandFS::KernelEmu::file_cache_write(dev_t mountID, ino_t vnodeID,
|
|
|
|
|
void *cookie, off_t offset, 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());
|
|
|
|
|
FileCacheWriteRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = mountID;
|
|
|
|
|
request->vnid = vnodeID;
|
|
|
|
|
request->cookie = cookie;
|
|
|
|
|
request->pos = offset;
|
|
|
|
|
|
|
|
|
|
error = allocator.AllocateData(request->buffer, buffer, *_size, 1, false);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, FILE_CACHE_WRITE_REPLY);
|
|
|
|
|
FileCacheWriteReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
|
|
|
|
|
|
|
|
|
// process the reply
|
|
|
|
|
*_size = reply->bytesWritten;
|
|
|
|
|
return reply->error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-03-14 02:32:25 +00:00
|
|
|
// #pragma mark - I/O
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
status_t
|
2009-03-15 02:49:05 +00:00
|
|
|
UserlandFS::KernelEmu::do_iterative_fd_io(dev_t volumeID, int fd,
|
|
|
|
|
int32 requestID, void* cookie, const file_io_vec* vecs, uint32 vecCount)
|
2009-03-14 02:32:25 +00:00
|
|
|
{
|
|
|
|
|
// 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());
|
|
|
|
|
DoIterativeFDIORequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
2009-03-15 02:49:05 +00:00
|
|
|
request->nsid = volumeID;
|
2009-03-14 02:32:25 +00:00
|
|
|
request->fd = fd;
|
|
|
|
|
request->request = requestID;
|
|
|
|
|
request->cookie = cookie;
|
|
|
|
|
|
|
|
|
|
if (vecCount > 0) {
|
2009-03-15 18:24:14 +00:00
|
|
|
vecCount = std::min(vecCount, (uint32)DoIterativeFDIORequest::MAX_VECS);
|
|
|
|
|
memcpy(request->vecs, vecs, sizeof(file_io_vec) * vecCount);
|
2009-03-14 02:32:25 +00:00
|
|
|
}
|
2009-03-15 18:24:14 +00:00
|
|
|
request->vecCount = vecCount;
|
2009-03-14 02:32:25 +00:00
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, DO_ITERATIVE_FD_IO_REPLY);
|
|
|
|
|
DoIterativeFDIOReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
2009-03-15 18:24:14 +00:00
|
|
|
// TODO: Up to this point we should call the finished hook on error!
|
2009-03-14 02:32:25 +00:00
|
|
|
RequestReleaser requestReleaser(port, reply);
|
|
|
|
|
|
|
|
|
|
// process the reply
|
|
|
|
|
return reply->error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-11-19 16:26:40 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-07-30 14:12:47 +00:00
|
|
|
status_t
|
|
|
|
|
UserlandFS::KernelEmu::notify_io_request(dev_t volumeID, int32 requestID,
|
|
|
|
|
status_t status)
|
|
|
|
|
{
|
|
|
|
|
// 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());
|
|
|
|
|
NotifyIORequestRequest* request;
|
|
|
|
|
error = AllocateRequest(allocator, &request);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
request->nsid = volumeID;
|
|
|
|
|
request->request = requestID;
|
|
|
|
|
request->status = status;
|
|
|
|
|
|
|
|
|
|
// send the request
|
|
|
|
|
UserlandRequestHandler handler(fileSystem, NOTIFY_IO_REQUEST_REPLY);
|
|
|
|
|
NotifyIORequestReply* reply;
|
|
|
|
|
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
|
|
|
if (error != B_OK)
|
|
|
|
|
return error;
|
|
|
|
|
RequestReleaser requestReleaser(port, reply);
|
|
|
|
|
|
|
|
|
|
// process the reply
|
|
|
|
|
return reply->error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// #pragma mark -
|
|
|
|
|
|
2009-03-05 00:43:06 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// kernel_debugger
|
|
|
|
|
void
|
2007-02-28 04:54:13 +00:00
|
|
|
UserlandFS::KernelEmu::kernel_debugger(const char *message)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
debugger(message);
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-11 15:04:53 +00:00
|
|
|
// vdprintf
|
|
|
|
|
void
|
|
|
|
|
UserlandFS::KernelEmu::vdprintf(const char *format, va_list args)
|
|
|
|
|
{
|
|
|
|
|
vprintf(format, args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dprintf
|
|
|
|
|
void
|
|
|
|
|
UserlandFS::KernelEmu::dprintf(const char *format, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, format);
|
2007-03-28 22:18:59 +00:00
|
|
|
vdprintf(format, args);
|
2007-03-11 15:04:53 +00:00
|
|
|
va_end(args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
UserlandFS::KernelEmu::dump_block(const char *buffer, int size,
|
|
|
|
|
const char *prefix)
|
|
|
|
|
{
|
|
|
|
|
// TODO: Implement!
|
|
|
|
|
}
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// parse_expression
|
2007-02-28 04:54:13 +00:00
|
|
|
//ulong
|
|
|
|
|
//parse_expression(char *str)
|
|
|
|
|
//{
|
|
|
|
|
// return 0;
|
|
|
|
|
//}
|
2007-02-24 00:30:19 +00:00
|
|
|
|
|
|
|
|
// add_debugger_command
|
|
|
|
|
int
|
2007-02-28 04:54:13 +00:00
|
|
|
UserlandFS::KernelEmu::add_debugger_command(char *name,
|
|
|
|
|
int (*func)(int argc, char **argv), char *help)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// remove_debugger_command
|
|
|
|
|
int
|
2007-02-28 04:54:13 +00:00
|
|
|
UserlandFS::KernelEmu::remove_debugger_command(char *name,
|
|
|
|
|
int (*func)(int argc, char **argv))
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
return B_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-27 13:20:53 +00:00
|
|
|
// parse_expression
|
|
|
|
|
uint32
|
|
|
|
|
UserlandFS::KernelEmu::parse_expression(const char *string)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// kprintf
|
2007-02-28 04:54:13 +00:00
|
|
|
//void
|
|
|
|
|
//kprintf(const char *format, ...)
|
|
|
|
|
//{
|
|
|
|
|
//}
|
2007-02-24 00:30:19 +00:00
|
|
|
|
|
|
|
|
// spawn_kernel_thread
|
|
|
|
|
thread_id
|
2007-02-28 04:54:13 +00:00
|
|
|
UserlandFS::KernelEmu::spawn_kernel_thread(thread_entry function,
|
|
|
|
|
const char *threadName, long priority, void *arg)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
return spawn_thread(function, threadName, priority, arg);
|
|
|
|
|
}
|