diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelFileSystem.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelFileSystem.cpp index c1268cff69..a355a5f932 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelFileSystem.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelFileSystem.cpp @@ -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, } diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelFileSystem.h b/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelFileSystem.h index 9094c12e3e..26a8042bd5 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelFileSystem.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelFileSystem.h @@ -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; diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelFileSystem.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelFileSystem.cpp new file mode 100644 index 0000000000..8632f8d3ee --- /dev/null +++ b/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelFileSystem.cpp @@ -0,0 +1,159 @@ +// HaikuKernelFileSystem.cpp + +#include "HaikuKernelFileSystem.h" + +#include + +#include + +#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(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); +} diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelFileSystem.h b/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelFileSystem.h new file mode 100644 index 0000000000..0cdffb7429 --- /dev/null +++ b/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelFileSystem.h @@ -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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelVolume.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelVolume.cpp new file mode 100644 index 0000000000..e11e20a474 --- /dev/null +++ b/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelVolume.cpp @@ -0,0 +1,675 @@ +// HaikuKernelVolume.cpp + +#include "HaikuKernelVolume.h" + +#include + +#include +#include + +#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); +} diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelVolume.h b/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelVolume.h new file mode 100644 index 0000000000..c4f1b5009a --- /dev/null +++ b/src/add-ons/kernel/file_systems/userlandfs/server/HaikuKernelVolume.h @@ -0,0 +1,155 @@ +// HaikuKernelVolume.h + +#ifndef USERLAND_FS_BEOS_KERNEL_VOLUME_H +#define USERLAND_FS_BEOS_KERNEL_VOLUME_H + +#include + +#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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/Jamfile b/src/add-ons/kernel/file_systems/userlandfs/server/Jamfile index 1cb2354fa1..b6e426ebcd 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/Jamfile +++ b/src/add-ons/kernel/file_systems/userlandfs/server/Jamfile @@ -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 : UserlandFSServer ; + +# the library providing the Haiku kernel interface for add-ons +SharedLibrary libuserlandfs_haiku_kernel.so + : haiku_kernel_emu.cpp + : UserlandFSServer +; diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.cpp index 2ebb0bbf54..34180bc7fd 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.cpp @@ -10,10 +10,10 @@ #include #include #include -#include #include #include +#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 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//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; +} diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.h b/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.h index 456dae801d..c3e7bf02f9 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/UserlandFSServer.h @@ -4,6 +4,7 @@ #define USERLAND_FS_SERVER_H #include +#include 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; diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp index e100312402..fc965aa319 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp @@ -175,7 +175,7 @@ is_vnode_removed(nspace_id nsid, vnode_id vnid) } -// #pragma mark - Block Cache +// #pragma mark - Locking int diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/haiku_kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/haiku_kernel_emu.cpp new file mode 100644 index 0000000000..98db7f004a --- /dev/null +++ b/src/add-ons/kernel/file_systems/userlandfs/server/haiku_kernel_emu.cpp @@ -0,0 +1,213 @@ +// beos_kernel_emu.cpp + +#include +#include +#include + +#include +#include +#include + +#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); +} diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp index e88426182e..ebb631708a 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp @@ -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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h index 172ed9e2fe..3d3b7d093f 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h @@ -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);