aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/kernel/filesystems/ext2/filesystem.cpp4
-rw-r--r--kernel/kernel/filesystems/ext2/filesystem.tests.cpp13
-rw-r--r--kernel/kernel/filesystems/ext2/inode.tests.cpp5
-rw-r--r--kernel/kernel/test_support/filesystems/ext2.cpp1
-rw-r--r--kernel/kernel/vfs.cpp110
-rw-r--r--kernel/kernel/vfs.hpp4
-rw-r--r--kernel/kernel/vfs.tests.cpp26
-rw-r--r--kernel/kernel/vfs/dentry.cpp5
-rw-r--r--kernel/kernel/vfs/dentry.hpp4
-rw-r--r--kernel/kernel/vfs/mount.cpp11
-rw-r--r--kernel/kernel/vfs/mount.hpp8
-rw-r--r--kernel/kernel/vfs/mount_table.cpp34
-rw-r--r--kernel/kernel/vfs/mount_table.hpp30
-rw-r--r--kernel/kernel/vfs/mount_table.tests.cpp21
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);
}
}