diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-08-28 20:50:09 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-08-28 20:50:09 +0200 |
| commit | 36b9c2e5734bca7cd2cec9514a266e89b4898a06 (patch) | |
| tree | 2edb7353a9c865180844ed910cf932cf912826eb /kernel | |
| parent | 380388c8c49889338d7803e1d9776320d166874e (diff) | |
| parent | a24af4a33c403e9aafd079e0a91a6e184fc85c46 (diff) | |
| download | kernel-36b9c2e5734bca7cd2cec9514a266e89b4898a06.tar.xz kernel-36b9c2e5734bca7cd2cec9514a266e89b4898a06.zip | |
Merge branch 'fmorgner/vfs-mount-initialization' into 'develop'
kernel/vfs: rework boot initialization
See merge request teachos/kernel!57
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kernel/filesystems/ext2/filesystem.cpp | 4 | ||||
| -rw-r--r-- | kernel/kernel/filesystems/ext2/filesystem.tests.cpp | 13 | ||||
| -rw-r--r-- | kernel/kernel/filesystems/ext2/inode.tests.cpp | 5 | ||||
| -rw-r--r-- | kernel/kernel/test_support/filesystems/ext2.cpp | 1 | ||||
| -rw-r--r-- | kernel/kernel/vfs.cpp | 110 | ||||
| -rw-r--r-- | kernel/kernel/vfs.hpp | 4 | ||||
| -rw-r--r-- | kernel/kernel/vfs.tests.cpp | 26 | ||||
| -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 | 34 | ||||
| -rw-r--r-- | kernel/kernel/vfs/mount_table.hpp | 30 | ||||
| -rw-r--r-- | kernel/kernel/vfs/mount_table.tests.cpp | 21 |
14 files changed, 146 insertions, 130 deletions
diff --git a/kernel/kernel/filesystems/ext2/filesystem.cpp b/kernel/kernel/filesystems/ext2/filesystem.cpp index 384dfc77..7eaeeba2 100644 --- a/kernel/kernel/filesystems/ext2/filesystem.cpp +++ b/kernel/kernel/filesystems/ext2/filesystem.cpp @@ -568,7 +568,7 @@ namespace kernel::filesystems::ext2 //! @return The filesystem offset of the block group descriptor table. [[nodiscard]] auto block_group_descriptor_table_offset(driver_state const & state) -> kstd::bytes { - return block_size(state) == 1024_B ? 2 * block_size(state) : block_size(state); + return (state.superblock.first_data_block + 1) * block_size(state); } //! The set of "incompatible" Extended Filesystem features supported by this driver. @@ -894,7 +894,7 @@ namespace kernel::filesystems::ext2 { bitmap_set(block_bitmap, i); ++claimed; - allocated_blocks.push_back(i + group_index * superblock.blocks_per_group); + allocated_blocks.push_back(i + group_index * superblock.blocks_per_group + superblock.first_data_block); } } diff --git a/kernel/kernel/filesystems/ext2/filesystem.tests.cpp b/kernel/kernel/filesystems/ext2/filesystem.tests.cpp index c7130e99..7477a51b 100644 --- a/kernel/kernel/filesystems/ext2/filesystem.tests.cpp +++ b/kernel/kernel/filesystems/ext2/filesystem.tests.cpp @@ -273,6 +273,7 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys superblock.inodes_per_group = 32; superblock.rev_level = kernel::filesystems::ext2::constants::dynamic_revision; superblock.inode_size = 128; + superblock.first_data_block = 1; auto block_group_descriptor = kernel::filesystems::ext2::block_group_descriptor{}; block_group_descriptor.block_bitmap = 255; @@ -322,7 +323,7 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys REQUIRE(write_global_block_number_to_inode_block_index(singly_start, inode_data, singly_global_block_number, *driver_state, batch)); - REQUIRE(inode_data.block[12] == 16); + REQUIRE(inode_data.block[12] == 17); REQUIRE(read_u32(static_cast<kstd::bytes>(inode_data.block[12]) * block_size.value) == singly_global_block_number); @@ -333,18 +334,18 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys REQUIRE(write_global_block_number_to_inode_block_index(doubly_start, inode_data, doubly_global_block_number, *driver_state, batch)); - REQUIRE(inode_data.block[13] == 17); + REQUIRE(inode_data.block[13] == 18); auto const doubly_leaf_table = read_u32(static_cast<size_t>(inode_data.block[13]) * block_size); - REQUIRE(doubly_leaf_table == 18); + REQUIRE(doubly_leaf_table == 19); REQUIRE(read_u32(static_cast<size_t>(doubly_leaf_table) * block_size) == doubly_global_block_number); REQUIRE(write_global_block_number_to_inode_block_index(triply_start, inode_data, triply_global_block_number, *driver_state, batch)); - REQUIRE(inode_data.block[14] == 19); + REQUIRE(inode_data.block[14] == 20); auto const triply_middle_table = read_u32(static_cast<size_t>(inode_data.block[14]) * block_size); - REQUIRE(triply_middle_table == 20); + REQUIRE(triply_middle_table == 21); auto const triply_leaf_table = read_u32(static_cast<size_t>(triply_middle_table) * block_size); - REQUIRE(triply_leaf_table == 21); + REQUIRE(triply_leaf_table == 22); REQUIRE(read_u32(static_cast<size_t>(triply_leaf_table) * block_size) == triply_global_block_number); auto inode = kernel::filesystems::ext2::inode{42, inode_data}; diff --git a/kernel/kernel/filesystems/ext2/inode.tests.cpp b/kernel/kernel/filesystems/ext2/inode.tests.cpp index d7d27553..bdfb661d 100644 --- a/kernel/kernel/filesystems/ext2/inode.tests.cpp +++ b/kernel/kernel/filesystems/ext2/inode.tests.cpp @@ -422,6 +422,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" superblock.inode_size = 128; superblock.rev_level = 1; superblock.free_blocks_count = 64 - 15; + superblock.first_data_block = 1; auto block_group_descriptor = kernel::filesystems::ext2::block_group_descriptor{}; block_group_descriptor.inode_table = 5; @@ -544,7 +545,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" REQUIRE(inode_data.blocks + 2 == read_inode.data().blocks); auto expected_blocks = inode_data.block; - expected_blocks[2] = 16; + expected_blocks[2] = 17; auto const read_blocks = read_inode.data().block; REQUIRE(expected_blocks == read_blocks); } @@ -569,6 +570,7 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending superblock.blocks_per_group = 64; superblock.inodes_per_group = 32; superblock.inode_size = 128; + superblock.first_data_block = 1; GIVEN("an ext2 inode with good old revision and inode_data.size = 256, inode_data.dir_acl = 32") { @@ -788,6 +790,7 @@ SCENARIO("Ext2 inode read_directory skips deleted entries and paginates correctl superblock.inodes_per_group = 32; superblock.inode_size = 128; superblock.rev_level = 1; + superblock.first_data_block = 1; auto block_group_descriptor = kernel::filesystems::ext2::block_group_descriptor{}; block_group_descriptor.inode_table = 5; diff --git a/kernel/kernel/test_support/filesystems/ext2.cpp b/kernel/kernel/test_support/filesystems/ext2.cpp index d9008ade..92f56aef 100644 --- a/kernel/kernel/test_support/filesystems/ext2.cpp +++ b/kernel/kernel/test_support/filesystems/ext2.cpp @@ -47,6 +47,7 @@ namespace kernel::tests::filesystems::ext2 superblock.inodes_per_group = 32; superblock.rev_level = 1; superblock.inode_size = 128; + superblock.first_data_block = 1; setup_mock_ext2_layout(device, superblock); } diff --git a/kernel/kernel/vfs.cpp b/kernel/kernel/vfs.cpp index 1f996fb4..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; + }); - // 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) + if (!root_devfs_mount) { - 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 mount initial devfs!", root_devfs_mount.error()); + } - auto root_dentry = resolve_path("/"); - if (!root_dentry) - { - kapi::system::panic("[OS:FS] No root directory found!"); - } + auto resolved = resolve_path_internal("/dev/ram0"); + if (!resolved) + { + kapi::system::panic("[OS:FS] Failed to resolve boot disk!", resolved.error()); + } + + auto [boot_device_dentry, boot_device_mount_context] = *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; + } - auto mount = - mount::create(*root_dentry, *driver, root_mount, boot_device_mount_context, boot_device_dentry->inode()); + 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); - if (!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()); } } @@ -220,25 +240,7 @@ namespace kernel::vfs return kstd::failure(errc::invalid_path); } - auto remove_result = m_mount_table.remove_mount(path); - if (remove_result == mount_table::operation_result::removed) - { - return kstd::success(); - } - else if (remove_result == mount_table::operation_result::mount_not_found) - { - return kstd::failure(errc::mount_point_not_found); - } - else if (remove_result == mount_table::operation_result::cannot_be_unmounted) - { - return kstd::failure(errc::mount_busy); - } - else if (remove_result == mount_table::operation_result::has_child_mounts) - { - return kstd::failure(errc::has_child_mounts); - } - - return kstd::failure(errc::unmount_failed); + return m_mount_table.remove_mount(path); } auto vfs::mkdir(std::string_view path) -> kstd::result<void> @@ -321,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)) @@ -378,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() == "/") @@ -389,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 475daf2d..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); @@ -284,12 +262,12 @@ SCENARIO_METHOD(kernel::tests::vfs::storage_boot_module_vfs_fixture, "VFS with f THEN("unmount with invalid path fails") { REQUIRE(vfs.unmount("").error() == kstd::errc::invalid_argument); - REQUIRE(vfs.unmount("information").error() == kstd::errc::no_such_file_or_directory); + REQUIRE(vfs.unmount("information").error() == kstd::errc::not_connected); } THEN("unmounting non-existent mount point returns expected error code") { - REQUIRE(vfs.unmount("/information/nonexistent").error() == kstd::errc::no_such_file_or_directory); + REQUIRE(vfs.unmount("/information/nonexistent").error() == kstd::errc::not_connected); } THEN("a file can be access if . in the path") 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 2b494040..43dff516 100644 --- a/kernel/kernel/vfs/mount_table.cpp +++ b/kernel/kernel/vfs/mount_table.cpp @@ -1,9 +1,11 @@ #include <kernel/vfs/mount_table.hpp> #include <kernel/vfs/dentry.hpp> +#include <kernel/vfs/error.hpp> #include <kernel/vfs/mount.hpp> #include <kstd/memory.hpp> +#include <kstd/result.hpp> #include <kstd/vector.hpp> #include <algorithm> @@ -33,22 +35,32 @@ namespace kernel::vfs } } - auto mount_table::remove_mount(std::string_view path) -> operation_result + auto mount_table::remove_mount(std::string_view path) -> kstd::result<void> { auto mount_it = find_mount_iterator(path); if (mount_it == m_mounts.end()) { - return operation_result::mount_not_found; + return kstd::failure(errc::not_mounted); } auto const & mount = *mount_it; + return remove_mount(mount); + } + + auto mount_table::remove_mount(kstd::shared_ptr<mount> const & mount) -> kstd::result<void> + { + if (!mount) + { + return kstd::failure(errc::invalid_argument); + } + if (!mount->is_ready_to_unmount()) { - return operation_result::cannot_be_unmounted; + return kstd::failure(errc::mount_busy); } if (has_child_mounts(mount)) { - return operation_result::has_child_mounts; + return kstd::failure(errc::has_child_mounts); } if (auto source_mount = mount->source_mount()) @@ -61,8 +73,8 @@ namespace kernel::vfs mount_dentry->unset_flag(dentry::dentry_flags::is_mount_point); } - m_mounts.erase(mount_it); - return operation_result::removed; + kstd::erase(m_mounts, mount); + return kstd::success(); } auto mount_table::find_mount(std::string_view path) const -> kstd::shared_ptr<mount> @@ -71,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 86810a16..d2bb2f94 100644 --- a/kernel/kernel/vfs/mount_table.hpp +++ b/kernel/kernel/vfs/mount_table.hpp @@ -1,9 +1,11 @@ #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> +#include <kstd/result.hpp> #include <kstd/vector.hpp> #include <string_view> @@ -13,15 +15,6 @@ namespace kernel::vfs //! A table managing all mounted filesystems. struct mount_table { - //! Results for mount table operations. - enum class operation_result : int - { - removed = 0, - has_child_mounts = -1, - mount_not_found = -2, - cannot_be_unmounted = -3 - }; - //! Add a mount to the table. //! //! @param mount The mount to add. @@ -30,9 +23,14 @@ namespace kernel::vfs //! Remove the topmost mount at the given @p path. //! //! @param path The mount path to remove. - //! @return The result of the removal operation. - [[nodiscard]] auto remove_mount(std::string_view path) - -> operation_result; // TODO: replace return type with kstd::result + //! @return Nothing on success, an error otherwise. + [[nodiscard]] auto remove_mount(std::string_view path) -> kstd::result<void>; + + //! Remove the given mount. + //! + //! @param mount The mount to remove. + //! @return Nothing on success, an error otherwise. + [[nodiscard]] auto remove_mount(kstd::shared_ptr<mount> const & mount) -> kstd::result<void>; //! Find the mount with the exact mount path matching the given path. //! @@ -40,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 diff --git a/kernel/kernel/vfs/mount_table.tests.cpp b/kernel/kernel/vfs/mount_table.tests.cpp index e8f3ec4a..52ca9313 100644 --- a/kernel/kernel/vfs/mount_table.tests.cpp +++ b/kernel/kernel/vfs/mount_table.tests.cpp @@ -2,8 +2,7 @@ #include <kernel/test_support/filesystems/filesystem.hpp> #include <kernel/test_support/filesystems/inode.hpp> -#include <kernel/vfs/dentry.hpp> -#include <kernel/vfs/mount.hpp> +#include <kernel/vfs.hpp> #include <kstd/memory.hpp> #include <kstd/print.hpp> @@ -21,8 +20,8 @@ SCENARIO("Mount table construction", "[filesystem][mount_table]") THEN("removing any mount returns mount_not_found") { - REQUIRE(table.remove_mount("/") == kernel::vfs::mount_table::operation_result::mount_not_found); - REQUIRE(table.remove_mount("/any/path") == kernel::vfs::mount_table::operation_result::mount_not_found); + REQUIRE(table.remove_mount("/").error() == kernel::vfs::errc::not_mounted); + REQUIRE(table.remove_mount("/any/path").error() == kernel::vfs::errc::not_mounted); } } } @@ -70,13 +69,13 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing a mount that has no child mounts succeeds") { - REQUIRE(table.remove_mount("/mnt") == kernel::vfs::mount_table::operation_result::removed); + REQUIRE(table.remove_mount("/mnt")); REQUIRE_FALSE(root_dentry2->has_flag(kernel::vfs::dentry::dentry_flags::is_mount_point)); } THEN("removing a mount that does not exist returns mount_not_found") { - REQUIRE(table.remove_mount("/nonexistent") == kernel::vfs::mount_table::operation_result::mount_not_found); + REQUIRE(table.remove_mount("/nonexistent").error() == kernel::vfs::errc::not_mounted); } } @@ -108,7 +107,7 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing the topmost mount with the same path succeeds") { - REQUIRE(table.remove_mount("/") == kernel::vfs::mount_table::operation_result::removed); + REQUIRE(table.remove_mount("/")); REQUIRE_FALSE(root_dentry2->has_flag(kernel::vfs::dentry::dentry_flags::is_mount_point)); } } @@ -144,13 +143,13 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem] THEN("removing a mount with child mounts returns has_child_mounts") { - REQUIRE(table.remove_mount("/") == kernel::vfs::mount_table::operation_result::has_child_mounts); - REQUIRE(table.remove_mount("/mnt") == kernel::vfs::mount_table::operation_result::has_child_mounts); + REQUIRE(table.remove_mount("/").error() == kernel::vfs::errc::has_child_mounts); + REQUIRE(table.remove_mount("/mnt").error() == kernel::vfs::errc::has_child_mounts); } THEN("removing a leaf mount succeeds") { - REQUIRE(table.remove_mount("/mnt/submnt") == kernel::vfs::mount_table::operation_result::removed); + REQUIRE(table.remove_mount("/mnt/submnt")); REQUIRE_FALSE(root_dentry3->has_flag(kernel::vfs::dentry::dentry_flags::is_mount_point)); } } @@ -177,7 +176,7 @@ SCENARIO("Mount reference counting", "[filesystem][mount_table]") table.add_mount(*mount); REQUIRE((*source_mount)->ref_count() == 1); - REQUIRE(table.remove_mount("/") == kernel::vfs::mount_table::operation_result::removed); + REQUIRE(table.remove_mount("/")); REQUIRE((*source_mount)->ref_count() == 0); } } |
