aboutsummaryrefslogtreecommitdiff
path: root/kernel/src
diff options
context:
space:
mode:
authorLukas Oesch <lukasoesch20@gmail.com>2026-04-08 15:21:10 +0200
committerLukas Oesch <lukasoesch20@gmail.com>2026-04-11 07:58:21 +0200
commit2793770dc6eba30b73b4a4993618d2cbe184790e (patch)
treeb3e18a675aecf20a5356b36985628b0c59b0c52b /kernel/src
parent9c0fb15aa67a4dda6beed3cbdfc4cc510674313f (diff)
downloadteachos-2793770dc6eba30b73b4a4993618d2cbe184790e.tar.xz
teachos-2793770dc6eba30b73b4a4993618d2cbe184790e.zip
implement unmount, improve error codes
Diffstat (limited to 'kernel/src')
-rw-r--r--kernel/src/filesystem/devfs/filesystem.cpp5
-rw-r--r--kernel/src/filesystem/ext2/filesystem.cpp12
-rw-r--r--kernel/src/filesystem/filesystem.cpp6
-rw-r--r--kernel/src/filesystem/mount.cpp9
-rw-r--r--kernel/src/filesystem/mount_table.cpp69
-rw-r--r--kernel/src/filesystem/rootfs/filesystem.cpp4
-rw-r--r--kernel/src/filesystem/vfs.cpp45
-rw-r--r--kernel/src/main.cpp3
8 files changed, 121 insertions, 32 deletions
diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp
index 9043ac5..03b4218 100644
--- a/kernel/src/filesystem/devfs/filesystem.cpp
+++ b/kernel/src/filesystem/devfs/filesystem.cpp
@@ -1,6 +1,7 @@
#include "kernel/filesystem/devfs/filesystem.hpp"
#include "kapi/devices/device.hpp"
+
#include "kernel/devices/storage/management.hpp"
#include "kernel/filesystem/devfs/inode.hpp"
#include "kernel/filesystem/device_inode.hpp"
@@ -13,12 +14,12 @@
namespace kernel::filesystem::devfs
{
- auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const &) -> int
+ auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const &) -> operation_result
{
m_root_inode = kstd::make_shared<inode>();
build_device_inode_table();
- return 0;
+ return operation_result::success;
}
auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name)
diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp
index 7ee1072..6d5960e 100644
--- a/kernel/src/filesystem/ext2/filesystem.cpp
+++ b/kernel/src/filesystem/ext2/filesystem.cpp
@@ -36,10 +36,6 @@ namespace kernel::filesystem::ext2
constexpr uint16_t S_IFREG = 0x8000;
constexpr uint16_t S_IFDIR = 0x4000;
- // Error codes
- constexpr int INVALID_MAGIC_NUMBER = -1;
- constexpr int INVALID_ROOT_INODE = -2;
-
auto S_ISREG(uint16_t mode) -> bool
{
return (mode & S_IFMT) == S_IFREG;
@@ -51,7 +47,7 @@ namespace kernel::filesystem::ext2
}
} // namespace
- auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const & device) -> int
+ auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result
{
kernel::filesystem::filesystem::mount(device);
@@ -59,7 +55,7 @@ namespace kernel::filesystem::ext2
if (m_superblock.magic != MAGIC_NUMBER)
{
- return INVALID_MAGIC_NUMBER;
+ return operation_result::invalid_magic_number;
}
auto const block_size = get_block_size();
@@ -77,9 +73,9 @@ namespace kernel::filesystem::ext2
if (!m_root_inode || !m_root_inode->is_directory())
{
- return INVALID_ROOT_INODE;
+ return operation_result::invalid_root_inode;
}
- return 0;
+ return operation_result::success;
}
auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name)
diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp
index b08b520..da2838d 100644
--- a/kernel/src/filesystem/filesystem.cpp
+++ b/kernel/src/filesystem/filesystem.cpp
@@ -30,7 +30,7 @@ namespace kernel::filesystem
for (auto & factory : filesystem_factories)
{
auto fs = factory();
- if (fs->mount(device) == 0)
+ if (fs->mount(device) == operation_result::success)
{
return fs;
}
@@ -39,11 +39,11 @@ namespace kernel::filesystem
return nullptr;
}
- auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const & device) -> int
+ auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result
{
// TODO BA-FS26 maybe check if device is null and panic here already?
m_device = device;
- return 0;
+ return operation_result::success;
}
auto filesystem::root_inode() const -> kstd::shared_ptr<inode> const &
diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp
index a6d2f7e..d165385 100644
--- a/kernel/src/filesystem/mount.cpp
+++ b/kernel/src/filesystem/mount.cpp
@@ -13,11 +13,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, std::string_view mount_path)
+ kstd::shared_ptr<filesystem> const & fs, std::string_view mount_path,
+ kstd::shared_ptr<mount> const & parent_mount)
: m_mount_path(mount_path)
, m_mount_dentry(mount_dentry)
, m_root_dentry(root_dentry)
, m_filesystem(fs)
+ , m_parent_mount(parent_mount)
{
if (!m_filesystem)
{
@@ -44,4 +46,9 @@ namespace kernel::filesystem
{
return m_mount_path.view();
}
+
+ auto mount::get_parent_mount() const -> kstd::shared_ptr<mount> const &
+ {
+ return m_parent_mount;
+ }
} // namespace kernel::filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp
index 195f48a..3b1dee3 100644
--- a/kernel/src/filesystem/mount_table.cpp
+++ b/kernel/src/filesystem/mount_table.cpp
@@ -1,17 +1,83 @@
#include "kernel/filesystem/mount_table.hpp"
+#include "kernel/filesystem/dentry.hpp"
#include "kernel/filesystem/mount.hpp"
#include <kstd/memory>
+#include <kstd/vector>
+#include <algorithm>
#include <cstddef>
+#include <ranges>
#include <string_view>
namespace kernel::filesystem
{
+ namespace
+ {
+ auto is_descendant_of(kstd::shared_ptr<mount> const & candidate, kstd::shared_ptr<mount> const & ancestor) -> bool
+ {
+ for (auto current = candidate; current; current = current->get_parent_mount())
+ {
+ if (current == ancestor)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ auto is_strict_prefix(std::string_view prefix, std::string_view path) -> bool
+ {
+ return prefix != "/" && path.starts_with(prefix) && path.size() > prefix.size() && path[prefix.size()] == '/';
+ }
+
+ auto is_visible_mount(kstd::shared_ptr<mount> const & candidate,
+ kstd::vector<kstd::shared_ptr<mount>> const & mounts) -> bool
+ {
+ return std::ranges::none_of(mounts, [&](auto const & other) {
+ return other != candidate && is_strict_prefix(other->get_mount_path(), candidate->get_mount_path()) &&
+ !is_descendant_of(candidate, other);
+ });
+ }
+ } // namespace
+
+ auto mount_table::has_child_mounts(kstd::shared_ptr<mount> const & parent_mount) const -> bool
+ {
+ return std::ranges::any_of(
+ m_mounts, [&parent_mount](auto const & mount) { return mount->get_parent_mount() == parent_mount; });
+ }
+
void mount_table::add_mount(kstd::shared_ptr<mount> const & mount)
{
m_mounts.push_back(mount);
+ if (auto mount_dentry = mount->get_mount_dentry())
+ {
+ mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted);
+ }
+ }
+
+ auto mount_table::remove_mount(std::string_view path) -> operation_result
+ {
+ auto mount_it = std::ranges::find_if(std::ranges::reverse_view(m_mounts), [&](auto const & mount) {
+ return mount->get_mount_path() == path && is_visible_mount(mount, m_mounts);
+ });
+
+ if (mount_it == std::ranges::reverse_view(m_mounts).end())
+ {
+ return operation_result::mount_not_found;
+ }
+
+ auto const & mount = *mount_it;
+ if (has_child_mounts(mount))
+ {
+ return operation_result::has_child_mounts;
+ }
+
+ mount->get_mount_dentry()->unset_flag(dentry::dentry_flags::dcache_mounted);
+ m_mounts.erase(std::ranges::find(m_mounts, mount));
+ return operation_result::removed;
}
auto mount_table::find_longest_prefix_mount(std::string_view path) const -> kstd::shared_ptr<mount>
@@ -25,8 +91,9 @@ namespace kernel::filesystem
// /a/b/c should match /a/b but not /a/bb or /a/b/c/d, / should match everything
bool is_prefix = path.starts_with(mp) && (mp == "/" || path.size() == mp.size() || path[mp.size()] == '/');
+ bool visible = is_visible_mount(mount, m_mounts);
- if (is_prefix && mp.size() >= best_len)
+ if (is_prefix && visible && mp.size() >= best_len)
{
mount_with_longest_prefix = mount;
best_len = mp.size();
diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp
index a7c746e..dffef99 100644
--- a/kernel/src/filesystem/rootfs/filesystem.cpp
+++ b/kernel/src/filesystem/rootfs/filesystem.cpp
@@ -11,13 +11,13 @@
namespace kernel::filesystem::rootfs
{
- auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const &) -> int
+ auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const &) -> operation_result
{
auto rfs_inode = kstd::make_shared<inode>();
rfs_inode->add_child("dev");
m_root_inode = rfs_inode;
- return 0;
+ return operation_result::success;
}
auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name)
diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp
index 2578036..45ae053 100644
--- a/kernel/src/filesystem/vfs.cpp
+++ b/kernel/src/filesystem/vfs.cpp
@@ -7,6 +7,7 @@
#include "kernel/filesystem/devfs/filesystem.hpp"
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/mount.hpp"
+#include "kernel/filesystem/mount_table.hpp"
#include "kernel/filesystem/open_file_description.hpp"
#include "kernel/filesystem/rootfs/filesystem.hpp"
@@ -21,11 +22,6 @@ namespace kernel::filesystem
namespace
{
constinit auto static active_vfs = std::optional<vfs>{};
-
- // Error codes
- constexpr int INVALID_PATH = -1;
- constexpr int MOUNT_POINT_NOT_FOUND = -2;
- constexpr int FILESYSTEM_NULL = -3;
} // namespace
auto vfs::init() -> void
@@ -45,7 +41,7 @@ namespace kernel::filesystem
root_fs->mount(nullptr);
auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode());
- m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, ""));
+ m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, "", nullptr));
auto storage_mgmt = devices::storage::management::get();
if (auto boot_device = storage_mgmt.determine_boot_device())
@@ -79,36 +75,55 @@ namespace kernel::filesystem
return nullptr;
}
- // TODO BA-FS26 implement unmount
- auto vfs::do_mount(std::string_view path, kstd::shared_ptr<filesystem> const & filesystem) -> int
+ auto vfs::do_mount(std::string_view path, kstd::shared_ptr<filesystem> const & filesystem) -> operation_result
{
if (!filesystem)
{
- return FILESYSTEM_NULL;
+ return operation_result::filesystem_null;
}
if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/'))
{
- return INVALID_PATH;
+ return operation_result::invalid_path;
}
if (auto mount_point_dentry = resolve_path(path))
{
do_mount_internal(path, mount_point_dentry, filesystem);
- return 0;
+ return operation_result::success;
+ }
+
+ return operation_result::mount_point_not_found;
+ }
+
+ auto vfs::unmount(std::string_view path) -> operation_result
+ {
+ if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/'))
+ {
+ return operation_result::invalid_path;
+ }
+
+ auto remove_result = m_mount_table.remove_mount(path);
+ if (remove_result == mount_table::operation_result::removed)
+ {
+ return operation_result::success;
+ }
+
+ if (remove_result == mount_table::operation_result::has_child_mounts)
+ {
+ return operation_result::unmount_failed;
}
- return MOUNT_POINT_NOT_FOUND;
+ return operation_result::mount_point_not_found;
}
auto vfs::do_mount_internal(std::string_view path, kstd::shared_ptr<dentry> const & mount_point_dentry,
kstd::shared_ptr<filesystem> const & fs) -> void
{
- // TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.)
+ auto parent_mount = m_mount_table.find_longest_prefix_mount(path);
auto new_fs_root = kstd::make_shared<dentry>(mount_point_dentry, fs->root_inode());
- auto new_mount = kstd::make_shared<mount>(mount_point_dentry, new_fs_root, fs, path);
+ auto new_mount = kstd::make_shared<mount>(mount_point_dentry, new_fs_root, fs, path, parent_mount);
m_mount_table.add_mount(new_mount);
- mount_point_dentry->set_flag(dentry::dentry_flags::dcache_mounted);
}
auto vfs::resolve_path(std::string_view path) -> kstd::shared_ptr<dentry>
diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp
index 1893b84..1d73e20 100644
--- a/kernel/src/main.cpp
+++ b/kernel/src/main.cpp
@@ -145,6 +145,9 @@ auto test_file_lookup() -> void
vfs.do_mount("/enclosures/aquarium", new_filesystem);
read_and_write_file("/enclosures/aquarium/closed.txt");
read_and_write_file("/enclosures/aquarium/information/info_2.txt");
+
+ vfs.unmount("/enclosures/aquarium");
+ read_and_write_file("/enclosures/aquarium/tank_1/fish_4.txt");
}
auto run_test_code() -> void