#include "kernel_interface.h"
#include <dirent.h>
#include <KernelExport.h>
#include <fs_interface.h>
#include "Debug.h"
#include "FileSystem.h"
#include "String.h"
#include "UserlandFS.h"
#include "Volume.h"
static status_t
parse_parameters(const char *parameters, String &fsName,
const char **fsParameters)
{
if (!parameters)
return B_BAD_VALUE;
int32 len = strlen(parameters);
for (; len > 0; parameters++, len--) {
if (*parameters != ' ' && *parameters != '\t' && *parameters != '\n')
break;
}
if (len == 0)
return B_BAD_VALUE;
int32 fsNameLen = len;
for (int32 i = 0; i < len; i++) {
if (parameters[i] == ' ' || parameters[i] == '\t'
|| parameters[i] == '\n') {
fsNameLen = i;
break;
}
}
fsName.SetTo(parameters, fsNameLen);
if (fsName.GetLength() == 0) {
exit_debugging();
return B_NO_MEMORY;
}
parameters += fsNameLen;
len -= fsNameLen;
for (; len > 0; parameters++, len--) {
if (*parameters != ' ' && *parameters != '\t' && *parameters != '\n')
break;
}
*fsParameters = parameters;
return B_OK;
}
static status_t
userlandfs_mount(fs_volume* fsVolume, const char* device, uint32 flags,
const char* args, ino_t* rootVnodeID)
{
PRINT(("userlandfs_mount(%p (%" B_PRId32 "), %s, 0x%" B_PRIx32
", %s, %p)\n", fsVolume, fsVolume->id, device, flags, args,
rootVnodeID));
status_t error = B_OK;
String fsName;
const char* fsParameters;
error = parse_parameters(args, fsName, &fsParameters);
if (error != B_OK)
RETURN_ERROR(error);
UserlandFS* userlandFS = UserlandFS::GetUserlandFS();
if (!userlandFS)
RETURN_ERROR(B_ERROR);
FileSystem* fileSystem = NULL;
error = userlandFS->RegisterFileSystem(fsName.GetString(), &fileSystem);
if (error != B_OK)
RETURN_ERROR(error);
Volume* volume = NULL;
error = fileSystem->Mount(fsVolume, device, flags, fsParameters, &volume);
if (error != B_OK) {
userlandFS->UnregisterFileSystem(fileSystem);
RETURN_ERROR(error);
}
fsVolume->private_volume = volume;
fsVolume->ops = volume->GetVolumeOps();
*rootVnodeID = volume->GetRootID();
PRINT(("userlandfs_mount() done: %p, %" B_PRIdINO "\n",
fsVolume->private_volume, *rootVnodeID));
return error;
}
static status_t
userlandfs_unmount(fs_volume* fsVolume)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_unmount(%p)\n", volume));
FileSystem* fileSystem = volume->GetFileSystem();
status_t error = volume->Unmount();
volume->ReleaseReference();
UserlandFS::GetUserlandFS()->UnregisterFileSystem(fileSystem);
PRINT(("userlandfs_unmount() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_sync(fs_volume* fsVolume)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_sync(%p)\n", volume));
status_t error = volume->Sync();
PRINT(("userlandfs_sync() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_read_fs_info(fs_volume* fsVolume, struct fs_info* info)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_fs_info(%p, %p)\n", volume, info));
status_t error = volume->ReadFSInfo(info);
PRINT(("userlandfs_read_fs_info() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_write_fs_info(fs_volume* fsVolume, const struct fs_info* info,
uint32 mask)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_write_fs_info(%p, %p, 0x%" B_PRIx32 ")\n", volume, info,
mask));
status_t error = volume->WriteFSInfo(info, mask);
PRINT(("userlandfs_write_fs_info() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_lookup(fs_volume* fsVolume, fs_vnode* fsDir, const char* entryName,
ino_t* vnid)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_lookup(%p, %p, `%s', %p)\n", volume, fsDir->private_node,
entryName, vnid));
status_t error = volume->Lookup(fsDir->private_node, entryName, vnid);
PRINT(("userlandfs_lookup() done: (%" B_PRIx32 ", %" B_PRIdINO ")\n", error,
*vnid));
return error;
}
static status_t
userlandfs_get_vnode_name(fs_volume* fsVolume, fs_vnode* fsNode, char* buffer,
size_t bufferSize)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_get_vnode_name(%p, %p, %p, %" B_PRIuSIZE ")\n", volume,
fsNode->private_node, buffer, bufferSize));
status_t error = volume->GetVNodeName(fsNode->private_node, buffer,
bufferSize);
PRINT(("userlandfs_get_vnode_name() done: (%" B_PRIx32 ", \"%.*s\")\n",
error, (int)bufferSize, (error == B_OK ? buffer : NULL)));
return error;
}
static status_t
userlandfs_get_vnode(fs_volume* fsVolume, ino_t vnid, fs_vnode* fsNode,
int* _type, uint32* _flags, bool reenter)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_get_vnode(%p, %" B_PRIdINO ", %p, %d)\n", volume, vnid,
fsNode->private_node, reenter));
void* node;
fs_vnode_ops* ops;
status_t error = volume->ReadVNode(vnid, reenter, &node, &ops, _type,
_flags);
if (error == B_OK) {
fsNode->private_node = node;
fsNode->ops = ops;
}
PRINT(("userlandfs_get_vnode() done: (%" B_PRIx32 ", %p, %#x, %#" B_PRIx32
")\n", error, node, *_type, *_flags));
return error;
}
static status_t
userlandfs_put_vnode(fs_volume* fsVolume, fs_vnode* fsNode, bool reenter)
{
Volume* volume = (Volume*)fsVolume->private_volume;
status_t error = volume->WriteVNode(fsNode->private_node, reenter);
return error;
}
static status_t
userlandfs_remove_vnode(fs_volume* fsVolume, fs_vnode* fsNode, bool reenter)
{
Volume* volume = (Volume*)fsVolume->private_volume;
status_t error = volume->RemoveVNode(fsNode->private_node, reenter);
return error;
}
status_t
userlandfs_io(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
io_request* request)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_io(%p, %p, %p, %p)\n", volume, fsNode->private_node,
cookie, request));
status_t error = volume->DoIO(fsNode->private_node, cookie, request);
PRINT(("userlandfs_io() done: (%" B_PRIx32 ")\n", error));
return error;
}
status_t
userlandfs_cancel_io(fs_volume* fsVolume, fs_vnode* fsNode, void *cookie,
io_request *request)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_cancel_io(%p, %p, %p, %p)\n", volume,
fsNode->private_node, cookie, request));
status_t error = volume->CancelIO(fsNode->private_node, cookie, request);
PRINT(("userlandfs_cancel_io() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_ioctl(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, uint32 op,
void* buffer, size_t length)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_ioctl(%p, %p, %p, %" B_PRIu32 ", %p, %" B_PRIuSIZE ")\n",
volume, fsNode->private_node, cookie, op, buffer, length));
status_t error = volume->IOCtl(fsNode->private_node, cookie, op, buffer,
length);
PRINT(("userlandfs_ioctl() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_set_flags(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
int flags)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_set_flags(%p, %p, %p, %d)\n", volume,
fsNode->private_node, cookie, flags));
status_t error = volume->SetFlags(fsNode->private_node, cookie, flags);
PRINT(("userlandfs_set_flags() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_select(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
uint8 event, selectsync* sync)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_select(%p, %p, %p, %hhd, %p)\n", volume,
fsNode->private_node, cookie, event, sync));
status_t error = volume->Select(fsNode->private_node, cookie, event, sync);
PRINT(("userlandfs_select() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_deselect(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
uint8 event, selectsync* sync)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_deselect(%p, %p, %p, %hhd, %p)\n", volume,
fsNode->private_node, cookie, event, sync));
status_t error = volume->Deselect(fsNode->private_node, cookie, event,
sync);
PRINT(("userlandfs_deselect() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_fsync(fs_volume* fsVolume, fs_vnode* fsNode, bool dataOnly)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_fsync(%p, %p)\n", volume, fsNode->private_node));
status_t error = volume->FSync(fsNode->private_node);
PRINT(("userlandfs_fsync() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_read_symlink(fs_volume* fsVolume, fs_vnode* fsLink, char* buffer,
size_t* bufferSize)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_symlink(%p, %p, %p, %" B_PRIuSIZE ")\n", volume,
fsLink->private_node, buffer, *bufferSize));
status_t error = volume->ReadSymlink(fsLink->private_node, buffer,
*bufferSize, bufferSize);
PRINT(("userlandfs_read_symlink() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n",
error, *bufferSize));
return error;
}
static status_t
userlandfs_create_symlink(fs_volume* fsVolume, fs_vnode* fsDir,
const char* name, const char* path, int mode)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_create_symlink(%p, %p, `%s', `%s', %d)\n", volume,
fsDir->private_node, name, path, mode));
status_t error = volume->CreateSymlink(fsDir->private_node, name, path,
mode);
PRINT(("userlandfs_create_symlink() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_link(fs_volume* fsVolume, fs_vnode* fsDir, const char* name,
fs_vnode* fsNode)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_link(%p, %p, `%s', %p)\n", volume,
fsDir->private_node, name, fsNode->private_node));
status_t error = volume->Link(fsDir->private_node, name,
fsNode->private_node);
PRINT(("userlandfs_link() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_unlink(fs_volume* fsVolume, fs_vnode* fsDir, const char* name)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_unlink(%p, %p, `%s')\n", volume, fsDir->private_node,
name));
status_t error = volume->Unlink(fsDir->private_node, name);
PRINT(("userlandfs_unlink() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_rename(fs_volume* fsVolume, fs_vnode* fsFromDir,
const char *fromName, fs_vnode* fsToDir, const char *toName)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_rename(%p, %p, `%s', %p, `%s')\n", volume,
fsFromDir->private_node, fromName, fsToDir->private_node, toName));
status_t error = volume->Rename(fsFromDir->private_node, fromName,
fsToDir->private_node, toName);
PRINT(("userlandfs_rename() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_access(fs_volume* fsVolume, fs_vnode* fsNode, int mode)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_access(%p, %p, %d)\n", volume, fsNode->private_node,
mode));
status_t error = volume->Access(fsNode->private_node, mode);
PRINT(("userlandfs_access() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_read_stat(fs_volume* fsVolume, fs_vnode* fsNode, struct stat* st)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_stat(%p, %p, %p)\n", volume, fsNode->private_node,
st));
status_t error = volume->ReadStat(fsNode->private_node, st);
PRINT(("userlandfs_read_stat() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_write_stat(fs_volume* fsVolume, fs_vnode* fsNode,
const struct stat* st, uint32 mask)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_write_stat(%p, %p, %p, %" B_PRIu32 ")\n", volume,
fsNode->private_node, st, mask));
status_t error = volume->WriteStat(fsNode->private_node, st, mask);
PRINT(("userlandfs_write_stat() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_create(fs_volume* fsVolume, fs_vnode* fsDir, const char* name,
int openMode, int perms, void** cookie, ino_t* vnid)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_create(%p, %p, `%s', %d, %d, %p, %p)\n", volume,
fsDir->private_node, name, openMode, perms, cookie, vnid));
status_t error = volume->Create(fsDir->private_node, name, openMode, perms,
cookie, vnid);
PRINT(("userlandfs_create() done: (%" B_PRIx32 ", %" B_PRIdINO ", %p)\n",
error, *vnid, *cookie));
return error;
}
static status_t
userlandfs_open(fs_volume* fsVolume, fs_vnode* fsNode, int openMode,
void** cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_open(%p, %p, %d)\n", volume, fsNode->private_node,
openMode));
status_t error = volume->Open(fsNode->private_node, openMode, cookie);
PRINT(("userlandfs_open() done: (%" B_PRIx32 ", %p)\n", error, *cookie));
return error;
}
static status_t
userlandfs_close(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_close(%p, %p, %p)\n", volume, fsNode->private_node,
cookie));
status_t error = volume->Close(fsNode->private_node, cookie);
PRINT(("userlandfs_close() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_free_cookie(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_free_cookie(%p, %p, %p)\n", volume, fsNode->private_node,
cookie));
status_t error = volume->FreeCookie(fsNode->private_node, cookie);
PRINT(("userlandfs_free_cookie() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_read(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, off_t pos,
void* buffer, size_t* length)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read(%p, %p, %p, %" B_PRIdOFF ", %p, %" B_PRIuSIZE ")\n",
volume, fsNode->private_node, cookie, pos, buffer, *length));
status_t error = volume->Read(fsNode->private_node, cookie, pos, buffer,
*length, length);
PRINT(("userlandfs_read() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n", error,
*length));
return error;
}
static status_t
userlandfs_write(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie, off_t pos,
const void* buffer, size_t* length)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_write(%p, %p, %p, %" B_PRIdOFF ", %p, %" B_PRIuSIZE
")\n", volume, fsNode->private_node, cookie, pos, buffer, *length));
status_t error = volume->Write(fsNode->private_node, cookie, pos, buffer,
*length, length);
PRINT(("userlandfs_write() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n", error,
*length));
return error;
}
static status_t
userlandfs_create_dir(fs_volume* fsVolume, fs_vnode* fsParent, const char* name,
int perms)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_create_dir(%p, %p, `%s', %#x)\n", volume,
fsParent->private_node, name, perms));
status_t error = volume->CreateDir(fsParent->private_node, name, perms);
PRINT(("userlandfs_create_dir() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_remove_dir(fs_volume* fsVolume, fs_vnode* fsParent, const char* name)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_remove_dir(%p, %p, `%s')\n", volume,
fsParent->private_node, name));
status_t error = volume->RemoveDir(fsParent->private_node, name);
PRINT(("userlandfs_remove_dir() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_open_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_open_dir(%p, %p)\n", volume, fsNode->private_node));
status_t error = volume->OpenDir(fsNode->private_node, cookie);
PRINT(("userlandfs_open_dir() done: (%" B_PRIx32 ", %p)\n", error,
*cookie));
return error;
}
static status_t
userlandfs_close_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_close_dir(%p, %p, %p)\n", volume, fsNode->private_node,
cookie));
status_t error = volume->CloseDir(fsNode->private_node, cookie);
PRINT(("userlandfs_close_dir() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_free_dir_cookie(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_free_dir_cookie(%p, %p, %p)\n", volume,
fsNode->private_node, cookie));
status_t error = volume->FreeDirCookie(fsNode->private_node, cookie);
PRINT(("userlandfs_free_dir_cookie() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_read_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
struct dirent* buffer, size_t bufferSize, uint32* count)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_dir(%p, %p, %p, %p, %" B_PRIuSIZE ", %" B_PRIu32
")\n", volume, fsNode->private_node, cookie, buffer, bufferSize,
*count));
status_t error = volume->ReadDir(fsNode->private_node, cookie, buffer,
bufferSize, *count, count);
PRINT(("userlandfs_read_dir() done: (%" B_PRIx32 ", %" B_PRIu32 ")\n",
error, *count));
#if DEBUG
dirent* entry = buffer;
for (uint32 i = 0; error == B_OK && i < *count; i++) {
char name[B_FILE_NAME_LENGTH];
int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1);
strncpy(name, entry->d_name, nameLen);
name[nameLen] = '\0';
PRINT((" entry: d_dev: %" B_PRIdDEV ", d_pdev: %" B_PRIdDEV
", d_ino: %" B_PRIdINO ", d_pino: %" B_PRIdINO ", "
"d_reclen: %" B_PRIu16 ", d_name: `%s'\n",
entry->d_dev, entry->d_pdev, entry->d_ino, entry->d_pino,
entry->d_reclen, name));
entry = (dirent*)((char*)entry + entry->d_reclen);
}
#endif
return error;
}
static status_t
userlandfs_rewind_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_rewind_dir(%p, %p, %p)\n", volume, fsNode->private_node,
cookie));
status_t error = volume->RewindDir(fsNode->private_node, cookie);
PRINT(("userlandfs_rewind_dir() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_open_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_open_attr_dir(%p, %p)\n", volume, fsNode->private_node));
status_t error = volume->OpenAttrDir(fsNode->private_node, cookie);
PRINT(("userlandfs_open_attr_dir() done: (%" B_PRIx32 ", %p)\n", error,
*cookie));
return error;
}
static status_t
userlandfs_close_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_close_attr_dir(%p, %p, %p)\n", volume,
fsNode->private_node, cookie));
status_t error = volume->CloseAttrDir(fsNode->private_node, cookie);
PRINT(("userlandfs_close_attr_dir() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_free_attr_dir_cookie(fs_volume* fsVolume, fs_vnode* fsNode,
void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_free_attr_dir_cookie(%p, %p, %p)\n", volume,
fsNode->private_node, cookie));
status_t error = volume->FreeAttrDirCookie(fsNode->private_node, cookie);
PRINT(("userlandfs_free_attr_dir_cookie() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_read_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
struct dirent* buffer, size_t bufferSize, uint32* count)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_attr_dir(%p, %p, %p, %p, %" B_PRIuSIZE ", %"
B_PRIu32 ")\n", volume, fsNode->private_node, cookie, buffer,
bufferSize, *count));
status_t error = volume->ReadAttrDir(fsNode->private_node, cookie, buffer,
bufferSize, *count, count);
PRINT(("userlandfs_read_attr_dir() done: (%" B_PRIx32 ", %" B_PRIu32 ")\n",
error, *count));
return error;
}
static status_t
userlandfs_rewind_attr_dir(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_rewind_attr_dir(%p, %p, %p)\n", volume,
fsNode->private_node, cookie));
status_t error = volume->RewindAttrDir(fsNode->private_node, cookie);
PRINT(("userlandfs_rewind_attr_dir() done: (%" B_PRIx32 ")\n", error));
return error;
}
status_t
userlandfs_create_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name,
uint32 type, int openMode, void** cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_create_attr(%p, %p, \"%s\", 0x%" B_PRIx32 ", %d, %p)\n",
volume, fsNode->private_node, name, type, openMode, cookie));
status_t error = volume->CreateAttr(fsNode->private_node, name, type,
openMode, cookie);
PRINT(("userlandfs_create_attr() done: (%" B_PRIx32 ", %p)\n", error,
*cookie));
return error;
}
status_t
userlandfs_open_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name,
int openMode, void** cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_open_attr(%p, %p, \"%s\", %d, %p)\n", volume,
fsNode->private_node, name, openMode, cookie));
status_t error = volume->OpenAttr(fsNode->private_node, name, openMode,
cookie);
PRINT(("userlandfs_open_attr() done: (%" B_PRIx32 ", %p)\n", error,
*cookie));
return error;
}
status_t
userlandfs_close_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_close_attr(%p, %p, %p)\n", volume, fsNode->private_node,
cookie));
status_t error = volume->CloseAttr(fsNode->private_node, cookie);
PRINT(("userlandfs_close_attr() done: %" B_PRIx32 "\n", error));
return error;
}
status_t
userlandfs_free_attr_cookie(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_free_attr_cookie(%p, %p, %p)\n", volume,
fsNode->private_node, cookie));
status_t error = volume->FreeAttrCookie(fsNode->private_node, cookie);
PRINT(("userlandfs_free_attr_cookie() done: %" B_PRIx32 "\n", error));
return error;
}
static status_t
userlandfs_read_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
off_t pos, void* buffer, size_t* length)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_attr(%p, %p, %p, %" B_PRIdOFF ", %p, %"
B_PRIuSIZE ")\n", volume, fsNode->private_node, cookie, pos, buffer,
*length));
status_t error = volume->ReadAttr(fsNode->private_node, cookie, pos, buffer,
*length, length);
PRINT(("userlandfs_read_attr() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n",
error, *length));
return error;
}
static status_t
userlandfs_write_attr(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
off_t pos, const void* buffer, size_t* length)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_write_attr(%p, %p, %p, %" B_PRIdOFF ", %p, %" B_PRIuSIZE
")\n", volume, fsNode->private_node, cookie, pos, buffer, *length));
status_t error = volume->WriteAttr(fsNode->private_node, cookie, pos,
buffer, *length, length);
PRINT(("userlandfs_write_attr() done: (%" B_PRIx32 ", %" B_PRIuSIZE ")\n",
error, *length));
return error;
}
static status_t
userlandfs_read_attr_stat(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
struct stat* st)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_attr_stat(%p, %p, %p, %p)\n", volume,
fsNode->private_node, cookie, st));
status_t error = volume->ReadAttrStat(fsNode->private_node, cookie, st);
PRINT(("userlandfs_read_attr_stat() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_write_attr_stat(fs_volume* fsVolume, fs_vnode* fsNode, void* cookie,
const struct stat* st, int statMask)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_write_attr_stat(%p, %p, %p, %p, 0x%x)\n", volume,
fsNode->private_node, cookie, st, statMask));
status_t error = volume->WriteAttrStat(fsNode->private_node, cookie, st,
statMask);
PRINT(("userlandfs_write_attr_stat() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_rename_attr(fs_volume* fsVolume, fs_vnode* fsFromNode,
const char* fromName, fs_vnode* fsToNode, const char* toName)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_rename_attr(%p, %p, `%s', %p, `%s')\n", volume,
fsFromNode->private_node, fromName, fsToNode->private_node, toName));
status_t error = volume->RenameAttr(fsFromNode->private_node, fromName,
fsToNode->private_node, toName);
PRINT(("userlandfs_rename_attr() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_remove_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_remove_attr(%p, %p, `%s')\n", volume,
fsNode->private_node, name));
status_t error = volume->RemoveAttr(fsNode->private_node, name);
PRINT(("userlandfs_remove_attr() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_open_index_dir(fs_volume* fsVolume, void** cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_open_index_dir(%p, %p)\n", volume, cookie));
status_t error = volume->OpenIndexDir(cookie);
PRINT(("userlandfs_open_index_dir() done: (%" B_PRIx32 ", %p)\n", error,
*cookie));
return error;
}
static status_t
userlandfs_close_index_dir(fs_volume* fsVolume, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_close_index_dir(%p, %p)\n", volume, cookie));
status_t error = volume->CloseIndexDir(cookie);
PRINT(("userlandfs_close_index_dir() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_free_index_dir_cookie(fs_volume* fsVolume, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_free_index_dir_cookie(%p, %p)\n", volume, cookie));
status_t error = volume->FreeIndexDirCookie(cookie);
PRINT(("userlandfs_free_index_dir_cookie() done: (%" B_PRIx32 ")\n",
error));
return error;
}
static status_t
userlandfs_read_index_dir(fs_volume* fsVolume, void* cookie,
struct dirent* buffer, size_t bufferSize, uint32* count)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_index_dir(%p, %p, %p, %" B_PRIuSIZE ", %" B_PRIu32
")\n", volume, cookie, buffer, bufferSize, *count));
status_t error = volume->ReadIndexDir(cookie, buffer, bufferSize,
*count, count);
PRINT(("userlandfs_read_index_dir() done: (%" B_PRIx32 ", %" B_PRIu32 ")\n",
error, *count));
return error;
}
static status_t
userlandfs_rewind_index_dir(fs_volume* fsVolume, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_rewind_index_dir(%p, %p)\n", volume, cookie));
status_t error = volume->RewindIndexDir(cookie);
PRINT(("userlandfs_rewind_index_dir() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_create_index(fs_volume* fsVolume, const char* name, uint32 type,
uint32 flags)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_create_index(%p, `%s', 0x%" B_PRIx32 ", 0x%" B_PRIx32
")\n", volume, name, type, flags));
status_t error = volume->CreateIndex(name, type, flags);
PRINT(("userlandfs_create_index() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_remove_index(fs_volume* fsVolume, const char* name)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_remove_index(%p, `%s')\n", volume, name));
status_t error = volume->RemoveIndex(name);
PRINT(("userlandfs_remove_index() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_read_index_stat(fs_volume* fsVolume, const char* name,
struct stat* st)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_index_stat(%p, `%s', %p)\n", volume, name, st));
status_t error = volume->ReadIndexStat(name, st);
PRINT(("userlandfs_read_index_stat() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_open_query(fs_volume* fsVolume, const char *queryString,
uint32 flags, port_id port, uint32 token, void** cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_open_query(%p, `%s', %" B_PRIu32 ", %" B_PRId32 ", %"
B_PRIu32 ", %p)\n", volume, queryString, flags, port, token, cookie));
status_t error = volume->OpenQuery(queryString, flags, port, token, cookie);
PRINT(("userlandfs_open_query() done: (%" B_PRIx32 ", %p)\n", error,
*cookie));
return error;
}
static status_t
userlandfs_close_query(fs_volume* fsVolume, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_close_query(%p, %p)\n", volume, cookie));
status_t error = volume->CloseQuery(cookie);
PRINT(("userlandfs_close_query() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_free_query_cookie(fs_volume* fsVolume, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_free_query_cookie(%p, %p)\n", volume, cookie));
status_t error = volume->FreeQueryCookie(cookie);
PRINT(("userlandfs_free_query_cookie() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_read_query(fs_volume* fsVolume, void* cookie,
struct dirent* buffer, size_t bufferSize, uint32* count)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_read_query(%p, %p, %p, %" B_PRIuSIZE ", %" B_PRIu32
")\n", volume, cookie, buffer, bufferSize, *count));
status_t error = volume->ReadQuery(cookie, buffer, bufferSize, *count,
count);
PRINT(("userlandfs_read_query() done: (%" B_PRIx32 ", %" B_PRIu32 ")\n",
error, *count));
#if DEBUG
if (error == B_OK && *count > 0) {
char name[B_FILE_NAME_LENGTH];
int nameLen = strnlen(buffer->d_name, B_FILE_NAME_LENGTH - 1);
strncpy(name, buffer->d_name, nameLen);
name[nameLen] = '\0';
PRINT((" entry: d_dev: %" B_PRIdDEV ", d_pdev: %" B_PRIdDEV
", d_ino: %" B_PRIdINO ", d_pino: %" B_PRIdINO ", d_reclen: %"
B_PRIu16 ", d_name: `%s'\n", buffer->d_dev, buffer->d_pdev,
buffer->d_ino, buffer->d_pino, buffer->d_reclen, name));
}
#endif
return error;
}
static status_t
userlandfs_rewind_query(fs_volume* fsVolume, void* cookie)
{
Volume* volume = (Volume*)fsVolume->private_volume;
PRINT(("userlandfs_rewind_query(%p, %p)\n", volume, cookie));
status_t error = volume->RewindQuery(cookie);
PRINT(("userlandfs_rewind_query() done: (%" B_PRIx32 ")\n", error));
return error;
}
static status_t
userlandfs_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
{
init_debugging();
PRINT(("userlandfs_std_ops(): B_MODULE_INIT\n"));
UserlandFS* userlandFS = NULL;
status_t error = UserlandFS::InitUserlandFS(&userlandFS);
if (error != B_OK) {
exit_debugging();
return error;
}
return B_OK;
}
case B_MODULE_UNINIT:
PRINT(("userlandfs_std_ops(): B_MODULE_UNINIT\n"));
UserlandFS::UninitUserlandFS();
exit_debugging();
return B_OK;
default:
return B_ERROR;
}
}
static file_system_module_info sUserlandFSModuleInfo = {
{
"file_systems/userlandfs" B_CURRENT_FS_API_VERSION,
0,
userlandfs_std_ops,
},
"userlandfs",
"Userland File System",
0,
NULL,
NULL,
NULL,
NULL,
&userlandfs_mount,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
fs_volume_ops gUserlandFSVolumeOps = {
&userlandfs_unmount,
&userlandfs_read_fs_info,
&userlandfs_write_fs_info,
&userlandfs_sync,
&userlandfs_get_vnode,
&userlandfs_open_index_dir,
&userlandfs_close_index_dir,
&userlandfs_free_index_dir_cookie,
&userlandfs_read_index_dir,
&userlandfs_rewind_index_dir,
&userlandfs_create_index,
&userlandfs_remove_index,
&userlandfs_read_index_stat,
&userlandfs_open_query,
&userlandfs_close_query,
&userlandfs_free_query_cookie,
&userlandfs_read_query,
&userlandfs_rewind_query,
NULL,
NULL,
NULL
};
fs_vnode_ops gUserlandFSVnodeOps = {
&userlandfs_lookup,
&userlandfs_get_vnode_name,
&userlandfs_put_vnode,
&userlandfs_remove_vnode,
NULL,
NULL,
NULL,
&userlandfs_io,
&userlandfs_cancel_io,
NULL,
&userlandfs_ioctl,
&userlandfs_set_flags,
&userlandfs_select,
&userlandfs_deselect,
&userlandfs_fsync,
&userlandfs_read_symlink,
&userlandfs_create_symlink,
&userlandfs_link,
&userlandfs_unlink,
&userlandfs_rename,
&userlandfs_access,
&userlandfs_read_stat,
&userlandfs_write_stat,
NULL,
&userlandfs_create,
&userlandfs_open,
&userlandfs_close,
&userlandfs_free_cookie,
&userlandfs_read,
&userlandfs_write,
&userlandfs_create_dir,
&userlandfs_remove_dir,
&userlandfs_open_dir,
&userlandfs_close_dir,
&userlandfs_free_dir_cookie,
&userlandfs_read_dir,
&userlandfs_rewind_dir,
&userlandfs_open_attr_dir,
&userlandfs_close_attr_dir,
&userlandfs_free_attr_dir_cookie,
&userlandfs_read_attr_dir,
&userlandfs_rewind_attr_dir,
&userlandfs_create_attr,
&userlandfs_open_attr,
&userlandfs_close_attr,
&userlandfs_free_attr_cookie,
&userlandfs_read_attr,
&userlandfs_write_attr,
&userlandfs_read_attr_stat,
&userlandfs_write_attr_stat,
&userlandfs_rename_attr,
&userlandfs_remove_attr,
NULL,
NULL
};
module_info *modules[] = {
(module_info *)&sUserlandFSModuleInfo,
NULL,
};