aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Braun <marcel.braun@ost.ch>2026-05-25 14:13:11 +0200
committerMarcel Braun <marcel.braun@ost.ch>2026-05-25 14:13:11 +0200
commit0ab7525951b0116241f393090987bedc07a18c33 (patch)
treefdd1d16c7de4f35dfc6d527cb9caa554e0db2c0c
parent093074d5209f2d0062be79059f5881ee051c07d0 (diff)
parentadb1b5f2d6858097227fa610e86d1152b79d0bfa (diff)
downloadkernel-0ab7525951b0116241f393090987bedc07a18c33.tar.xz
kernel-0ab7525951b0116241f393090987bedc07a18c33.zip
Merge branch 'improve-mount-reference-count' into 'develop-BA-FS26'
Increase reference count of source_mount when one of its files is mounted somewhere See merge request teachos/kernel!42
-rw-r--r--kernel/include/kernel/filesystem/mount.hpp17
-rw-r--r--kernel/include/kernel/filesystem/vfs.hpp7
-rw-r--r--kernel/src/filesystem/mount.cpp14
-rw-r--r--kernel/src/filesystem/mount.tests.cpp19
-rw-r--r--kernel/src/filesystem/mount_table.cpp16
-rw-r--r--kernel/src/filesystem/mount_table.tests.cpp41
-rw-r--r--kernel/src/filesystem/vfs.cpp26
-rw-r--r--kernel/src/filesystem/vfs.tests.cpp36
-rw-r--r--kernel/src/main.cpp54
9 files changed, 171 insertions, 59 deletions
diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp
index 4ce374f..53d7f6d 100644
--- a/kernel/include/kernel/filesystem/mount.hpp
+++ b/kernel/include/kernel/filesystem/mount.hpp
@@ -24,11 +24,12 @@ namespace kernel::filesystem
@param mount_dentry The dentry where the filesystem is mounted.
@param root_dentry The root dentry of the mounted filesystem.
@param fs The filesystem instance being mounted.
- @param mount_path The path at which the filesystem is mounted.
- @param parent_mount The parent mount that this mount is attached beneath.
+ @param parent_mount The mount that contains the mount_dentry.
+ @param source_mount The mount that the filesystem originates from.
*/
mount(kstd::shared_ptr<dentry> const & mount_dentry, kstd::shared_ptr<dentry> const & root_dentry,
- kstd::shared_ptr<filesystem> const & fs, kstd::shared_ptr<mount> const & parent_mount);
+ kstd::shared_ptr<filesystem> const & fs, kstd::shared_ptr<mount> const & parent_mount,
+ kstd::shared_ptr<mount> const & source_mount);
/**
@brief Get the dentry where the filesystem is mounted.
@@ -56,15 +57,20 @@ namespace kernel::filesystem
[[nodiscard]] auto parent_mount() const -> kstd::shared_ptr<mount> const &;
/**
+ @brief Get the source mount where this mount originates from.
+ */
+ [[nodiscard]] auto source_mount() const -> kstd::shared_ptr<mount>;
+
+ /**
@brief Increment the reference count for this mount.
*/
auto increment_ref_count() -> void;
/**
@brief Decrement the reference count for this mount.
- @return True if the reference count reached zero, false otherwise.
+ @warning Throws if ref_count is zero.
*/
- [[nodiscard]] auto decrement_ref_count() -> bool;
+ auto decrement_ref_count() -> void;
/**
@brief Check if the mount is ready to be unmounted.
@@ -83,6 +89,7 @@ namespace kernel::filesystem
kstd::shared_ptr<dentry> m_root_dentry;
kstd::shared_ptr<filesystem> m_filesystem{};
kstd::shared_ptr<mount> m_parent_mount{};
+ kstd::weak_ptr<mount> m_source_mount{};
std::atomic_size_t m_ref_count;
};
} // namespace kernel::filesystem
diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp
index aec8bfe..e6f2327 100644
--- a/kernel/include/kernel/filesystem/vfs.hpp
+++ b/kernel/include/kernel/filesystem/vfs.hpp
@@ -32,8 +32,7 @@ namespace kernel::filesystem
non_existent_path = -2,
mount_point_not_found = -3,
unmount_failed = -4,
- invalid_filesystem = -5,
- close_failed = -6
+ invalid_filesystem = -5
};
/**
@@ -103,8 +102,8 @@ namespace kernel::filesystem
[[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr<mount>;
auto do_mount_internal(kstd::shared_ptr<dentry> const & mount_point_dentry,
- kstd::shared_ptr<mount> const & parent_mount, kstd::shared_ptr<filesystem> const & fs)
- -> void;
+ kstd::shared_ptr<mount> const & parent_mount, kstd::shared_ptr<filesystem> const & fs,
+ kstd::shared_ptr<mount> const & source_mount = nullptr) -> void;
auto graft_persistent_device_fs(kstd::shared_ptr<devfs::filesystem> const & device_fs) -> void;
diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp
index b64c370..ead7479 100644
--- a/kernel/src/filesystem/mount.cpp
+++ b/kernel/src/filesystem/mount.cpp
@@ -14,11 +14,13 @@
namespace kernel::filesystem
{
mount::mount(kstd::shared_ptr<dentry> const & mount_dentry, kstd::shared_ptr<dentry> const & root_dentry,
- kstd::shared_ptr<filesystem> const & fs, kstd::shared_ptr<mount> const & parent_mount)
+ kstd::shared_ptr<filesystem> const & fs, kstd::shared_ptr<mount> const & parent_mount,
+ kstd::shared_ptr<mount> const & source_mount)
: m_mount_dentry(mount_dentry)
, m_root_dentry(root_dentry)
, m_filesystem(fs)
, m_parent_mount(parent_mount)
+ , m_source_mount(source_mount)
, m_ref_count(0)
{
if (!m_filesystem)
@@ -56,20 +58,24 @@ namespace kernel::filesystem
return m_parent_mount;
}
+ auto mount::source_mount() const -> kstd::shared_ptr<mount>
+ {
+ return m_source_mount.lock();
+ }
+
auto mount::increment_ref_count() -> void
{
m_ref_count += 1;
}
- auto mount::decrement_ref_count() -> bool
+ auto mount::decrement_ref_count() -> void
{
if (m_ref_count == 0)
{
- return false;
+ kapi::system::panic("[FILESYSTEM] decrement_ref_count() was called but ref_count is 0");
}
m_ref_count -= 1;
- return true;
}
auto mount::is_ready_to_unmount() const -> bool
diff --git a/kernel/src/filesystem/mount.tests.cpp b/kernel/src/filesystem/mount.tests.cpp
index 6b66571..c9ff82e 100644
--- a/kernel/src/filesystem/mount.tests.cpp
+++ b/kernel/src/filesystem/mount.tests.cpp
@@ -11,6 +11,8 @@
#include <catch2/catch_test_macros.hpp>
+#include <stdexcept>
+
SCENARIO("Mount construction", "[filesystem][mount]")
{
GIVEN("a filesystem and a root dentry")
@@ -21,7 +23,7 @@ SCENARIO("Mount construction", "[filesystem][mount]")
WHEN("constructing a mount with the filesystem and root dentry")
{
- auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr};
+ auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr, nullptr};
THEN("the mount has the correct filesystem, root dentry, mount dentry, and mount path")
{
@@ -32,9 +34,10 @@ SCENARIO("Mount construction", "[filesystem][mount]")
REQUIRE(mount.is_ready_to_unmount());
}
- THEN("the mount has no parent mount")
+ THEN("the mount has no parent mount and no source mount")
{
REQUIRE(mount.parent_mount() == nullptr);
+ REQUIRE(mount.source_mount() == nullptr);
}
}
@@ -42,7 +45,7 @@ SCENARIO("Mount construction", "[filesystem][mount]")
{
THEN("the constructor panics")
{
- REQUIRE_THROWS_AS((kernel::filesystem::mount{root_dentry, root_dentry, nullptr, nullptr}),
+ REQUIRE_THROWS_AS((kernel::filesystem::mount{root_dentry, root_dentry, nullptr, nullptr, nullptr}),
kernel::tests::cpu::halt);
}
}
@@ -60,7 +63,7 @@ SCENARIO("Mount reference counting", "[filesystem][mount]")
THEN("reference count can be incremented and decremented, the mount is ready to unmount when the reference "
"count == 0")
{
- auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr};
+ auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr, nullptr};
mount.increment_ref_count();
REQUIRE(mount.ref_count() == 1);
@@ -70,20 +73,20 @@ SCENARIO("Mount reference counting", "[filesystem][mount]")
REQUIRE(mount.ref_count() == 2);
REQUIRE_FALSE(mount.is_ready_to_unmount());
- REQUIRE(mount.decrement_ref_count());
+ mount.decrement_ref_count();
REQUIRE(mount.ref_count() == 1);
REQUIRE_FALSE(mount.is_ready_to_unmount());
- REQUIRE(mount.decrement_ref_count());
+ mount.decrement_ref_count();
REQUIRE(mount.ref_count() == 0);
REQUIRE(mount.is_ready_to_unmount());
}
THEN("decrementing reference count when it is already zero does not decrement it below zero")
{
- auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr};
+ auto mount = kernel::filesystem::mount{root_dentry, root_dentry, fs, nullptr, nullptr};
- REQUIRE_FALSE(mount.decrement_ref_count());
+ REQUIRE_THROWS_AS(mount.decrement_ref_count(), std::runtime_error);
REQUIRE(mount.ref_count() == 0);
REQUIRE(mount.is_ready_to_unmount());
}
diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp
index 26828b4..af8434b 100644
--- a/kernel/src/filesystem/mount_table.cpp
+++ b/kernel/src/filesystem/mount_table.cpp
@@ -22,6 +22,11 @@ namespace kernel::filesystem
{
m_mounts.push_back(mount);
+ if (auto source_mount = mount->source_mount())
+ {
+ source_mount->increment_ref_count();
+ }
+
if (auto mount_dentry = mount->mount_dentry())
{
mount_dentry->set_flag(dentry::dentry_flags::is_mount_point);
@@ -46,7 +51,16 @@ namespace kernel::filesystem
return operation_result::has_child_mounts;
}
- mount->mount_dentry()->unset_flag(dentry::dentry_flags::is_mount_point);
+ if (auto source_mount = mount->source_mount())
+ {
+ source_mount->decrement_ref_count();
+ }
+
+ if (auto mount_dentry = mount->mount_dentry())
+ {
+ mount_dentry->unset_flag(dentry::dentry_flags::is_mount_point);
+ }
+
m_mounts.erase(mount_it);
return operation_result::removed;
}
diff --git a/kernel/src/filesystem/mount_table.tests.cpp b/kernel/src/filesystem/mount_table.tests.cpp
index f22b25e..19b47b2 100644
--- a/kernel/src/filesystem/mount_table.tests.cpp
+++ b/kernel/src/filesystem/mount_table.tests.cpp
@@ -38,14 +38,14 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem]
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
auto mount_dentry1 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
- auto mount1 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry1, root_dentry1, fs1, nullptr);
+ auto mount1 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry1, root_dentry1, fs1, nullptr, nullptr);
auto fs2 = kstd::make_shared<kernel::tests::filesystem::filesystem>();
auto root_dentry2 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
auto mount_dentry2 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/mnt");
- auto mount2 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry2, root_dentry2, fs2, nullptr);
+ auto mount2 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry2, root_dentry2, fs2, nullptr, nullptr);
table.add_mount(mount1);
table.add_mount(mount2);
@@ -89,14 +89,14 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem]
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
auto mount_dentry1 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
- auto mount1 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry1, root_dentry1, fs1, nullptr);
+ auto mount1 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry1, root_dentry1, fs1, nullptr, nullptr);
auto fs2 = kstd::make_shared<kernel::tests::filesystem::filesystem>();
auto root_dentry2 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
auto mount_dentry2 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
- auto mount2 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry2, root_dentry2, fs2, nullptr);
+ auto mount2 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry2, root_dentry2, fs2, nullptr, nullptr);
table.add_mount(mount1);
table.add_mount(mount2);
@@ -122,21 +122,21 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem]
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
auto mount_dentry1 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
- auto mount1 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry1, root_dentry1, fs1, nullptr);
+ auto mount1 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry1, root_dentry1, fs1, nullptr, nullptr);
auto fs2 = kstd::make_shared<kernel::tests::filesystem::filesystem>();
auto root_dentry2 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
auto mount_dentry2 = kstd::make_shared<kernel::filesystem::dentry>(
mount_dentry1, kstd::make_shared<kernel::tests::filesystem::inode>(), "mnt");
- auto mount2 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry2, root_dentry2, fs2, mount1);
+ auto mount2 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry2, root_dentry2, fs2, mount1, nullptr);
auto fs3 = kstd::make_shared<kernel::tests::filesystem::filesystem>();
auto root_dentry3 = kstd::make_shared<kernel::filesystem::dentry>(
nullptr, kstd::make_shared<kernel::tests::filesystem::inode>(), "/");
auto mount_dentry3 = kstd::make_shared<kernel::filesystem::dentry>(
mount_dentry2, kstd::make_shared<kernel::tests::filesystem::inode>(), "submnt");
- auto mount3 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry3, root_dentry3, fs3, mount2);
+ auto mount3 = kstd::make_shared<kernel::filesystem::mount>(mount_dentry3, root_dentry3, fs3, mount2, nullptr);
table.add_mount(mount1);
table.add_mount(mount2);
@@ -155,3 +155,30 @@ SCENARIO("Adding, finding and removing mounts in the mount table", "[filesystem]
}
}
}
+
+SCENARIO("Mount reference counting", "[filesystem][mount_table]")
+{
+ kernel::filesystem::mount_table table;
+
+ GIVEN("a filesystem and a root dentry")
+ {
+ auto fs = kstd::make_shared<kernel::tests::filesystem::filesystem>();
+ auto root_inode = kstd::make_shared<kernel::tests::filesystem::inode>();
+ auto root_dentry = kstd::make_shared<kernel::filesystem::dentry>(nullptr, root_inode, "/");
+
+ auto source_mount = kstd::make_shared<kernel::filesystem::mount>(root_dentry, root_dentry, fs, nullptr, nullptr);
+ auto mount = kstd::make_shared<kernel::filesystem::mount>(root_dentry, root_dentry, fs, nullptr, source_mount);
+
+ THEN("reference count of source mount is incremented when a mount is added to the mount table and decremented when "
+ "the mount is removed")
+ {
+ REQUIRE(source_mount->ref_count() == 0);
+
+ table.add_mount(mount);
+ REQUIRE(source_mount->ref_count() == 1);
+
+ REQUIRE(table.remove_mount("/") == kernel::filesystem::mount_table::operation_result::removed);
+ REQUIRE(source_mount->ref_count() == 0);
+ }
+ }
+}
diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp
index bf9a77d..ae85291 100644
--- a/kernel/src/filesystem/vfs.cpp
+++ b/kernel/src/filesystem/vfs.cpp
@@ -47,7 +47,7 @@ namespace kernel::filesystem
root_fs->mount(nullptr);
auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode(), "/");
- auto root_mount = kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, nullptr);
+ auto root_mount = kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, nullptr, nullptr);
m_mount_table.add_mount(root_mount);
// mount devfs at /dev (inside rootfs, temporary, will be shadowed)
@@ -56,13 +56,14 @@ namespace kernel::filesystem
graft_persistent_device_fs(device_fs);
// mount boot fs at / (shadows rootfs), re-graft devfs
- if (auto boot_device_dentry = resolve_path("/dev/ram0"))
+ auto [boot_device_dentry, boot_device_mount_context] = resolve_path_internal("/dev/ram0");
+ if (boot_device_dentry && boot_device_mount_context)
{
if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode()))
{
if (auto root_dentry = resolve_path("/"))
{
- do_mount_internal(root_dentry, root_mount, boot_root_fs);
+ do_mount_internal(root_dentry, root_mount, boot_root_fs, boot_device_mount_context);
graft_persistent_device_fs(device_fs);
}
}
@@ -94,11 +95,8 @@ namespace kernel::filesystem
{
if (auto mount = find_mount(path))
{
- if (mount->decrement_ref_count())
- {
- return operation_result::success;
- }
- return operation_result::close_failed;
+ mount->decrement_ref_count();
+ return operation_result::success;
}
return operation_result::invalid_path;
}
@@ -111,14 +109,14 @@ namespace kernel::filesystem
}
auto [mount_point_dentry, mount_context] = resolve_path_internal(target);
-
if (mount_point_dentry && mount_context)
{
- if (auto source_dentry = resolve_path(source))
+ auto [source_dentry, source_mount_context] = resolve_path_internal(source);
+ if (source_dentry && source_mount_context)
{
if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode()))
{
- do_mount_internal(mount_point_dentry, mount_context, fs);
+ do_mount_internal(mount_point_dentry, mount_context, fs, source_mount_context);
return operation_result::success;
}
return operation_result::invalid_filesystem;
@@ -149,12 +147,12 @@ namespace kernel::filesystem
}
auto vfs::do_mount_internal(kstd::shared_ptr<dentry> const & mount_point_dentry,
- kstd::shared_ptr<mount> const & parent_mount, kstd::shared_ptr<filesystem> const & fs)
- -> void
+ kstd::shared_ptr<mount> const & parent_mount, kstd::shared_ptr<filesystem> const & fs,
+ kstd::shared_ptr<mount> const & source_mount) -> void
{
auto new_fs_root =
kstd::make_shared<dentry>(mount_point_dentry->parent(), fs->root_inode(), mount_point_dentry->name());
- auto new_mount = kstd::make_shared<mount>(mount_point_dentry, new_fs_root, fs, parent_mount);
+ auto new_mount = kstd::make_shared<mount>(mount_point_dentry, new_fs_root, fs, parent_mount, source_mount);
m_mount_table.add_mount(new_mount);
}
diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp
index 6fcc84e..962e067 100644
--- a/kernel/src/filesystem/vfs.tests.cpp
+++ b/kernel/src/filesystem/vfs.tests.cpp
@@ -10,6 +10,7 @@
#include <cstddef>
#include <filesystem>
+#include <stdexcept>
#include <string_view>
SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS with dummy modules",
@@ -156,7 +157,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
THEN("file with invalid path or not opened file cannot be closed")
{
REQUIRE(vfs.close("invalid_path") == kernel::filesystem::vfs::operation_result::invalid_path);
- REQUIRE(vfs.close("/information/info_1.txt") == kernel::filesystem::vfs::operation_result::close_failed);
+ REQUIRE_THROWS_AS(vfs.close("/information/info_1.txt"), std::runtime_error);
}
THEN("file cannot be closed twice")
@@ -165,7 +166,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
REQUIRE(info_1 != nullptr);
REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.close(info_1->absolute_path().view()) == kernel::filesystem::vfs::operation_result::close_failed);
+ REQUIRE_THROWS_AS(vfs.close(info_1->absolute_path().view()), std::runtime_error);
}
THEN("images can be stacked mounted and correct file system is unmounted again")
@@ -415,6 +416,37 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
}
}
+ GIVEN("two real image files where the second contains as filesystem formatted files")
+ {
+ REQUIRE(std::filesystem::exists(image_path_1));
+ REQUIRE(std::filesystem::exists(image_path_3));
+ REQUIRE_NOTHROW(
+ setup_modules_from_img_and_init_vfs({"test_img_module_3", "test_img_module_1"}, {image_path_3, image_path_1}));
+
+ auto & vfs = kernel::filesystem::vfs::get();
+
+ THEN("cannot unmount a filesystem if files are mounted")
+ {
+ REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/enclosures") ==
+ kernel::filesystem::vfs::operation_result::success);
+
+ REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::unmount_failed);
+ REQUIRE(vfs.unmount("/enclosures") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success);
+ }
+
+ THEN("can mount filesystem onto the directory that contains it")
+ {
+ REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/entrance") ==
+ kernel::filesystem::vfs::operation_result::success);
+
+ REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success);
+ }
+ }
+
GIVEN("A real image files, containing symbolic links")
{
REQUIRE(std::filesystem::exists(image_path_1));
diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp
index 22d2b1e..6985e94 100644
--- a/kernel/src/main.cpp
+++ b/kernel/src/main.cpp
@@ -13,7 +13,6 @@
#include <kapi/system.hpp>
#include <kstd/format>
-#include <kstd/os/error.hpp>
#include <kstd/print>
#include <kstd/units>
#include <kstd/vector>
@@ -26,57 +25,84 @@ using namespace kstd::units_literals;
auto run_demo() -> void
{
// 1) open a file
+ kstd::println("attempting to open /entrance/tickets.txt");
auto fd_1 = kapi::filesystem::open("/entrance/tickets.txt");
if (fd_1 == -1)
{
- kstd::os::panic("demo failed");
+ kapi::system::panic("demo failed");
+ }
+ else
+ {
+ kstd::println("--> successfully opened /entrance/tickets.txt with file descriptor {}", fd_1);
}
// 2) read from the file
kstd::vector<std::byte> buffer_1{10};
auto bytes_read = kapi::filesystem::read(fd_1, buffer_1.data(), buffer_1.size());
auto buffer_as_str = std::string_view{reinterpret_cast<char *>(buffer_1.data()), static_cast<size_t>(bytes_read)};
- kstd::println("Read {} bytes from /entrance/tickets.txt: {}", bytes_read, buffer_as_str);
+ kstd::println("--> read {} bytes from /entrance/tickets.txt: {}", bytes_read, buffer_as_str);
+ kstd::println("");
// 3) show that /entrance/information/info_1.txt is not accessible before mounting
+ kstd::println("attempting to open /entrance/information/info_1.txt before mounting");
auto fd_before_mount = kapi::filesystem::open("/entrance/information/info_1.txt");
if (fd_before_mount == -1)
{
- kstd::println("/entrance/information/info_1.txt is not accessible before mounting, as expected.");
+ kstd::println("--> as expected the file could not be opened before mounting");
}
// 4) mount a new filesystem on top of /entrance
- kapi::filesystem::mount("/dev/ram16", "/entrance");
+ kstd::println("mount /dev/ram16 to /entrance");
+ if (kapi::filesystem::mount("/dev/ram16", "/entrance") == 0)
+ {
+ kstd::println("--> successfully mounted /dev/ram16 to /entrance");
+ }
+ else
+ {
+ kapi::system::panic("demo failed");
+ }
+ kstd::println("");
// 5) open a file from the new filesystem
+ kstd::println("attempting to open /entrance/information/info_1.txt");
auto fd_2 = kapi::filesystem::open("/entrance/information/info_1.txt");
- if (fd_2 == -1)
+ if (fd_2 != -1)
+ {
+ kstd::println("--> successfully opened /entrance/information/info_1.txt with file descriptor {}", fd_2);
+ }
+ else
{
- kstd::os::panic("demo failed");
+ kapi::system::panic("demo failed");
}
// 6) read from the new file
kstd::vector<std::byte> buffer_2{10};
bytes_read = kapi::filesystem::read(fd_2, buffer_2.data(), buffer_2.size());
buffer_as_str = std::string_view{reinterpret_cast<char *>(buffer_2.data()), static_cast<size_t>(bytes_read)};
- kstd::println("Read {} bytes from /entrance/information/info_1.txt: {}", bytes_read, buffer_as_str);
+ kstd::println("--> read {} bytes from /entrance/information/info_1.txt: {} ", bytes_read, buffer_as_str);
// 7) open device as file
- auto fd_3 = kapi::filesystem::open("/dev/ram48");
- if (fd_3 == -1)
+ kstd::println("attempting to open /dev/ram32 as a file");
+ auto fd_3 = kapi::filesystem::open("/dev/ram32");
+ if (fd_3 != -1)
+ {
+ kstd::println("--> successfully opened /dev/ram32 as a file with file descriptor {}", fd_3);
+ }
+ else
{
- kstd::os::panic("demo failed");
+ kapi::system::panic("demo failed");
}
// 8) read from the device file
kstd::vector<std::byte> buffer_3{2};
bytes_read = kapi::filesystem::read(fd_3, buffer_3.data(), buffer_3.size());
- kstd::println("Read {} bytes from /dev/ram48: {::#04x}", bytes_read, buffer_3);
+ kstd::println("--> read {} bytes from /dev/ram32: {::#04x} ", bytes_read, buffer_3);
// 9) write to the device file
- kstd::vector<std::byte> write_buffer{std::byte{0xAA}, std::byte{0xAA}};
+ auto const default_buffer_value = std::byte{0xAA};
+ kstd::vector<std::byte> write_buffer{default_buffer_value, default_buffer_value};
auto bytes_written = kapi::filesystem::write(fd_3, write_buffer.data(), write_buffer.size());
- kstd::println("Written {} bytes to /dev/ram48: {::#04x}", bytes_written, write_buffer);
+ kstd::println("--> written {} bytes to /dev/ram32: {::#04x}", bytes_written, write_buffer);
// 10) do memory dump to show that the write to the device file had an effect
}