diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kernel/vfs.cpp | 90 | ||||
| -rw-r--r-- | kernel/kernel/vfs.hpp | 4 | ||||
| -rw-r--r-- | kernel/kernel/vfs.tests.cpp | 22 | ||||
| -rw-r--r-- | kernel/kernel/vfs/dentry.cpp | 5 | ||||
| -rw-r--r-- | kernel/kernel/vfs/dentry.hpp | 4 | ||||
| -rw-r--r-- | kernel/kernel/vfs/mount.cpp | 11 | ||||
| -rw-r--r-- | kernel/kernel/vfs/mount.hpp | 8 | ||||
| -rw-r--r-- | kernel/kernel/vfs/mount_table.cpp | 10 | ||||
| -rw-r--r-- | kernel/kernel/vfs/mount_table.hpp | 9 |
9 files changed, 92 insertions, 71 deletions
diff --git a/kernel/kernel/vfs.cpp b/kernel/kernel/vfs.cpp index 5f729406..742af328 100644 --- a/kernel/kernel/vfs.cpp +++ b/kernel/kernel/vfs.cpp @@ -84,36 +84,56 @@ namespace kernel::vfs } auto [device_fs_root, device_fs_data] = *device_fs_mount_result; - graft_persistent_device_fs(*devfs, device_fs_root, device_fs_data); + auto root_devfs_mount = resolve_path_internal("/").transform([&](auto res) { + auto [root_dentry, root_mount] = res; + auto dev_dentry = kstd::make_shared<dentry>(root_dentry, device_fs_root, "dev"); + root_dentry->add_child(dev_dentry); + auto mount = mount::attach(dev_dentry, *devfs, device_fs_root, device_fs_data, root_mount, nullptr); + m_mount_table.add_mount(mount); + return mount; + }); + + if (!root_devfs_mount) + { + kapi::system::panic("[OS:FS] failed to mount initial devfs!", root_devfs_mount.error()); + } - // mount boot fs at / (shadows rootfs), re-graft devfs - auto [boot_device_dentry, boot_device_mount_context] = - resolve_path_internal("/dev/ram0").value_or(std::pair{nullptr, nullptr}); - if (boot_device_dentry && boot_device_mount_context) + auto resolved = resolve_path_internal("/dev/ram0"); + if (!resolved) { - auto driver = driver_registry::get().match(boot_device_dentry->inode()); - if (!driver) - { - kstd::println(kstd::print_sink::stderr, "[OS:FS] Missing driver for root disk!"); - return; - } + kapi::system::panic("[OS:FS] Failed to resolve boot disk!", resolved.error()); + } - auto root_dentry = resolve_path("/"); - if (!root_dentry) - { - kapi::system::panic("[OS:FS] No root directory found!"); - } + auto [boot_device_dentry, boot_device_mount_context] = *resolved; - auto mount = - mount::create(*root_dentry, *driver, root_mount, boot_device_mount_context, boot_device_dentry->inode()); + auto driver = driver_registry::get().match(boot_device_dentry->inode()); + if (!driver) + { + kstd::println(kstd::print_sink::stderr, "[OS:FS] Missing driver for root disk!"); + return; + } - if (!mount) + auto mount = mount::create(nullptr, *driver, nullptr, boot_device_mount_context, boot_device_dentry->inode()); + if (!mount) + { + kapi::system::panic("[OS:FS] failed to mount boot FS", mount.error()); + } + m_mount_table.add_mount(*mount); + + auto real_dev_dentry = resolve_path("/dev"); + if (!real_dev_dentry) + { + if (auto result = mkdir("/dev"); !result) { - kapi::system::panic("[OS:FS] failed to mount boot FS", mount.error()); + kapi::system::panic("[OS:FS] Failed to create devfs mount point!", result.error()); } - m_mount_table.add_mount(*mount); + real_dev_dentry = resolve_path("/dev"); + } - graft_persistent_device_fs(*devfs, device_fs_root, device_fs_data); + m_mount_table.move_mount(*root_devfs_mount, *real_dev_dentry, *mount); + if (auto result = m_mount_table.remove_mount(root_mount); !result) + { + kapi::system::panic("[OS:FS] Failed to unmount early rootfs!", result.error()); } } @@ -303,25 +323,6 @@ namespace kernel::vfs return kstd::failure(errc::no_such_file_or_directory); } - auto vfs::graft_persistent_device_fs(kstd::shared_ptr<filesystem> const & device_fs, - kstd::shared_ptr<inode> const & root_inode, - kstd::shared_ptr<driver_state> driver_data) -> void - { - auto [root_mount_point_dentry, root_mount] = resolve_path_internal("/").value_or(std::pair{nullptr, nullptr}); - if (root_mount_point_dentry && root_mount) - { - auto dev_dentry = root_mount_point_dentry->find_child("dev"); - if (!dev_dentry) - { - dev_dentry = kstd::make_shared<dentry>(root_mount_point_dentry, root_inode, "dev"); - root_mount_point_dentry->add_child(dev_dentry); - } - - auto new_mount = mount::attach(dev_dentry, device_fs, root_inode, driver_data, root_mount, nullptr); - m_mount_table.add_mount(new_mount); - } - } - auto vfs::resolve_path_internal(std::string_view path) const -> kstd::result<std::pair<dentry_ptr, mount_ptr>> { if (!path::is_valid_absolute_path(path)) @@ -360,8 +361,6 @@ namespace kernel::vfs if (part == "..") { - auto parent_dentry = current_dentry->parent(); - if (current_dentry == current_mount->root_dentry()) { if (current_mount->mount_path() == "/") @@ -371,12 +370,13 @@ namespace kernel::vfs if (auto parent_mount = current_mount->parent_mount()) { + current_dentry = current_mount->mount_dentry()->parent(); current_mount = parent_mount; - current_dentry = parent_dentry; + continue; } } - current_dentry = parent_dentry; + current_dentry = current_dentry->parent(); continue; } diff --git a/kernel/kernel/vfs.hpp b/kernel/kernel/vfs.hpp index 8688536a..4528ab2e 100644 --- a/kernel/kernel/vfs.hpp +++ b/kernel/kernel/vfs.hpp @@ -124,10 +124,6 @@ namespace kernel::vfs [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::result<mount_ptr>; - auto graft_persistent_device_fs(kstd::shared_ptr<filesystem> const & device_fs, - kstd::shared_ptr<inode> const & root_inode, - kstd::shared_ptr<driver_state> driver_data) -> void; - auto create_inode(std::string_view path, kapi::filesystem::file_type type, std::optional<kapi::filesystem::device_number> raw_device = std::nullopt) -> kstd::result<void>; diff --git a/kernel/kernel/vfs.tests.cpp b/kernel/kernel/vfs.tests.cpp index 0c807082..f766a992 100644 --- a/kernel/kernel/vfs.tests.cpp +++ b/kernel/kernel/vfs.tests.cpp @@ -238,28 +238,6 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_vfs_fixture, "VFS with f REQUIRE(dev_ram_32 != nullptr); } - THEN("boot root can be unmounted and remounted again but /dev is not re-grafted") - { - auto info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 != nullptr); - - REQUIRE(vfs.close(info_1.value()->absolute_path())); - - REQUIRE(vfs.unmount("/dev")); - REQUIRE(vfs.unmount("/")); - - info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); - - REQUIRE(vfs.mount("/dev/ram0", "/")); - - info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 != nullptr); - - auto dev_ram_0 = vfs.open("/dev/ram0"); - REQUIRE(dev_ram_0.error() == kstd::errc::no_such_file_or_directory); - } - THEN("mount with null file system fails") { REQUIRE(vfs.mount("/closed.txt", "/information").error() == kstd::errc::not_supported); diff --git a/kernel/kernel/vfs/dentry.cpp b/kernel/kernel/vfs/dentry.cpp index a7bfc3cb..c22dc0e2 100644 --- a/kernel/kernel/vfs/dentry.cpp +++ b/kernel/kernel/vfs/dentry.cpp @@ -93,4 +93,9 @@ namespace kernel::vfs { return (m_flags & static_cast<uint32_t>(flag)) != 0; } + + auto dentry::set_parent(dentry_ptr const & parent) -> void + { + m_parent = parent; + } } // namespace kernel::vfs
\ No newline at end of file diff --git a/kernel/kernel/vfs/dentry.hpp b/kernel/kernel/vfs/dentry.hpp index b15a6f6c..13dea2a3 100644 --- a/kernel/kernel/vfs/dentry.hpp +++ b/kernel/kernel/vfs/dentry.hpp @@ -87,6 +87,10 @@ namespace kernel::vfs [[nodiscard]] auto has_flag(dentry_flags flag) const -> bool; private: + friend struct mount_table; + + auto set_parent(dentry_ptr const & parent) -> void; + kstd::string m_name; kstd::weak_ptr<dentry> m_parent; kstd::vector<dentry_ptr> m_children; diff --git a/kernel/kernel/vfs/mount.cpp b/kernel/kernel/vfs/mount.cpp index b5fdfa39..76f72e22 100644 --- a/kernel/kernel/vfs/mount.cpp +++ b/kernel/kernel/vfs/mount.cpp @@ -138,4 +138,15 @@ namespace kernel::vfs { return m_ref_count; } + + auto mount::set_mount_dentry(dentry_ptr const & mount_dentry) -> void + { + m_mount_dentry = mount_dentry; + } + + auto mount::set_parent_mount(mount_ptr const & parent_mount) -> void + { + m_parent_mount = parent_mount; + } + } // namespace kernel::vfs
\ No newline at end of file diff --git a/kernel/kernel/vfs/mount.hpp b/kernel/kernel/vfs/mount.hpp index beecb759..b0993dd3 100644 --- a/kernel/kernel/vfs/mount.hpp +++ b/kernel/kernel/vfs/mount.hpp @@ -86,6 +86,8 @@ namespace kernel::vfs [[nodiscard]] auto ref_count() const -> size_t; private: + friend struct mount_table; + //! Create a new mount with the given parameters. //! //! @param mount_dentry The directory entry where the filesystem is mounted. @@ -98,6 +100,12 @@ namespace kernel::vfs mount_ptr const & parent_mount, mount_ptr const & source_mount, kstd::shared_ptr<vfs::driver_state> driver_state); + //! Set the directory entry where the filesystem is mounted. + auto set_mount_dentry(dentry_ptr const & mount_dentry) -> void; + + //! Set the parent mount this this mount was attached beneath. + auto set_parent_mount(mount_ptr const & parent_mount) -> void; + dentry_ptr m_mount_dentry{}; dentry_ptr m_root_dentry{}; filesystem_ptr m_filesystem{}; diff --git a/kernel/kernel/vfs/mount_table.cpp b/kernel/kernel/vfs/mount_table.cpp index 01127697..43dff516 100644 --- a/kernel/kernel/vfs/mount_table.cpp +++ b/kernel/kernel/vfs/mount_table.cpp @@ -83,6 +83,16 @@ namespace kernel::vfs return (mount_it != m_mounts.end()) ? *mount_it : nullptr; } + auto mount_table::move_mount(kstd::shared_ptr<mount> const & mount, kstd::shared_ptr<dentry> const & mount_point, + kstd::shared_ptr<struct mount> const & parent) -> void + { + mount->mount_dentry()->unset_flag(dentry::dentry_flags::is_mount_point); + mount->root_dentry()->set_parent(mount_point->parent()); + mount->set_mount_dentry(mount_point); + mount->set_parent_mount(parent); + mount_point->set_flag(dentry::dentry_flags::is_mount_point); + } + auto mount_table::find_mount_iterator(std::string_view path) const -> kstd::vector<kstd::shared_ptr<mount>>::const_iterator { diff --git a/kernel/kernel/vfs/mount_table.hpp b/kernel/kernel/vfs/mount_table.hpp index 140aebac..731b0ad8 100644 --- a/kernel/kernel/vfs/mount_table.hpp +++ b/kernel/kernel/vfs/mount_table.hpp @@ -1,6 +1,7 @@ #ifndef TEACHOS_KERNEL_VFS_MOUNT_TABLE_HPP #define TEACHOS_KERNEL_VFS_MOUNT_TABLE_HPP +#include <kernel/vfs/dentry.hpp> #include <kernel/vfs/mount.hpp> #include <kstd/memory.hpp> @@ -37,6 +38,14 @@ namespace kernel::vfs //! @return A pointer to the mount with the exact matching path on success, nullpointer otherwise. [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr<mount>; + //! Move the mount attachment of an existing mount + //! + //! @param mount The mount to modify. + //! @param mount_point The new location the mount is mounted on. + //! @param parent The new parent mount of the mount. + auto move_mount(kstd::shared_ptr<mount> const & mount, kstd::shared_ptr<dentry> const & mount_point, + kstd::shared_ptr<struct mount> const & parent) -> void; + private: [[nodiscard]] auto has_child_mounts(kstd::shared_ptr<mount> const & parent_mount) const -> bool; [[nodiscard]] auto find_mount_iterator(std::string_view path) const |
