diff --git a/kernel/include/kernel/FS/VirtualFileSystem.h b/kernel/include/kernel/FS/VirtualFileSystem.h index 7ce1c7a2..7197feec 100644 --- a/kernel/include/kernel/FS/VirtualFileSystem.h +++ b/kernel/include/kernel/FS/VirtualFileSystem.h @@ -1,5 +1,7 @@ #pragma once +#include +#include #include #include @@ -13,7 +15,9 @@ namespace Kernel static VirtualFileSystem& get(); virtual ~VirtualFileSystem() {}; - virtual const BAN::RefPtr root_inode() const override { return m_root_inode; } + virtual const BAN::RefPtr root_inode() const override; + + void close_inode(BAN::StringView); BAN::ErrorOr> from_absolute_path(BAN::StringView); @@ -22,9 +26,8 @@ namespace Kernel BAN::ErrorOr initialize_impl(); private: - BAN::RefPtr m_root_inode; - - BAN::Vector m_storage_controllers; + BAN::HashMap> m_open_inodes; + BAN::Vector m_storage_controllers; }; } \ No newline at end of file diff --git a/kernel/kernel/FS/VirtualFileSystem.cpp b/kernel/kernel/FS/VirtualFileSystem.cpp index a3cb2d71..3601d331 100644 --- a/kernel/kernel/FS/VirtualFileSystem.cpp +++ b/kernel/kernel/FS/VirtualFileSystem.cpp @@ -93,7 +93,7 @@ namespace Kernel { if (partition.name() == "banan-root"sv) { - if (m_root_inode) + if (root_inode()) dwarnln("multiple root partitions found"); else { @@ -103,32 +103,51 @@ namespace Kernel else // FIXME: We leave a dangling pointer to ext2fs. This might be okay since // root fs sould probably be always mounted - m_root_inode = ext2fs_or_error.release_value()->root_inode(); + TRY(m_open_inodes.insert("/"sv, ext2fs_or_error.release_value()->root_inode())); } } } } } - if (m_root_inode.empty()) + if (!root_inode()) derrorln("Could not locate root partition"); return {}; } + const BAN::RefPtr VirtualFileSystem::root_inode() const + { + if (!m_open_inodes.contains("/"sv)) + return nullptr; + return m_open_inodes["/"sv]; + } + + void VirtualFileSystem::close_inode(BAN::StringView path) + { + ASSERT(m_open_inodes.contains(path)); + + // Delete the cached inode, if we are the only one holding a reference to it + if (m_open_inodes[path]->ref_count() == 1) + m_open_inodes.remove(path); + } + BAN::ErrorOr> VirtualFileSystem::from_absolute_path(BAN::StringView path) { - if (path.front() != '/') - return BAN::Error::from_c_string("Path must be an absolute path"); + ASSERT(path.front() == '/'); + + if (m_open_inodes.contains(path)) + return m_open_inodes[path]; auto inode = root_inode(); if (!inode) return BAN::Error::from_c_string("No root inode available"); auto path_parts = TRY(path.split('/')); - for (BAN::StringView part : path_parts) inode = TRY(inode->directory_find(part)); + TRY(m_open_inodes.insert(path, inode)); + return inode; }