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-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-02-26 00:09:43 +00:00
|
|
|
UserlandFS::KernelEmu::new_vnode(dev_t nsid, ino_t vnid, void* data)
|
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;
|
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,
|
|
|
|
|
int type, uint32 flags)
|
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;
|
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
|
|
|
|
|
UserlandFS::KernelEmu::publish_vnode(dev_t nsid, ino_t vnid, void* data)
|
|
|
|
|
{
|
|
|
|
|
// 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
|
|
|
|
|
return UserlandFS::KernelEmu::publish_vnode(nsid, vnid, data, type, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
// vpanic
|
2007-02-24 00:30:19 +00:00
|
|
|
void
|
2007-03-11 15:04:53 +00:00
|
|
|
UserlandFS::KernelEmu::vpanic(const char *format, va_list args)
|
2007-02-24 00:30:19 +00:00
|
|
|
{
|
|
|
|
|
char buffer[1024];
|
|
|
|
|
strcpy(buffer, "PANIC: ");
|
|
|
|
|
int32 prefixLen = strlen(buffer);
|
|
|
|
|
int bufferSize = sizeof(buffer) - prefixLen;
|
2007-03-11 15:04:53 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
// no vsnprintf() on PPC
|
|
|
|
|
#if defined(__INTEL__)
|
|
|
|
|
vsnprintf(buffer + prefixLen, bufferSize - 1, format, args);
|
|
|
|
|
#else
|
|
|
|
|
vsprintf(buffer + prefixLen, format, args);
|
|
|
|
|
#endif
|
2007-03-11 15:04:53 +00:00
|
|
|
|
2007-02-24 00:30:19 +00:00
|
|
|
buffer[sizeof(buffer) - 1] = '\0';
|
|
|
|
|
debugger(buffer);
|
|
|
|
|
}
|
|
|
|
|
|
2007-03-11 15:04:53 +00:00
|
|
|
// panic
|
|
|
|
|
void
|
|
|
|
|
UserlandFS::KernelEmu::panic(const char *format, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, format);
|
|
|
|
|
vpanic(format, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
}
|