#pragma once #include "fs/VFS.h" #include <luna/LinkedList.h> class MountInode : public VFS::Inode, public LinkedListNode<MountInode> { public: static Result<SharedPtr<VFS::Inode>> create(SharedPtr<VFS::Inode> source, SharedPtr<VFS::FileSystem> fs); void set_fs(SharedPtr<VFS::FileSystem> fs) { m_mountee = fs; } Result<SharedPtr<VFS::Inode>> find(const char* name) const override { return m_mount_root_inode->find(name); } Option<VFS::DirectoryEntry> get(usize index) const override { return m_mount_root_inode->get(index); } Result<usize> read(u8*, usize, usize) const override { return err(EISDIR); } Result<usize> write(const u8*, usize, usize) override { return err(EISDIR); } Result<void> truncate(usize) override { return err(EISDIR); } bool will_block_if_read() const override { return false; } const VFS::InodeMetadata& metadata() const override { return m_mount_root_inode->metadata(); } Result<void> set_metadata(const VFS::InodeMetadata& metadata) override { return m_mount_root_inode->set_metadata(metadata); } VFS::FileSystem* fs() const override { return m_mountee.ptr(); } VFS::InodeType type() const override { return VFS::InodeType::Directory; } void did_link() override { m_mount_root_inode->did_link(); } void did_unlink() override { m_mount_root_inode->did_unlink(); } usize entries() const override { return m_mount_root_inode->entries(); } bool is_mountpoint() const override { return true; } SharedPtr<VFS::Inode> source() const { return m_source; } Result<void> remove_entry(const char* name) override { return m_mount_root_inode->remove_entry(name); } Result<SharedPtr<VFS::Inode>> create_file(const char* name, mode_t mode) override { return m_mount_root_inode->create_file(name, mode); } Result<SharedPtr<VFS::Inode>> create_subdirectory(const char* name, mode_t mode) override { return m_mount_root_inode->create_subdirectory(name, mode); } Result<void> add_entry(SharedPtr<VFS::Inode> inode, const char* name) override { return m_mount_root_inode->add_entry(inode, name); } Result<void> replace_entry(SharedPtr<VFS::Inode> inode, const char* name) override { return m_mount_root_inode->replace_entry(inode, name); } Result<void> set_source(SharedPtr<VFS::Inode> source) { if (m_source) m_source->remove_handle(); m_source = source; if (source) { auto parent = TRY(source->find("..")); TRY(m_mountee->set_mount_dir(parent)); source->add_handle(); } return {}; } virtual ~MountInode(); private: SharedPtr<VFS::Inode> m_source {}; SharedPtr<VFS::FileSystem> m_mountee; SharedPtr<VFS::Inode> m_mount_root_inode; MountInode() = default; }; extern LinkedList<MountInode> g_mounts;