* Added support for interfacing with Haiku style FS modules (yet

untested).
* Added library with the relevant part of the Haiku kernel interface.
  The cache interface is missing, though.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20340 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-03-06 02:39:34 +00:00
parent 2f92537221
commit 4ed322c66e
13 changed files with 1409 additions and 95 deletions

View File

@ -14,7 +14,7 @@ BeOSKernelFileSystem::BeOSKernelFileSystem(beos_vnode_ops* fsOps)
: FileSystem(),
fFSOps(fsOps)
{
_InitCapabilities(fsOps);
_InitCapabilities();
}
// destructor
@ -49,7 +49,7 @@ BeOSKernelFileSystem::DeleteVolume(Volume* volume)
// _InitCapabilities
void
BeOSKernelFileSystem::_InitCapabilities(beos_vnode_ops* fsOps)
BeOSKernelFileSystem::_InitCapabilities()
{
fCapabilities.ClearAll();
@ -57,20 +57,20 @@ BeOSKernelFileSystem::_InitCapabilities(beos_vnode_ops* fsOps)
fCapabilities.clientFSType = CLIENT_FS_BEOS_KERNEL;
// FS operations
fCapabilities.Set(FS_CAPABILITY_MOUNT, fsOps->mount);
fCapabilities.Set(FS_CAPABILITY_UNMOUNT, fsOps->unmount);
fCapabilities.Set(FS_CAPABILITY_MOUNT, fFSOps->mount);
fCapabilities.Set(FS_CAPABILITY_UNMOUNT, fFSOps->unmount);
fCapabilities.Set(FS_CAPABILITY_READ_FS_INFO, fsOps->rfsstat);
fCapabilities.Set(FS_CAPABILITY_WRITE_FS_INFO, fsOps->wfsstat);
fCapabilities.Set(FS_CAPABILITY_SYNC, fsOps->sync);
fCapabilities.Set(FS_CAPABILITY_READ_FS_INFO, fFSOps->rfsstat);
fCapabilities.Set(FS_CAPABILITY_WRITE_FS_INFO, fFSOps->wfsstat);
fCapabilities.Set(FS_CAPABILITY_SYNC, fFSOps->sync);
// vnode operations
fCapabilities.Set(FS_CAPABILITY_LOOKUP, fsOps->walk);
fCapabilities.Set(FS_CAPABILITY_LOOKUP, fFSOps->walk);
// missing: FS_CAPABILITY_GET_VNODE_NAME,
fCapabilities.Set(FS_CAPABILITY_GET_VNODE, fsOps->read_vnode);
fCapabilities.Set(FS_CAPABILITY_PUT_VNODE, fsOps->write_vnode);
fCapabilities.Set(FS_CAPABILITY_REMOVE_VNODE, fsOps->remove_vnode);
fCapabilities.Set(FS_CAPABILITY_GET_VNODE, fFSOps->read_vnode);
fCapabilities.Set(FS_CAPABILITY_PUT_VNODE, fFSOps->write_vnode);
fCapabilities.Set(FS_CAPABILITY_REMOVE_VNODE, fFSOps->remove_vnode);
// VM file access
// missing: FS_CAPABILITY_CAN_PAGE,
@ -81,80 +81,81 @@ BeOSKernelFileSystem::_InitCapabilities(beos_vnode_ops* fsOps)
// missing: FS_CAPABILITY_GET_FILE_MAP,
// common operations
fCapabilities.Set(FS_CAPABILITY_IOCTL, fsOps->ioctl);
fCapabilities.Set(FS_CAPABILITY_SET_FLAGS, fsOps->setflags);
fCapabilities.Set(FS_CAPABILITY_SELECT, fsOps->select);
fCapabilities.Set(FS_CAPABILITY_DESELECT, fsOps->deselect);
fCapabilities.Set(FS_CAPABILITY_FSYNC, fsOps->fsync);
fCapabilities.Set(FS_CAPABILITY_IOCTL, fFSOps->ioctl);
fCapabilities.Set(FS_CAPABILITY_SET_FLAGS, fFSOps->setflags);
fCapabilities.Set(FS_CAPABILITY_SELECT, fFSOps->select);
fCapabilities.Set(FS_CAPABILITY_DESELECT, fFSOps->deselect);
fCapabilities.Set(FS_CAPABILITY_FSYNC, fFSOps->fsync);
fCapabilities.Set(FS_CAPABILITY_READ_SYMLINK, fsOps->readlink);
fCapabilities.Set(FS_CAPABILITY_CREATE_SYMLINK, fsOps->symlink);
fCapabilities.Set(FS_CAPABILITY_READ_SYMLINK, fFSOps->readlink);
fCapabilities.Set(FS_CAPABILITY_CREATE_SYMLINK, fFSOps->symlink);
fCapabilities.Set(FS_CAPABILITY_LINK, fsOps->link);
fCapabilities.Set(FS_CAPABILITY_UNLINK, fsOps->unlink);
fCapabilities.Set(FS_CAPABILITY_RENAME, fsOps->rename);
fCapabilities.Set(FS_CAPABILITY_LINK, fFSOps->link);
fCapabilities.Set(FS_CAPABILITY_UNLINK, fFSOps->unlink);
fCapabilities.Set(FS_CAPABILITY_RENAME, fFSOps->rename);
fCapabilities.Set(FS_CAPABILITY_ACCESS, fsOps->access);
fCapabilities.Set(FS_CAPABILITY_READ_STAT, fsOps->rstat);
fCapabilities.Set(FS_CAPABILITY_WRITE_STAT, fsOps->wstat);
fCapabilities.Set(FS_CAPABILITY_ACCESS, fFSOps->access);
fCapabilities.Set(FS_CAPABILITY_READ_STAT, fFSOps->rstat);
fCapabilities.Set(FS_CAPABILITY_WRITE_STAT, fFSOps->wstat);
// file operations
fCapabilities.Set(FS_CAPABILITY_CREATE, fsOps->create);
fCapabilities.Set(FS_CAPABILITY_OPEN, fsOps->open);
fCapabilities.Set(FS_CAPABILITY_CLOSE, fsOps->close);
fCapabilities.Set(FS_CAPABILITY_FREE_COOKIE, fsOps->free_cookie);
fCapabilities.Set(FS_CAPABILITY_READ, fsOps->read);
fCapabilities.Set(FS_CAPABILITY_WRITE, fsOps->write);
fCapabilities.Set(FS_CAPABILITY_CREATE, fFSOps->create);
fCapabilities.Set(FS_CAPABILITY_OPEN, fFSOps->open);
fCapabilities.Set(FS_CAPABILITY_CLOSE, fFSOps->close);
fCapabilities.Set(FS_CAPABILITY_FREE_COOKIE, fFSOps->free_cookie);
fCapabilities.Set(FS_CAPABILITY_READ, fFSOps->read);
fCapabilities.Set(FS_CAPABILITY_WRITE, fFSOps->write);
// directory operations
fCapabilities.Set(FS_CAPABILITY_CREATE_DIR, fsOps->mkdir);
fCapabilities.Set(FS_CAPABILITY_REMOVE_DIR, fsOps->rmdir);
fCapabilities.Set(FS_CAPABILITY_OPEN_DIR, fsOps->opendir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_DIR, fsOps->closedir);
fCapabilities.Set(FS_CAPABILITY_FREE_DIR_COOKIE, fsOps->free_dircookie);
fCapabilities.Set(FS_CAPABILITY_READ_DIR, fsOps->readdir);
fCapabilities.Set(FS_CAPABILITY_REWIND_DIR, fsOps->rewinddir);
fCapabilities.Set(FS_CAPABILITY_CREATE_DIR, fFSOps->mkdir);
fCapabilities.Set(FS_CAPABILITY_REMOVE_DIR, fFSOps->rmdir);
fCapabilities.Set(FS_CAPABILITY_OPEN_DIR, fFSOps->opendir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_DIR, fFSOps->closedir);
fCapabilities.Set(FS_CAPABILITY_FREE_DIR_COOKIE, fFSOps->free_dircookie);
fCapabilities.Set(FS_CAPABILITY_READ_DIR, fFSOps->readdir);
fCapabilities.Set(FS_CAPABILITY_REWIND_DIR, fFSOps->rewinddir);
// attribute directory operations
fCapabilities.Set(FS_CAPABILITY_OPEN_ATTR_DIR, fsOps->open_attrdir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_ATTR_DIR, fsOps->close_attrdir);
fCapabilities.Set(FS_CAPABILITY_OPEN_ATTR_DIR, fFSOps->open_attrdir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_ATTR_DIR, fFSOps->close_attrdir);
fCapabilities.Set(FS_CAPABILITY_FREE_ATTR_DIR_COOKIE,
fsOps->free_attrdircookie);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_DIR, fsOps->read_attrdir);
fCapabilities.Set(FS_CAPABILITY_REWIND_ATTR_DIR, fsOps->rewind_attrdir);
fFSOps->free_attrdircookie);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_DIR, fFSOps->read_attrdir);
fCapabilities.Set(FS_CAPABILITY_REWIND_ATTR_DIR, fFSOps->rewind_attrdir);
// attribute operations
// we emulate open_attr() and free_attr_dir_cookie() if either read_attr()
// or write_attr() is present
bool hasAttributes = (fsOps->read_attr || fsOps->write_attr);
bool hasAttributes = (fFSOps->read_attr || fFSOps->write_attr);
fCapabilities.Set(FS_CAPABILITY_CREATE_ATTR, hasAttributes);
fCapabilities.Set(FS_CAPABILITY_OPEN_ATTR, hasAttributes);
fCapabilities.Set(FS_CAPABILITY_CLOSE_ATTR, false);
fCapabilities.Set(FS_CAPABILITY_FREE_ATTR_COOKIE, hasAttributes);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR, fsOps->read_attr);
fCapabilities.Set(FS_CAPABILITY_WRITE_ATTR, fsOps->write_attr);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR, fFSOps->read_attr);
fCapabilities.Set(FS_CAPABILITY_WRITE_ATTR, fFSOps->write_attr);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_STAT, fsOps->stat_attr);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_STAT, fFSOps->stat_attr);
// missing: FS_CAPABILITY_WRITE_ATTR_STAT
fCapabilities.Set(FS_CAPABILITY_RENAME_ATTR, fsOps->rename_attr);
fCapabilities.Set(FS_CAPABILITY_REMOVE_ATTR, fsOps->remove_attr);
fCapabilities.Set(FS_CAPABILITY_RENAME_ATTR, fFSOps->rename_attr);
fCapabilities.Set(FS_CAPABILITY_REMOVE_ATTR, fFSOps->remove_attr);
// index directory & index operations
fCapabilities.Set(FS_CAPABILITY_OPEN_INDEX_DIR, fsOps->open_indexdir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_INDEX_DIR, fsOps->close_indexdir);
fCapabilities.Set(FS_CAPABILITY_OPEN_INDEX_DIR, fFSOps->open_indexdir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_INDEX_DIR, fFSOps->close_indexdir);
fCapabilities.Set(FS_CAPABILITY_FREE_INDEX_DIR_COOKIE,
fsOps->free_indexdircookie);
fCapabilities.Set(FS_CAPABILITY_READ_INDEX_DIR, fsOps->read_indexdir);
fCapabilities.Set(FS_CAPABILITY_REWIND_INDEX_DIR, fsOps->rewind_indexdir);
fFSOps->free_indexdircookie);
fCapabilities.Set(FS_CAPABILITY_READ_INDEX_DIR, fFSOps->read_indexdir);
fCapabilities.Set(FS_CAPABILITY_REWIND_INDEX_DIR, fFSOps->rewind_indexdir);
fCapabilities.Set(FS_CAPABILITY_CREATE_INDEX, fsOps->create_index);
fCapabilities.Set(FS_CAPABILITY_REMOVE_INDEX, fsOps->remove_index);
fCapabilities.Set(FS_CAPABILITY_READ_INDEX_STAT, fsOps->stat_index);
fCapabilities.Set(FS_CAPABILITY_CREATE_INDEX, fFSOps->create_index);
fCapabilities.Set(FS_CAPABILITY_REMOVE_INDEX, fFSOps->remove_index);
fCapabilities.Set(FS_CAPABILITY_READ_INDEX_STAT, fFSOps->stat_index);
// query operations
fCapabilities.Set(FS_CAPABILITY_OPEN_QUERY, fsOps->open_query);
fCapabilities.Set(FS_CAPABILITY_CLOSE_QUERY, fsOps->close_query);
fCapabilities.Set(FS_CAPABILITY_FREE_QUERY_COOKIE, fsOps->free_querycookie);
fCapabilities.Set(FS_CAPABILITY_READ_QUERY, fsOps->read_query);
fCapabilities.Set(FS_CAPABILITY_OPEN_QUERY, fFSOps->open_query);
fCapabilities.Set(FS_CAPABILITY_CLOSE_QUERY, fFSOps->close_query);
fCapabilities.Set(FS_CAPABILITY_FREE_QUERY_COOKIE,
fFSOps->free_querycookie);
fCapabilities.Set(FS_CAPABILITY_READ_QUERY, fFSOps->read_query);
// missing: FS_CAPABILITY_REWIND_QUERY,
}

View File

@ -18,7 +18,7 @@ public:
virtual status_t DeleteVolume(Volume* volume);
private:
void _InitCapabilities(beos_vnode_ops* fsOps);
void _InitCapabilities();
private:
beos_vnode_ops* fFSOps;

View File

@ -0,0 +1,159 @@
// HaikuKernelFileSystem.cpp
#include "HaikuKernelFileSystem.h"
#include <new>
#include <fs_interface.h>
#include "HaikuKernelVolume.h"
using std::nothrow;
// constructor
HaikuKernelFileSystem::HaikuKernelFileSystem(file_system_module_info* fsModule)
: FileSystem(),
fFSModule(fsModule)
{
_InitCapabilities();
}
// destructor
HaikuKernelFileSystem::~HaikuKernelFileSystem()
{
}
// CreateVolume
status_t
HaikuKernelFileSystem::CreateVolume(Volume** volume, mount_id id)
{
// check initialization and parameters
if (!fFSModule || !volume)
return B_BAD_VALUE;
// create the volume
*volume = new(nothrow) HaikuKernelVolume(this, id, fFSModule);
if (!*volume)
return B_NO_MEMORY;
return B_OK;
}
// DeleteVolume
status_t
HaikuKernelFileSystem::DeleteVolume(Volume* volume)
{
if (!volume || !dynamic_cast<HaikuKernelVolume*>(volume))
return B_BAD_VALUE;
delete volume;
return B_OK;
}
// _InitCapabilities
void
HaikuKernelFileSystem::_InitCapabilities()
{
fCapabilities.ClearAll();
// FS interface type
fCapabilities.clientFSType = CLIENT_FS_HAIKU_KERNEL;
// FS operations
fCapabilities.Set(FS_CAPABILITY_MOUNT, fFSModule->mount);
fCapabilities.Set(FS_CAPABILITY_UNMOUNT, fFSModule->unmount);
fCapabilities.Set(FS_CAPABILITY_READ_FS_INFO, fFSModule->read_fs_info);
fCapabilities.Set(FS_CAPABILITY_WRITE_FS_INFO, fFSModule->write_fs_info);
fCapabilities.Set(FS_CAPABILITY_SYNC, fFSModule->sync);
// vnode operations
fCapabilities.Set(FS_CAPABILITY_LOOKUP, fFSModule->lookup);
fCapabilities.Set(FS_CAPABILITY_GET_VNODE_NAME, fFSModule->get_vnode_name);
fCapabilities.Set(FS_CAPABILITY_GET_VNODE, fFSModule->get_vnode);
fCapabilities.Set(FS_CAPABILITY_PUT_VNODE, fFSModule->put_vnode);
fCapabilities.Set(FS_CAPABILITY_REMOVE_VNODE, fFSModule->remove_vnode);
// VM file access
fCapabilities.Set(FS_CAPABILITY_CAN_PAGE, fFSModule->can_page);
fCapabilities.Set(FS_CAPABILITY_READ_PAGES, fFSModule->read_pages);
fCapabilities.Set(FS_CAPABILITY_WRITE_PAGES, fFSModule->write_pages);
// cache file access
fCapabilities.Set(FS_CAPABILITY_GET_FILE_MAP, fFSModule->get_file_map);
// common operations
fCapabilities.Set(FS_CAPABILITY_IOCTL, fFSModule->ioctl);
fCapabilities.Set(FS_CAPABILITY_SET_FLAGS, fFSModule->set_flags);
fCapabilities.Set(FS_CAPABILITY_SELECT, fFSModule->select);
fCapabilities.Set(FS_CAPABILITY_DESELECT, fFSModule->deselect);
fCapabilities.Set(FS_CAPABILITY_FSYNC, fFSModule->fsync);
fCapabilities.Set(FS_CAPABILITY_READ_SYMLINK, fFSModule->read_symlink);
fCapabilities.Set(FS_CAPABILITY_CREATE_SYMLINK, fFSModule->create_symlink);
fCapabilities.Set(FS_CAPABILITY_LINK, fFSModule->link);
fCapabilities.Set(FS_CAPABILITY_UNLINK, fFSModule->unlink);
fCapabilities.Set(FS_CAPABILITY_RENAME, fFSModule->rename);
fCapabilities.Set(FS_CAPABILITY_ACCESS, fFSModule->access);
fCapabilities.Set(FS_CAPABILITY_READ_STAT, fFSModule->read_stat);
fCapabilities.Set(FS_CAPABILITY_WRITE_STAT, fFSModule->write_stat);
// file operations
fCapabilities.Set(FS_CAPABILITY_CREATE, fFSModule->create);
fCapabilities.Set(FS_CAPABILITY_OPEN, fFSModule->open);
fCapabilities.Set(FS_CAPABILITY_CLOSE, fFSModule->close);
fCapabilities.Set(FS_CAPABILITY_FREE_COOKIE, fFSModule->free_cookie);
fCapabilities.Set(FS_CAPABILITY_READ, fFSModule->read);
fCapabilities.Set(FS_CAPABILITY_WRITE, fFSModule->write);
// directory operations
fCapabilities.Set(FS_CAPABILITY_CREATE_DIR, fFSModule->create_dir);
fCapabilities.Set(FS_CAPABILITY_REMOVE_DIR, fFSModule->remove_dir);
fCapabilities.Set(FS_CAPABILITY_OPEN_DIR, fFSModule->open_dir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_DIR, fFSModule->close_dir);
fCapabilities.Set(FS_CAPABILITY_FREE_DIR_COOKIE, fFSModule->free_dir_cookie);
fCapabilities.Set(FS_CAPABILITY_READ_DIR, fFSModule->read_dir);
fCapabilities.Set(FS_CAPABILITY_REWIND_DIR, fFSModule->rewind_dir);
// attribute directory operations
fCapabilities.Set(FS_CAPABILITY_OPEN_ATTR_DIR, fFSModule->open_attr_dir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_ATTR_DIR, fFSModule->close_attr_dir);
fCapabilities.Set(FS_CAPABILITY_FREE_ATTR_DIR_COOKIE,
fFSModule->free_attr_dir_cookie);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_DIR, fFSModule->read_attr_dir);
fCapabilities.Set(FS_CAPABILITY_REWIND_ATTR_DIR, fFSModule->rewind_attr_dir);
// attribute operations
fCapabilities.Set(FS_CAPABILITY_CREATE_ATTR, fFSModule->create_attr);
fCapabilities.Set(FS_CAPABILITY_OPEN_ATTR, fFSModule->open_attr);
fCapabilities.Set(FS_CAPABILITY_CLOSE_ATTR, fFSModule->close_attr);
fCapabilities.Set(FS_CAPABILITY_FREE_ATTR_COOKIE,
fFSModule->free_attr_cookie);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR, fFSModule->read_attr);
fCapabilities.Set(FS_CAPABILITY_WRITE_ATTR, fFSModule->write_attr);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_STAT, fFSModule->read_attr_stat);
fCapabilities.Set(FS_CAPABILITY_READ_ATTR_STAT, fFSModule->write_attr_stat);
fCapabilities.Set(FS_CAPABILITY_RENAME_ATTR, fFSModule->rename_attr);
fCapabilities.Set(FS_CAPABILITY_REMOVE_ATTR, fFSModule->remove_attr);
// index directory & index operations
fCapabilities.Set(FS_CAPABILITY_OPEN_INDEX_DIR, fFSModule->open_index_dir);
fCapabilities.Set(FS_CAPABILITY_CLOSE_INDEX_DIR, fFSModule->close_index_dir);
fCapabilities.Set(FS_CAPABILITY_FREE_INDEX_DIR_COOKIE,
fFSModule->free_index_dir_cookie);
fCapabilities.Set(FS_CAPABILITY_READ_INDEX_DIR, fFSModule->read_index_dir);
fCapabilities.Set(FS_CAPABILITY_REWIND_INDEX_DIR, fFSModule->rewind_index_dir);
fCapabilities.Set(FS_CAPABILITY_CREATE_INDEX, fFSModule->create_index);
fCapabilities.Set(FS_CAPABILITY_REMOVE_INDEX, fFSModule->remove_index);
fCapabilities.Set(FS_CAPABILITY_READ_INDEX_STAT, fFSModule->read_index_stat);
// query operations
fCapabilities.Set(FS_CAPABILITY_OPEN_QUERY, fFSModule->open_query);
fCapabilities.Set(FS_CAPABILITY_CLOSE_QUERY, fFSModule->close_query);
fCapabilities.Set(FS_CAPABILITY_FREE_QUERY_COOKIE, fFSModule->free_query_cookie);
fCapabilities.Set(FS_CAPABILITY_READ_QUERY, fFSModule->read_query);
fCapabilities.Set(FS_CAPABILITY_REWIND_QUERY, fFSModule->rewind_query);
}

View File

@ -0,0 +1,32 @@
// HaikuKernelFileSystem.h
#ifndef USERLAND_FS_HAIKU_KERNEL_FILE_SYSTEM_H
#define USERLAND_FS_HAIKU_KERNEL_FILE_SYSTEM_H
#include "FileSystem.h"
struct file_system_module_info;
namespace UserlandFS {
class HaikuKernelFileSystem : public FileSystem {
public:
HaikuKernelFileSystem(
file_system_module_info* fsModule);
virtual ~HaikuKernelFileSystem();
virtual status_t CreateVolume(Volume** volume, mount_id id);
virtual status_t DeleteVolume(Volume* volume);
private:
void _InitCapabilities();
private:
file_system_module_info* fFSModule;
};
} // namespace UserlandFS
using UserlandFS::HaikuKernelFileSystem;
#endif // USERLAND_FS_HAIKU_KERNEL_FILE_SYSTEM_H

View File

@ -0,0 +1,675 @@
// HaikuKernelVolume.cpp
#include "HaikuKernelVolume.h"
#include <new>
#include <fcntl.h>
#include <unistd.h>
#include "Debug.h"
#include "kernel_emu.h"
// constructor
HaikuKernelVolume::HaikuKernelVolume(FileSystem* fileSystem, mount_id id,
file_system_module_info* fsModule)
: Volume(fileSystem, id),
fFSModule(fsModule),
fVolumeCookie(NULL)
{
}
// destructor
HaikuKernelVolume::~HaikuKernelVolume()
{
}
// #pragma mark -
// #pragma mark ----- FS -----
// Mount
status_t
HaikuKernelVolume::Mount(const char* device, uint32 flags,
const char* parameters, vnode_id* rootID)
{
if (!fFSModule->mount)
return B_BAD_VALUE;
return fFSModule->mount(GetID(), device, flags, parameters, &fVolumeCookie,
rootID);
}
// Unmount
status_t
HaikuKernelVolume::Unmount()
{
if (!fFSModule->unmount)
return B_BAD_VALUE;
return fFSModule->unmount(fVolumeCookie);
}
// Sync
status_t
HaikuKernelVolume::Sync()
{
if (!fFSModule->sync)
return B_BAD_VALUE;
return fFSModule->sync(fVolumeCookie);
}
// ReadFSInfo
status_t
HaikuKernelVolume::ReadFSInfo(fs_info* info)
{
if (!fFSModule->read_fs_info)
return B_BAD_VALUE;
return fFSModule->read_fs_info(fVolumeCookie, info);
}
// WriteFSInfo
status_t
HaikuKernelVolume::WriteFSInfo(const struct fs_info* info, uint32 mask)
{
if (!fFSModule->write_fs_info)
return B_BAD_VALUE;
return fFSModule->write_fs_info(fVolumeCookie, info, mask);
}
// #pragma mark - vnodes
// Lookup
status_t
HaikuKernelVolume::Lookup(fs_vnode dir, const char* entryName, vnode_id* vnid,
int* type)
{
if (!fFSModule->lookup)
return B_BAD_VALUE;
return fFSModule->lookup(fVolumeCookie, dir, entryName, vnid, type);
}
// ReadVNode
status_t
HaikuKernelVolume::ReadVNode(vnode_id vnid, bool reenter, fs_vnode* node)
{
if (!fFSModule->get_vnode)
return B_BAD_VALUE;
return fFSModule->get_vnode(fVolumeCookie, vnid, node, reenter);
}
// WriteVNode
status_t
HaikuKernelVolume::WriteVNode(fs_vnode node, bool reenter)
{
if (!fFSModule->put_vnode)
return B_BAD_VALUE;
return fFSModule->put_vnode(fVolumeCookie, node, reenter);
}
// RemoveVNode
status_t
HaikuKernelVolume::RemoveVNode(fs_vnode node, bool reenter)
{
if (!fFSModule->remove_vnode)
return B_BAD_VALUE;
return fFSModule->remove_vnode(fVolumeCookie, node, reenter);
}
// #pragma mark - nodes
// IOCtl
status_t
HaikuKernelVolume::IOCtl(fs_vnode node, fs_cookie cookie, uint32 command,
void* buffer, size_t size)
{
if (!fFSModule->ioctl)
return B_BAD_VALUE;
return fFSModule->ioctl(fVolumeCookie, node, cookie, command, buffer,
size);
}
// SetFlags
status_t
HaikuKernelVolume::SetFlags(fs_vnode node, fs_cookie cookie, int flags)
{
if (!fFSModule->set_flags)
return B_BAD_VALUE;
return fFSModule->set_flags(fVolumeCookie, node, cookie, flags);
}
// Select
status_t
HaikuKernelVolume::Select(fs_vnode node, fs_cookie cookie, uint8 event,
uint32 ref, selectsync* sync)
{
if (!fFSModule->select) {
UserlandFS::KernelEmu::notify_select_event(sync, ref, event, false);
return B_OK;
}
return fFSModule->select(fVolumeCookie, node, cookie, event, ref, sync);
}
// Deselect
status_t
HaikuKernelVolume::Deselect(fs_vnode node, fs_cookie cookie, uint8 event,
selectsync* sync)
{
if (!fFSModule->select || !fFSModule->deselect)
return B_OK;
return fFSModule->deselect(fVolumeCookie, node, cookie, event, sync);
}
// FSync
status_t
HaikuKernelVolume::FSync(fs_vnode node)
{
if (!fFSModule->fsync)
return B_BAD_VALUE;
return fFSModule->fsync(fVolumeCookie, node);
}
// ReadSymlink
status_t
HaikuKernelVolume::ReadSymlink(fs_vnode node, char* buffer, size_t bufferSize,
size_t* bytesRead)
{
if (!fFSModule->read_symlink)
return B_BAD_VALUE;
*bytesRead = bufferSize;
return fFSModule->read_symlink(fVolumeCookie, node, buffer, bytesRead);
}
// CreateSymlink
status_t
HaikuKernelVolume::CreateSymlink(fs_vnode dir, const char* name,
const char* target, int mode)
{
if (!fFSModule->create_symlink)
return B_BAD_VALUE;
return fFSModule->create_symlink(fVolumeCookie, dir, name, target, mode);
}
// Link
status_t
HaikuKernelVolume::Link(fs_vnode dir, const char* name, fs_vnode node)
{
if (!fFSModule->link)
return B_BAD_VALUE;
return fFSModule->link(fVolumeCookie, dir, name, node);
}
// Unlink
status_t
HaikuKernelVolume::Unlink(fs_vnode dir, const char* name)
{
if (!fFSModule->unlink)
return B_BAD_VALUE;
return fFSModule->unlink(fVolumeCookie, dir, name);
}
// Rename
status_t
HaikuKernelVolume::Rename(fs_vnode oldDir, const char* oldName, fs_vnode newDir,
const char* newName)
{
if (!fFSModule->rename)
return B_BAD_VALUE;
return fFSModule->rename(fVolumeCookie, oldDir, oldName, newDir, newName);
}
// Access
status_t
HaikuKernelVolume::Access(fs_vnode node, int mode)
{
if (!fFSModule->access)
return B_OK;
return fFSModule->access(fVolumeCookie, node, mode);
}
// ReadStat
status_t
HaikuKernelVolume::ReadStat(fs_vnode node, struct stat* st)
{
if (!fFSModule->read_stat)
return B_BAD_VALUE;
return fFSModule->read_stat(fVolumeCookie, node, st);
}
// WriteStat
status_t
HaikuKernelVolume::WriteStat(fs_vnode node, const struct stat *st, uint32 mask)
{
if (!fFSModule->write_stat)
return B_BAD_VALUE;
return fFSModule->write_stat(fVolumeCookie, node, st, mask);
}
// #pragma mark - files
// Create
status_t
HaikuKernelVolume::Create(fs_vnode dir, const char* name, int openMode, int mode,
fs_cookie* cookie, vnode_id* vnid)
{
if (!fFSModule->create)
return B_BAD_VALUE;
return fFSModule->create(fVolumeCookie, dir, name, openMode, mode, cookie,
vnid);
}
// Open
status_t
HaikuKernelVolume::Open(fs_vnode node, int openMode, fs_cookie* cookie)
{
if (!fFSModule->open)
return B_BAD_VALUE;
return fFSModule->open(fVolumeCookie, node, openMode, cookie);
}
// Close
status_t
HaikuKernelVolume::Close(fs_vnode node, fs_cookie cookie)
{
if (!fFSModule->close)
return B_OK;
return fFSModule->close(fVolumeCookie, node, cookie);
}
// FreeCookie
status_t
HaikuKernelVolume::FreeCookie(fs_vnode node, fs_cookie cookie)
{
if (!fFSModule->free_cookie)
return B_OK;
return fFSModule->free_cookie(fVolumeCookie, node, cookie);
}
// Read
status_t
HaikuKernelVolume::Read(fs_vnode node, fs_cookie cookie, off_t pos, void* buffer,
size_t bufferSize, size_t* bytesRead)
{
if (!fFSModule->read)
return B_BAD_VALUE;
*bytesRead = bufferSize;
return fFSModule->read(fVolumeCookie, node, cookie, pos, buffer, bytesRead);
}
// Write
status_t
HaikuKernelVolume::Write(fs_vnode node, fs_cookie cookie, off_t pos,
const void* buffer, size_t bufferSize, size_t* bytesWritten)
{
if (!fFSModule->write)
return B_BAD_VALUE;
*bytesWritten = bufferSize;
return fFSModule->write(fVolumeCookie, node, cookie, pos, buffer,
bytesWritten);
}
// #pragma mark - directories
// CreateDir
status_t
HaikuKernelVolume::CreateDir(fs_vnode dir, const char* name, int mode,
vnode_id *newDir)
{
if (!fFSModule->create_dir)
return B_BAD_VALUE;
return fFSModule->create_dir(fVolumeCookie, dir, name, mode, newDir);
}
// RemoveDir
status_t
HaikuKernelVolume::RemoveDir(fs_vnode dir, const char* name)
{
if (!fFSModule->remove_dir)
return B_BAD_VALUE;
return fFSModule->remove_dir(fVolumeCookie, dir, name);
}
// OpenDir
status_t
HaikuKernelVolume::OpenDir(fs_vnode node, fs_cookie* cookie)
{
if (!fFSModule->open_dir)
return B_BAD_VALUE;
return fFSModule->open_dir(fVolumeCookie, node, cookie);
}
// CloseDir
status_t
HaikuKernelVolume::CloseDir(fs_vnode node, fs_vnode cookie)
{
if (!fFSModule->close_dir)
return B_OK;
return fFSModule->close_dir(fVolumeCookie, node, cookie);
}
// FreeDirCookie
status_t
HaikuKernelVolume::FreeDirCookie(fs_vnode node, fs_vnode cookie)
{
if (!fFSModule->free_dir_cookie)
return B_OK;
return fFSModule->free_dir_cookie(fVolumeCookie, node, cookie);
}
// ReadDir
status_t
HaikuKernelVolume::ReadDir(fs_vnode node, fs_vnode cookie, void* buffer,
size_t bufferSize, uint32 count, uint32* countRead)
{
if (!fFSModule->read_dir)
return B_BAD_VALUE;
*countRead = count;
return fFSModule->read_dir(fVolumeCookie, node, cookie,
(struct dirent*)buffer, bufferSize, countRead);
}
// RewindDir
status_t
HaikuKernelVolume::RewindDir(fs_vnode node, fs_vnode cookie)
{
if (!fFSModule->rewind_dir)
return B_BAD_VALUE;
return fFSModule->rewind_dir(fVolumeCookie, node, cookie);
}
// #pragma mark - attribute directories
// OpenAttrDir
status_t
HaikuKernelVolume::OpenAttrDir(fs_vnode node, fs_cookie *cookie)
{
if (!fFSModule->open_attr_dir)
return B_BAD_VALUE;
return fFSModule->open_attr_dir(fVolumeCookie, node, cookie);
}
// CloseAttrDir
status_t
HaikuKernelVolume::CloseAttrDir(fs_vnode node, fs_cookie cookie)
{
if (!fFSModule->close_attr_dir)
return B_OK;
return fFSModule->close_attr_dir(fVolumeCookie, node, cookie);
}
// FreeAttrDirCookie
status_t
HaikuKernelVolume::FreeAttrDirCookie(fs_vnode node, fs_cookie cookie)
{
if (!fFSModule->free_attr_dir_cookie)
return B_OK;
return fFSModule->free_attr_dir_cookie(fVolumeCookie, node, cookie);
}
// ReadAttrDir
status_t
HaikuKernelVolume::ReadAttrDir(fs_vnode node, fs_cookie cookie, void* buffer,
size_t bufferSize, uint32 count, uint32* countRead)
{
if (!fFSModule->read_attr_dir)
return B_BAD_VALUE;
*countRead = count;
return fFSModule->read_attr_dir(fVolumeCookie, node, cookie,
(struct dirent*)buffer, bufferSize, countRead);
}
// RewindAttrDir
status_t
HaikuKernelVolume::RewindAttrDir(fs_vnode node, fs_cookie cookie)
{
if (!fFSModule->rewind_attr_dir)
return B_BAD_VALUE;
return fFSModule->rewind_attr_dir(fVolumeCookie, node, cookie);
}
// #pragma mark - attributes
// CreateAttr
status_t
HaikuKernelVolume::CreateAttr(fs_vnode node, const char* name, uint32 type,
int openMode, fs_cookie* cookie)
{
if (!fFSModule->create_attr)
return B_BAD_VALUE;
return fFSModule->create_attr(fVolumeCookie, node, name, type, openMode,
cookie);
}
// OpenAttr
status_t
HaikuKernelVolume::OpenAttr(fs_vnode node, const char* name, int openMode,
fs_cookie* cookie)
{
if (!fFSModule->open_attr)
return B_BAD_VALUE;
return fFSModule->open_attr(fVolumeCookie, node, name, openMode, cookie);
}
// CloseAttr
status_t
HaikuKernelVolume::CloseAttr(fs_vnode node, fs_cookie cookie)
{
if (!fFSModule->close_attr)
return B_OK;
return fFSModule->close_attr(fVolumeCookie, node, cookie);
}
// FreeAttrCookie
status_t
HaikuKernelVolume::FreeAttrCookie(fs_vnode node, fs_cookie cookie)
{
if (!fFSModule->free_attr_cookie)
return B_OK;
return fFSModule->free_attr_cookie(fVolumeCookie, node, cookie);
}
// ReadAttr
status_t
HaikuKernelVolume::ReadAttr(fs_vnode node, fs_cookie cookie, off_t pos,
void* buffer, size_t bufferSize, size_t* bytesRead)
{
if (!fFSModule->read_attr)
return B_BAD_VALUE;
*bytesRead = bufferSize;
return fFSModule->read_attr(fVolumeCookie, node, cookie, pos, buffer,
bytesRead);
}
// WriteAttr
status_t
HaikuKernelVolume::WriteAttr(fs_vnode node, fs_cookie cookie, off_t pos,
const void* buffer, size_t bufferSize, size_t* bytesWritten)
{
if (!fFSModule->write_attr)
return B_BAD_VALUE;
*bytesWritten = bufferSize;
return fFSModule->write_attr(fVolumeCookie, node, cookie, pos, buffer,
bytesWritten);
}
// ReadAttrStat
status_t
HaikuKernelVolume::ReadAttrStat(fs_vnode node, fs_cookie cookie,
struct stat *st)
{
if (!fFSModule->read_attr_stat)
return B_BAD_VALUE;
return fFSModule->read_attr_stat(fVolumeCookie, node, cookie, st);
}
// RenameAttr
status_t
HaikuKernelVolume::RenameAttr(fs_vnode oldNode, const char* oldName,
fs_vnode newNode, const char* newName)
{
if (!fFSModule->rename_attr)
return B_BAD_VALUE;
return fFSModule->rename_attr(fVolumeCookie, oldNode, oldName, newNode,
newName);
}
// RemoveAttr
status_t
HaikuKernelVolume::RemoveAttr(fs_vnode node, const char* name)
{
if (!fFSModule->remove_attr)
return B_BAD_VALUE;
return fFSModule->remove_attr(fVolumeCookie, node, name);
}
// #pragma mark - indices
// OpenIndexDir
status_t
HaikuKernelVolume::OpenIndexDir(fs_cookie *cookie)
{
if (!fFSModule->open_index_dir)
return B_BAD_VALUE;
return fFSModule->open_index_dir(fVolumeCookie, cookie);
}
// CloseIndexDir
status_t
HaikuKernelVolume::CloseIndexDir(fs_cookie cookie)
{
if (!fFSModule->close_index_dir)
return B_OK;
return fFSModule->close_index_dir(fVolumeCookie, cookie);
}
// FreeIndexDirCookie
status_t
HaikuKernelVolume::FreeIndexDirCookie(fs_cookie cookie)
{
if (!fFSModule->free_index_dir_cookie)
return B_OK;
return fFSModule->free_index_dir_cookie(fVolumeCookie, cookie);
}
// ReadIndexDir
status_t
HaikuKernelVolume::ReadIndexDir(fs_cookie cookie, void* buffer,
size_t bufferSize, uint32 count, uint32* countRead)
{
if (!fFSModule->read_index_dir)
return B_BAD_VALUE;
*countRead = count;
return fFSModule->read_index_dir(fVolumeCookie, cookie,
(struct dirent*)buffer, bufferSize, countRead);
}
// RewindIndexDir
status_t
HaikuKernelVolume::RewindIndexDir(fs_cookie cookie)
{
if (!fFSModule->rewind_index_dir)
return B_BAD_VALUE;
return fFSModule->rewind_index_dir(fVolumeCookie, cookie);
}
// CreateIndex
status_t
HaikuKernelVolume::CreateIndex(const char* name, uint32 type, uint32 flags)
{
if (!fFSModule->create_index)
return B_BAD_VALUE;
return fFSModule->create_index(fVolumeCookie, name, type, flags);
}
// RemoveIndex
status_t
HaikuKernelVolume::RemoveIndex(const char* name)
{
if (!fFSModule->remove_index)
return B_BAD_VALUE;
return fFSModule->remove_index(fVolumeCookie, name);
}
// StatIndex
status_t
HaikuKernelVolume::ReadIndexStat(const char *name, struct stat *st)
{
if (!fFSModule->read_index_stat)
return B_BAD_VALUE;
return fFSModule->read_index_stat(fVolumeCookie, name, st);
}
// #pragma mark - queries
// OpenQuery
status_t
HaikuKernelVolume::OpenQuery(const char* queryString, uint32 flags,
port_id port, uint32 token, fs_cookie *cookie)
{
if (!fFSModule->open_query)
return B_BAD_VALUE;
return fFSModule->open_query(fVolumeCookie, queryString, flags, port,
token, cookie);
}
// CloseQuery
status_t
HaikuKernelVolume::CloseQuery(fs_cookie cookie)
{
if (!fFSModule->close_query)
return B_OK;
return fFSModule->close_query(fVolumeCookie, cookie);
}
// FreeQueryCookie
status_t
HaikuKernelVolume::FreeQueryCookie(fs_cookie cookie)
{
if (!fFSModule->free_query_cookie)
return B_OK;
return fFSModule->free_query_cookie(fVolumeCookie, cookie);
}
// ReadQuery
status_t
HaikuKernelVolume::ReadQuery(fs_cookie cookie, void* buffer, size_t bufferSize,
uint32 count, uint32* countRead)
{
if (!fFSModule->read_query)
return B_BAD_VALUE;
*countRead = count;
return fFSModule->read_query(fVolumeCookie, cookie, (struct dirent*)buffer,
bufferSize, countRead);
}

View File

@ -0,0 +1,155 @@
// HaikuKernelVolume.h
#ifndef USERLAND_FS_BEOS_KERNEL_VOLUME_H
#define USERLAND_FS_BEOS_KERNEL_VOLUME_H
#include <fs_interface.h>
#include "Volume.h"
namespace UserlandFS {
class HaikuKernelVolume : public Volume {
public:
HaikuKernelVolume(FileSystem* fileSystem,
mount_id id,
file_system_module_info* fsModule);
virtual ~HaikuKernelVolume();
// FS
virtual status_t Mount(const char* device, uint32 flags,
const char* parameters, vnode_id* rootID);
virtual status_t Unmount();
virtual status_t Sync();
virtual status_t ReadFSInfo(fs_info* info);
virtual status_t WriteFSInfo(const struct fs_info* info,
uint32 mask);
// vnodes
virtual status_t Lookup(fs_vnode dir, const char* entryName,
vnode_id* vnid, int* type);
virtual status_t ReadVNode(vnode_id vnid, bool reenter,
fs_vnode* node);
virtual status_t WriteVNode(fs_vnode node, bool reenter);
virtual status_t RemoveVNode(fs_vnode node, bool reenter);
// nodes
virtual status_t IOCtl(fs_vnode node, fs_cookie cookie,
uint32 command, void* buffer, size_t size);
virtual status_t SetFlags(fs_vnode node, fs_cookie cookie,
int flags);
virtual status_t Select(fs_vnode node, fs_cookie cookie,
uint8 event, uint32 ref, selectsync* sync);
virtual status_t Deselect(fs_vnode node, fs_cookie cookie,
uint8 event, selectsync* sync);
virtual status_t FSync(fs_vnode node);
virtual status_t ReadSymlink(fs_vnode node, char* buffer,
size_t bufferSize, size_t* bytesRead);
virtual status_t CreateSymlink(fs_vnode dir, const char* name,
const char* target, int mode);
virtual status_t Link(fs_vnode dir, const char* name,
fs_vnode node);
virtual status_t Unlink(fs_vnode dir, const char* name);
virtual status_t Rename(fs_vnode oldDir, const char* oldName,
fs_vnode newDir, const char* newName);
virtual status_t Access(fs_vnode node, int mode);
virtual status_t ReadStat(fs_vnode node, struct stat* st);
virtual status_t WriteStat(fs_vnode node, const struct stat *st,
uint32 mask);
// files
virtual status_t Create(fs_vnode dir, const char* name,
int openMode, int mode, fs_cookie* cookie,
vnode_id* vnid);
virtual status_t Open(fs_vnode node, int openMode,
fs_cookie* cookie);
virtual status_t Close(fs_vnode node, fs_cookie cookie);
virtual status_t FreeCookie(fs_vnode node, fs_cookie cookie);
virtual status_t Read(fs_vnode node, fs_cookie cookie, off_t pos,
void* buffer, size_t bufferSize,
size_t* bytesRead);
virtual status_t Write(fs_vnode node, fs_cookie cookie,
off_t pos, const void* buffer,
size_t bufferSize, size_t* bytesWritten);
// directories
virtual status_t CreateDir(fs_vnode dir, const char* name,
int mode, vnode_id *newDir);
virtual status_t RemoveDir(fs_vnode dir, const char* name);
virtual status_t OpenDir(fs_vnode node, fs_cookie* cookie);
virtual status_t CloseDir(fs_vnode node, fs_vnode cookie);
virtual status_t FreeDirCookie(fs_vnode node, fs_vnode cookie);
virtual status_t ReadDir(fs_vnode node, fs_vnode cookie,
void* buffer, size_t bufferSize,
uint32 count, uint32* countRead);
virtual status_t RewindDir(fs_vnode node, fs_vnode cookie);
// attribute directories
virtual status_t OpenAttrDir(fs_vnode node, fs_cookie *cookie);
virtual status_t CloseAttrDir(fs_vnode node, fs_cookie cookie);
virtual status_t FreeAttrDirCookie(fs_vnode node,
fs_cookie cookie);
virtual status_t ReadAttrDir(fs_vnode node, fs_cookie cookie,
void* buffer, size_t bufferSize,
uint32 count, uint32* countRead);
virtual status_t RewindAttrDir(fs_vnode node, fs_cookie cookie);
// attributes
virtual status_t CreateAttr(fs_vnode node, const char *name,
uint32 type, int openMode,
fs_cookie *cookie);
virtual status_t OpenAttr(fs_vnode node, const char *name,
int openMode, fs_cookie *cookie);
virtual status_t CloseAttr(fs_vnode node, fs_cookie cookie);
virtual status_t FreeAttrCookie(fs_vnode node, fs_cookie cookie);
virtual status_t ReadAttr(fs_vnode node, fs_cookie cookie,
off_t pos, void* buffer, size_t bufferSize,
size_t* bytesRead);
virtual status_t WriteAttr(fs_vnode node, fs_cookie cookie,
off_t pos, const void* buffer,
size_t bufferSize, size_t* bytesWritten);
virtual status_t ReadAttrStat(fs_vnode node, fs_cookie cookie,
struct stat *st);
virtual status_t RenameAttr(fs_vnode oldNode,
const char* oldName, fs_vnode newNode,
const char* newName);
virtual status_t RemoveAttr(fs_vnode node, const char* name);
// indices
virtual status_t OpenIndexDir(fs_cookie *cookie);
virtual status_t CloseIndexDir(fs_cookie cookie);
virtual status_t FreeIndexDirCookie(fs_cookie cookie);
virtual status_t ReadIndexDir(fs_cookie cookie, void* buffer,
size_t bufferSize, uint32 count,
uint32* countRead);
virtual status_t RewindIndexDir(fs_cookie cookie);
virtual status_t CreateIndex(const char* name, uint32 type,
uint32 flags);
virtual status_t RemoveIndex(const char* name);
virtual status_t ReadIndexStat(const char *name,
struct stat *st);
// queries
virtual status_t OpenQuery(const char* queryString,
uint32 flags, port_id port, uint32 token,
fs_cookie *cookie);
virtual status_t CloseQuery(fs_cookie cookie);
virtual status_t FreeQueryCookie(fs_cookie cookie);
virtual status_t ReadQuery(fs_cookie cookie, void* buffer,
size_t bufferSize, uint32 count,
uint32* countRead);
private:
file_system_module_info* fFSModule;
fs_cookie fVolumeCookie;
};
} // namespace UserlandFS
using UserlandFS::HaikuKernelVolume;
#endif // USERLAND_FS_BEOS_KERNEL_VOLUME_H

View File

@ -40,6 +40,8 @@ Application UserlandFSServer
BeOSKernelVolume.cpp
DispatcherFileSystem.cpp
FileSystem.cpp
HaikuKernelFileSystem.cpp
HaikuKernelVolume.cpp
kernel_emu.cpp
main.cpp
RequestThread.cpp
@ -56,3 +58,9 @@ SharedLibrary libuserlandfs_beos_kernel.so
: beos_kernel_emu.cpp
: <nogrist>UserlandFSServer
;
# the library providing the Haiku kernel interface for add-ons
SharedLibrary libuserlandfs_haiku_kernel.so
: haiku_kernel_emu.cpp
: <nogrist>UserlandFSServer
;

View File

@ -10,10 +10,10 @@
#include <Clipboard.h>
#include <FindDirectory.h>
#include <fs_interface.h>
#include <image.h>
#include <Locker.h>
#include <Path.h>
#include "AutoDeleter.h"
#include "AutoLocker.h"
#include "beos_fs_cache.h"
#include "beos_fs_interface.h"
@ -23,6 +23,7 @@
#include "DispatcherDefs.h"
#include "FileSystem.h"
#include "FSInfo.h"
#include "HaikuKernelFileSystem.h"
#include "RequestThread.h"
#include "ServerDefs.h"
@ -80,32 +81,17 @@ UserlandFSServer::Init(const char* fileSystem)
if (fAddOnImage < 0)
RETURN_ERROR(fAddOnImage);
// get the symbols "fs_entry" and "api_version"
beos_vnode_ops* fsOps;
error = get_image_symbol(fAddOnImage, "fs_entry", B_SYMBOL_TYPE_DATA,
(void**)&fsOps);
if (error != B_OK)
RETURN_ERROR(error);
int32* apiVersion;
error = get_image_symbol(fAddOnImage, "api_version", B_SYMBOL_TYPE_DATA,
(void**)&apiVersion);
if (error != B_OK)
RETURN_ERROR(error);
// check api version
if (*apiVersion != BEOS_FS_API_VERSION)
RETURN_ERROR(B_ERROR);
// create the file system
fFileSystem = new(nothrow) BeOSKernelFileSystem(fsOps);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
// init the block cache
error = beos_init_block_cache(kMaxBlockCacheBlocks, 0);
if (error != B_OK)
RETURN_ERROR(error);
fBlockCacheInitialized = true;
// create the FileSystem interface
// BeOS kernel interface
if (_CreateBeOSKernelInterface(fileSystem, fAddOnImage, &fFileSystem)
== B_OK) {
// BeOS interface
} else if (_CreateHaikuKernelInterface(fileSystem, fAddOnImage,
&fFileSystem) == B_OK) {
// Haiku interface
} else {
ERROR(("Add-on doesn't has a supported interface.\n"));
}
// create the notification request port
fNotificationRequestPort = new(nothrow) RequestPort(kRequestPortSize);
@ -216,3 +202,79 @@ UserlandFSServer::_RegisterWithDispatcher(const char* fsName)
return error;
}
// _CreateBeOSKernelInterface
status_t
UserlandFSServer::_CreateBeOSKernelInterface(const char* fsName, image_id image,
FileSystem** _fileSystem)
{
// get the symbols "fs_entry" and "api_version"
beos_vnode_ops* fsOps;
status_t error = get_image_symbol(image, "fs_entry", B_SYMBOL_TYPE_DATA,
(void**)&fsOps);
if (error != B_OK)
RETURN_ERROR(error);
int32* apiVersion;
error = get_image_symbol(image, "api_version", B_SYMBOL_TYPE_DATA,
(void**)&apiVersion);
if (error != B_OK)
RETURN_ERROR(error);
// check api version
if (*apiVersion != BEOS_FS_API_VERSION)
RETURN_ERROR(B_ERROR);
// create the file system
BeOSKernelFileSystem* fileSystem = new(nothrow) BeOSKernelFileSystem(fsOps);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
ObjectDeleter<BeOSKernelFileSystem> fsDeleter(fileSystem);
// init the block cache
error = beos_init_block_cache(kMaxBlockCacheBlocks, 0);
if (error != B_OK)
RETURN_ERROR(error);
fBlockCacheInitialized = true;
// everything went fine
fsDeleter.Detach();
*_fileSystem = fileSystem;
return B_OK;
}
// _CreateHaikuKernelInterface
status_t
UserlandFSServer::_CreateHaikuKernelInterface(const char* fsName,
image_id image, FileSystem** _fileSystem)
{
// get the modules
module_info** modules;
status_t error = get_image_symbol(image, "modules", B_SYMBOL_TYPE_DATA,
(void**)&modules);
if (error != B_OK)
RETURN_ERROR(error);
// module name must match "file_systems/<name>/v1"
char moduleName[B_PATH_NAME_LENGTH];
snprintf(moduleName, sizeof(moduleName), "file_systems/%s/v1", fsName);
// find the module
file_system_module_info* module = NULL;
for (int32 i = 0; modules[i]->name; i++) {
if (strcmp(modules[i]->name, moduleName) == 0) {
module = (file_system_module_info*)modules[i];
break;
}
}
if (!module)
RETURN_ERROR(B_ERROR);
// create the file system
HaikuKernelFileSystem* fileSystem
= new(nothrow) HaikuKernelFileSystem(module);
if (!fileSystem)
RETURN_ERROR(B_NO_MEMORY);
// everything went fine
*_fileSystem = fileSystem;
return B_OK;
}

View File

@ -4,6 +4,7 @@
#define USERLAND_FS_SERVER_H
#include <Application.h>
#include <image.h>
namespace UserlandFSUtil {
class RequestPort;
@ -27,6 +28,11 @@ public:
private:
status_t _RegisterWithDispatcher(const char* fsName);
status_t _CreateBeOSKernelInterface(const char* fsName,
image_id image, FileSystem** fileSystem);
status_t _CreateHaikuKernelInterface(const char* fsName,
image_id image, FileSystem** fileSystem);
private:
image_id fAddOnImage;
FileSystem* fFileSystem;

View File

@ -175,7 +175,7 @@ is_vnode_removed(nspace_id nsid, vnode_id vnid)
}
// #pragma mark - Block Cache
// #pragma mark - Locking
int

View File

@ -0,0 +1,213 @@
// beos_kernel_emu.cpp
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <fs_interface.h>
#include <KernelExport.h>
#include <NodeMonitor.h>
#include "Debug.h"
#include "kernel_emu.h"
// #pragma mark - Notifications
// notify_entry_created
status_t
notify_entry_created(mount_id device, vnode_id directory, const char *name,
vnode_id node)
{
if (!name)
return B_BAD_VALUE;
return UserlandFS::KernelEmu::notify_listener(B_ENTRY_CREATED, 0, device, 0,
directory, node, NULL, name);
}
// notify_entry_removed
status_t
notify_entry_removed(mount_id device, vnode_id directory, const char *name,
vnode_id node)
{
if (!name)
return B_BAD_VALUE;
return UserlandFS::KernelEmu::notify_listener(B_ENTRY_REMOVED, 0, device, 0,
directory, node, NULL, name);
}
// notify_entry_moved
status_t
notify_entry_moved(mount_id device, vnode_id fromDirectory,
const char *fromName, vnode_id toDirectory, const char *toName,
vnode_id node)
{
if (!fromName || !toName)
return B_BAD_VALUE;
return UserlandFS::KernelEmu::notify_listener(B_ENTRY_MOVED, 0, device,
fromDirectory, toDirectory, node, fromName, toName);
}
// notify_stat_changed
status_t
notify_stat_changed(mount_id device, vnode_id node, uint32 statFields)
{
return UserlandFS::KernelEmu::notify_listener(B_STAT_CHANGED, statFields,
device, 0, 0, node, NULL, NULL);
}
// notify_attribute_changed
status_t
notify_attribute_changed(mount_id device, vnode_id node, const char *attribute,
int32 cause)
{
if (!attribute)
return B_BAD_VALUE;
return UserlandFS::KernelEmu::notify_listener(B_ATTR_CHANGED, cause,
device, 0, 0, node, NULL, attribute);
}
// notify_select_event
status_t
notify_select_event(selectsync *sync, uint32 ref, uint8 event)
{
return UserlandFS::KernelEmu::notify_select_event(sync, ref, event, false);
}
// notify_query_entry_created
status_t
notify_query_entry_created(port_id port, int32 token, mount_id device,
vnode_id directory, const char *name, vnode_id node)
{
if (!name)
return B_BAD_VALUE;
return UserlandFS::KernelEmu::notify_query(port, token, B_ENTRY_CREATED,
device, directory, name, node);
}
// notify_query_entry_removed
status_t
notify_query_entry_removed(port_id port, int32 token, mount_id device,
vnode_id directory, const char *name, vnode_id node)
{
if (!name)
return B_BAD_VALUE;
return UserlandFS::KernelEmu::notify_query(port, token, B_ENTRY_REMOVED,
device, directory, name, node);
}
// #pragma mark - VNodes
// new_vnode
status_t
new_vnode(mount_id mountID, vnode_id vnodeID, fs_vnode privateNode)
{
return UserlandFS::KernelEmu::publish_vnode(mountID, vnodeID, privateNode);
}
// publish_vnode
status_t
publish_vnode(mount_id mountID, vnode_id vnodeID, fs_vnode privateNode)
{
return UserlandFS::KernelEmu::publish_vnode(mountID, vnodeID, privateNode);
}
// get_vnode
status_t
get_vnode(mount_id mountID, vnode_id vnodeID, fs_vnode *privateNode)
{
return UserlandFS::KernelEmu::get_vnode(mountID, vnodeID, privateNode);
}
// put_vnode
status_t
put_vnode(mount_id mountID, vnode_id vnodeID)
{
return UserlandFS::KernelEmu::put_vnode(mountID, vnodeID);
}
// remove_vnode
status_t
remove_vnode(mount_id mountID, vnode_id vnodeID)
{
return UserlandFS::KernelEmu::remove_vnode(mountID, vnodeID);
}
// unremove_vnode
status_t
unremove_vnode(mount_id mountID, vnode_id vnodeID)
{
return UserlandFS::KernelEmu::unremove_vnode(mountID, vnodeID);
}
// get_vnode_removed
status_t
get_vnode_removed(mount_id mountID, vnode_id vnodeID, bool* removed)
{
return UserlandFS::KernelEmu::get_vnode_removed(mountID, vnodeID, removed);
}
// #pragma mark - Misc
// kernel_debugger
void
kernel_debugger(const char *message)
{
UserlandFS::KernelEmu::kernel_debugger(message);
}
// panic
void
panic(const char *format, ...)
{
char buffer[1024];
strcpy(buffer, "PANIC: ");
int32 prefixLen = strlen(buffer);
int bufferSize = sizeof(buffer) - prefixLen;
va_list args;
va_start(args, format);
vsnprintf(buffer + prefixLen, bufferSize - 1, format, args);
va_end(args);
buffer[sizeof(buffer) - 1] = '\0';
debugger(buffer);
}
// add_debugger_command
int
add_debugger_command(char *name, debugger_command_hook hook, char *help)
{
return B_OK;
}
// remove_debugger_command
int
remove_debugger_command(char *name, debugger_command_hook hook)
{
return B_OK;
}
// kprintf
void
kprintf(const char *format, ...)
{
}
// spawn_kernel_thread
thread_id
spawn_kernel_thread(thread_func function, const char *threadName,
int32 priority, void *arg)
{
return UserlandFS::KernelEmu::spawn_kernel_thread(function, threadName,
priority, arg);
}

View File

@ -169,7 +169,7 @@ UserlandFS::KernelEmu::notify_listener(int32 operation, uint32 details,
}
// notify_select_event
void
status_t
UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
uint8 event, bool unspecifiedEvent)
{
@ -178,14 +178,14 @@ UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
FileSystem* fileSystem;
status_t error = get_port_and_fs(&port, &fileSystem);
if (error != B_OK)
return;
return error;
// prepare the request
RequestAllocator allocator(port->GetPort());
NotifySelectEventRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return;
return error;
request->sync = sync;
request->ref = ref;
@ -197,10 +197,13 @@ UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
NotifySelectEventReply* reply;
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
if (error != B_OK)
return;
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply: nothing to do
// process the reply
if (reply->error != B_OK)
return reply->error;
return error;
}
// send_notification

View File

@ -17,7 +17,7 @@ void free_path(char *p);
status_t notify_listener(int32 operation, uint32 details, mount_id device,
vnode_id oldDirectory, vnode_id directory, vnode_id node,
const char* oldName, const char* name);
void notify_select_event(selectsync *sync, uint32 ref, uint8 event,
status_t notify_select_event(selectsync *sync, uint32 ref, uint8 event,
bool unspecifiedEvent);
status_t notify_query(port_id port, int32 token, int32 operation,
mount_id device, vnode_id directory, const char* name, vnode_id node);