From 72de2c45863670db6c10dcd82e8bde242e5994f9 Mon Sep 17 00:00:00 2001 From: Stepan Usatiuk Date: Sat, 4 May 2024 20:03:34 +0200 Subject: [PATCH] VFS: vnode cache --- src/arch/x86/kmain.cpp | 4 +++- src/kernel/vfs/FDT.cpp | 2 +- src/kernel/vfs/Filesystem.cpp | 29 +++++++++++++++++++++++++++-- src/kernel/vfs/Filesystem.hpp | 21 +++++++++++++++++---- src/kernel/vfs/MemFs.cpp | 4 ++-- src/kernel/vfs/MemFs.hpp | 4 ++-- src/kernel/vfs/MountTable.cpp | 3 ++- src/kernel/vfs/MountTable.hpp | 2 +- src/kernel/vfs/TarFs.cpp | 4 ++-- src/kernel/vfs/TarFs.hpp | 4 ++-- src/kernel/vfs/VFSGlobals.cpp | 4 ++-- src/kernel/vfs/VFSGlobals.hpp | 4 ++-- 12 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/arch/x86/kmain.cpp b/src/arch/x86/kmain.cpp index 3c4af67f4..d850687a7 100644 --- a/src/arch/x86/kmain.cpp +++ b/src/arch/x86/kmain.cpp @@ -56,11 +56,13 @@ void ktask_main() { (new Task(Task::TaskMode::TASKMODE_KERN, templates_tester, "templates_tester2"))->start(); // (new Task(Task::TaskMode::TASKMODE_KERN, vfs_tester, "vfs_tester"))->start(); + VFSGlobals::root = SharedPtr(new RootNode()); + for (int i = 0; i < saved_modules_size; i++) { auto &mod = saved_modules[i]; if (strcmp(saved_modules_names[i], "/sysroot.tar") == 0) { - VFSGlobals::mounts.add_mount(new TarFs((char *) mod.address, mod.size, &VFSGlobals::root)); + VFSGlobals::mounts.add_mount(new TarFs((char *) mod.address, mod.size))->set_root(static_ptr_cast(VFSGlobals::root)); } } GlobalTtyManager.all_tty_putstr("Setup finished \n"); diff --git a/src/kernel/vfs/FDT.cpp b/src/kernel/vfs/FDT.cpp index 5f1176e76..de74c7c90 100644 --- a/src/kernel/vfs/FDT.cpp +++ b/src/kernel/vfs/FDT.cpp @@ -14,7 +14,7 @@ #include FDT::FD FDT::open(const Path &p, int opts) { - if (auto n = VFSGlobals::root.traverse(p); n.get() != nullptr) { + if (auto n = VFSGlobals::root->traverse(p); n.get() != nullptr) { LockGuard l(_mtx); _files.emplace(_cur_fd++, UniquePtr(new File(n, opts))); return _cur_fd - 1; diff --git a/src/kernel/vfs/Filesystem.cpp b/src/kernel/vfs/Filesystem.cpp index e78c368ce..3bb3b9d58 100644 --- a/src/kernel/vfs/Filesystem.cpp +++ b/src/kernel/vfs/Filesystem.cpp @@ -4,8 +4,33 @@ #include "Filesystem.hpp" -Filesystem::~Filesystem() = default; -Filesystem::Filesystem(NodeDir *mounted_on) : _mounted_on(mounted_on) { +Filesystem::~Filesystem() { + if (_mounted_on.get()) { + _mounted_on->set_mounted(nullptr); + } +} + +void Filesystem::set_root(SharedPtr node) { + _mounted_on = std::move(node); assert(_mounted_on->type() == Node::DIR); _mounted_on->set_mounted(this); } + +SharedPtr Filesystem::get_node(ino_t inode) { + { + LockGuard l(_vnode_cache_lock); + if (auto p = _vnode_cache.find(inode); p != _vnode_cache.end()) + if (auto l = p->second.lock()) return *l; + } + + auto found = get_node_impl(inode); + + { + LockGuard l(_vnode_cache_lock); + if (auto p = _vnode_cache.find(inode); p != _vnode_cache.end()) + if (auto l = p->second.lock()) return *l; + + _vnode_cache.emplace(inode, found); + return found; + } +} diff --git a/src/kernel/vfs/Filesystem.hpp b/src/kernel/vfs/Filesystem.hpp index f2e390bbc..496673eb5 100644 --- a/src/kernel/vfs/Filesystem.hpp +++ b/src/kernel/vfs/Filesystem.hpp @@ -8,16 +8,29 @@ #include "Node.hpp" #include "PointersCollection.hpp" +#include "SkipList.hpp" class Filesystem { public: - Filesystem(NodeDir *mounted_on); + Filesystem() = default; virtual ~Filesystem() = 0; - virtual SharedPtr root() = 0; - virtual SharedPtr get_node(ino_t inode) = 0; + Filesystem(Filesystem const &other) = delete; + Filesystem &operator=(Filesystem const &other) = delete; - NodeDir *_mounted_on; + virtual SharedPtr root() = 0; + virtual SharedPtr get_node(ino_t inode); + + void set_root(SharedPtr node_dir); + +protected: + virtual SharedPtr get_node_impl(ino_t inode) = 0; + + SharedPtr _mounted_on; + +private: + SkipListMap> _vnode_cache; + Mutex _vnode_cache_lock; }; diff --git a/src/kernel/vfs/MemFs.cpp b/src/kernel/vfs/MemFs.cpp index 883c50c75..c622c250c 100644 --- a/src/kernel/vfs/MemFs.cpp +++ b/src/kernel/vfs/MemFs.cpp @@ -84,7 +84,7 @@ size_t MemFs::MemFsNodeFile::size() { LockGuard l2(_fs_node->lock); return _fs_node->data.size(); } -MemFs::MemFs(NodeDir *mounted_on) : Filesystem(mounted_on) { +MemFs::MemFs() { _files.emplace(1, new DirInode{1}); _top_inode = 2; } @@ -100,7 +100,7 @@ SharedPtr MemFs::root() { return static_ptr_cast(MemFsNodeDir::create(this, static_ptr_cast(root))); } } -SharedPtr MemFs::get_node(ino_t inode) { +SharedPtr MemFs::get_node_impl(ino_t inode) { LockGuard l(_files_lock); auto found = _files.find(inode); if (found == _files.end()) return nullptr; diff --git a/src/kernel/vfs/MemFs.hpp b/src/kernel/vfs/MemFs.hpp index f4f4f20ab..b3eac306d 100644 --- a/src/kernel/vfs/MemFs.hpp +++ b/src/kernel/vfs/MemFs.hpp @@ -91,10 +91,10 @@ private: }; public: - MemFs(NodeDir *mounted_on); + MemFs(); SharedPtr root() override; - SharedPtr get_node(ino_t inode) override; + SharedPtr get_node_impl(ino_t inode) override; private: ino_t _top_inode; diff --git a/src/kernel/vfs/MountTable.cpp b/src/kernel/vfs/MountTable.cpp index 44b9b9b5d..d499c28e9 100644 --- a/src/kernel/vfs/MountTable.cpp +++ b/src/kernel/vfs/MountTable.cpp @@ -3,6 +3,7 @@ // #include "MountTable.hpp" -void MountTable::add_mount(Filesystem *fs) { +Filesystem *MountTable::add_mount(Filesystem *fs) { _mounts.emplace_front(fs); + return fs; } diff --git a/src/kernel/vfs/MountTable.hpp b/src/kernel/vfs/MountTable.hpp index dd6b711d5..f23cdeed5 100644 --- a/src/kernel/vfs/MountTable.hpp +++ b/src/kernel/vfs/MountTable.hpp @@ -13,7 +13,7 @@ class MountTable { public: - void add_mount(Filesystem *fs); + Filesystem *add_mount(Filesystem *fs); private: List _mounts; diff --git a/src/kernel/vfs/TarFs.cpp b/src/kernel/vfs/TarFs.cpp index f3fea96c8..6642bdc79 100644 --- a/src/kernel/vfs/TarFs.cpp +++ b/src/kernel/vfs/TarFs.cpp @@ -7,7 +7,7 @@ #include -TarFs::TarFs(char *backing, size_t backing_size, NodeDir *mounted_on) : Filesystem(mounted_on), _backing((tar_header *) backing), _backing_size(backing_size) { +TarFs::TarFs(char *backing, size_t backing_size) : _backing((tar_header *) backing), _backing_size(backing_size) { int i = 2; const tar_header *header = _backing; @@ -89,7 +89,7 @@ SharedPtr TarFs::root() { return static_ptr_cast(get_node(1)); } -SharedPtr TarFs::get_node(ino_t inode) { +SharedPtr TarFs::get_node_impl(ino_t inode) { if (_dir_map.find(inode) != _dir_map.end()) { return static_ptr_cast(TarFsNodeDir::create(this, inode)); } else { diff --git a/src/kernel/vfs/TarFs.hpp b/src/kernel/vfs/TarFs.hpp index 7ba42319d..fda8170ee 100644 --- a/src/kernel/vfs/TarFs.hpp +++ b/src/kernel/vfs/TarFs.hpp @@ -9,11 +9,11 @@ class TarFs : public Filesystem { public: - TarFs(char *backing, size_t backing_size, NodeDir *mounted_on); + TarFs(char *backing, size_t backing_size); ~TarFs() override = default; SharedPtr root() override; - SharedPtr get_node(ino_t inode) override; + SharedPtr get_node_impl(ino_t inode) override; struct TarFsNodeDir : public ::NodeDir { diff --git a/src/kernel/vfs/VFSGlobals.cpp b/src/kernel/vfs/VFSGlobals.cpp index b894b47df..3fcee071a 100644 --- a/src/kernel/vfs/VFSGlobals.cpp +++ b/src/kernel/vfs/VFSGlobals.cpp @@ -17,5 +17,5 @@ ino_t RootNode::mkfile(const String &name) { } -RootNode VFSGlobals::root; -MountTable VFSGlobals::mounts; +SharedPtr VFSGlobals::root; +MountTable VFSGlobals::mounts; diff --git a/src/kernel/vfs/VFSGlobals.hpp b/src/kernel/vfs/VFSGlobals.hpp index 456e8f78f..13a1169be 100644 --- a/src/kernel/vfs/VFSGlobals.hpp +++ b/src/kernel/vfs/VFSGlobals.hpp @@ -19,8 +19,8 @@ public: }; namespace VFSGlobals { - extern RootNode root; - extern MountTable mounts; + extern SharedPtr root; + extern MountTable mounts; } // namespace VFSGlobals