aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorLukas Oesch <lukasoesch20@gmail.com>2026-03-24 23:54:28 +0100
committerLukas Oesch <lukasoesch20@gmail.com>2026-03-26 21:19:30 +0100
commit84d4476650b31dbfc52becf2ff65ddce9d31c9ec (patch)
treeeb4e69e2148690d654303dc145c3f71d94ea9bd9 /kernel
parent76de81de1e12694bf6bec1edd3e3409092a92d09 (diff)
downloadteachos-84d4476650b31dbfc52becf2ff65ddce9d31c9ec.tar.xz
teachos-84d4476650b31dbfc52becf2ff65ddce9d31c9ec.zip
implement a rootfs to handle / mounts correctly
Diffstat (limited to 'kernel')
-rw-r--r--kernel/CMakeLists.txt2
-rw-r--r--kernel/include/kernel/filesystem/filesystem.hpp5
-rw-r--r--kernel/include/kernel/filesystem/mount.hpp10
-rw-r--r--kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp21
-rw-r--r--kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp19
-rw-r--r--kernel/src/filesystem/filesystem.cpp11
-rw-r--r--kernel/src/filesystem/mount.cpp15
-rw-r--r--kernel/src/filesystem/mount_table.cpp14
-rw-r--r--kernel/src/filesystem/rootfs/rootfs_filesystem.cpp24
-rw-r--r--kernel/src/filesystem/rootfs/rootfs_inode.cpp22
-rw-r--r--kernel/src/filesystem/vfs.cpp43
-rw-r--r--kernel/src/main.cpp10
12 files changed, 149 insertions, 47 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index ee1f585..406ac54 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -32,6 +32,8 @@ add_executable("kernel"
"src/filesystem/mount_table.cpp"
"src/filesystem/mount.cpp"
"src/filesystem/open_file_description.cpp"
+ "src/filesystem/rootfs/rootfs_filesystem.cpp"
+ "src/filesystem/rootfs/rootfs_inode.cpp"
"src/filesystem/vfs.cpp"
)
diff --git a/kernel/include/kernel/filesystem/filesystem.hpp b/kernel/include/kernel/filesystem/filesystem.hpp
index 362242f..e069ced 100644
--- a/kernel/include/kernel/filesystem/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/filesystem.hpp
@@ -2,7 +2,6 @@
#define TEACH_OS_KERNEL_FILESYSTEM_FILESYSTEM_HPP
#include "kernel/devices/device.hpp"
-#include "kernel/filesystem/dentry.hpp"
#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
@@ -20,15 +19,11 @@ namespace filesystem
virtual auto lookup(kstd::shared_ptr<inode> const & parent, std::string_view name) -> kstd::shared_ptr<inode> = 0;
[[nodiscard]] auto root_inode() const -> kstd::shared_ptr<inode> const &;
- [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr<dentry> const &;
-
- auto set_root_dentry(kstd::shared_ptr<dentry> dentry) -> void;
protected:
kstd::shared_ptr<inode> m_root_inode{};
kstd::shared_ptr<devices::device> m_device{};
kstd::vector<kstd::shared_ptr<inode>> m_inodes{};
- kstd::shared_ptr<dentry> m_root_dentry;
};
} // namespace filesystem
diff --git a/kernel/include/kernel/filesystem/mount.hpp b/kernel/include/kernel/filesystem/mount.hpp
index dd47ce7..0cd30b4 100644
--- a/kernel/include/kernel/filesystem/mount.hpp
+++ b/kernel/include/kernel/filesystem/mount.hpp
@@ -10,13 +10,17 @@ namespace filesystem
{
struct mount
{
- mount(kstd::shared_ptr<dentry> const & mount_dentry, kstd::shared_ptr<filesystem> const & fs);
+ mount(kstd::shared_ptr<dentry> const & mount_dentry, kstd::shared_ptr<dentry> const & root_dentry,
+ kstd::shared_ptr<filesystem> const & fs);
+
+ [[nodiscard]] auto get_mount_dentry() const -> kstd::shared_ptr<dentry>;
+ [[nodiscard]] auto root_dentry() const -> kstd::shared_ptr<dentry> const &;
- [[nodiscard]] auto get_dentry() const -> kstd::shared_ptr<dentry>;
[[nodiscard]] auto get_filesystem() const -> kstd::shared_ptr<filesystem> const &;
private:
- kstd::shared_ptr<dentry> m_dentry;
+ kstd::shared_ptr<dentry> m_mount_dentry;
+ kstd::shared_ptr<dentry> m_root_dentry;
kstd::shared_ptr<filesystem> m_filesystem{};
};
} // namespace filesystem
diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp
new file mode 100644
index 0000000..949ac83
--- /dev/null
+++ b/kernel/include/kernel/filesystem/rootfs/rootfs_filesystem.hpp
@@ -0,0 +1,21 @@
+#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_FILESYSTEM_HPP
+#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_FILESYSTEM_HPP
+
+#include "kernel/devices/device.hpp"
+#include "kernel/filesystem/filesystem.hpp"
+#include "kernel/filesystem/inode.hpp"
+
+#include <kstd/memory>
+
+#include <string_view>
+
+namespace filesystem::rootfs
+{
+ struct rootfs_filesystem : filesystem
+ {
+ auto mount(kstd::shared_ptr<devices::device> const & device) -> int override;
+ auto lookup(kstd::shared_ptr<inode> const & parent, std::string_view name) -> kstd::shared_ptr<inode> override;
+ };
+} // namespace filesystem::rootfs
+
+#endif
diff --git a/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp
new file mode 100644
index 0000000..d533e8e
--- /dev/null
+++ b/kernel/include/kernel/filesystem/rootfs/rootfs_inode.hpp
@@ -0,0 +1,19 @@
+#ifndef TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_INODE_HPP
+#define TEACH_OS_KERNEL_FILESYSTEM_ROOTFS_ROOTFS_INODE_HPP
+
+#include "kernel/filesystem/inode.hpp"
+
+#include <cstddef>
+
+namespace filesystem::rootfs
+{
+ struct rootfs_inode : inode
+ {
+ rootfs_inode();
+
+ auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
+ auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+ };
+} // namespace filesystem::rootfs
+
+#endif
diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp
index 8ebe58f..0e33d95 100644
--- a/kernel/src/filesystem/filesystem.cpp
+++ b/kernel/src/filesystem/filesystem.cpp
@@ -1,7 +1,6 @@
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/devices/device.hpp"
-#include "kernel/filesystem/dentry.hpp"
#include "kernel/filesystem/inode.hpp"
#include <kstd/memory>
@@ -22,14 +21,4 @@ namespace filesystem
{
return m_root_inode;
}
-
- auto filesystem::root_dentry() const -> kstd::shared_ptr<dentry> const &
- {
- return m_root_dentry;
- }
-
- auto filesystem::set_root_dentry(kstd::shared_ptr<dentry> dentry) -> void
- {
- m_root_dentry = dentry;
- }
} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/mount.cpp b/kernel/src/filesystem/mount.cpp
index b65f331..d9937dc 100644
--- a/kernel/src/filesystem/mount.cpp
+++ b/kernel/src/filesystem/mount.cpp
@@ -11,8 +11,10 @@
namespace filesystem
{
- mount::mount(kstd::shared_ptr<dentry> const & mount_dentry, kstd::shared_ptr<filesystem> const & fs)
- : m_dentry(mount_dentry)
+ mount::mount(kstd::shared_ptr<dentry> const & mount_dentry, kstd::shared_ptr<dentry> const & root_dentry,
+ kstd::shared_ptr<filesystem> const & fs)
+ : m_mount_dentry(mount_dentry)
+ , m_root_dentry(root_dentry)
, m_filesystem(fs)
{
if (!m_filesystem)
@@ -21,13 +23,18 @@ namespace filesystem
}
}
- auto mount::get_dentry() const -> kstd::shared_ptr<dentry>
+ auto mount::get_mount_dentry() const -> kstd::shared_ptr<dentry>
{
- return m_dentry;
+ return m_mount_dentry;
}
auto mount::get_filesystem() const -> kstd::shared_ptr<filesystem> const &
{
return m_filesystem;
}
+
+ auto mount::root_dentry() const -> kstd::shared_ptr<dentry> const &
+ {
+ return m_root_dentry;
+ }
} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/mount_table.cpp b/kernel/src/filesystem/mount_table.cpp
index debb9ab..681c2b9 100644
--- a/kernel/src/filesystem/mount_table.cpp
+++ b/kernel/src/filesystem/mount_table.cpp
@@ -1,7 +1,5 @@
#include "kernel/filesystem/mount_table.hpp"
-#include "kapi/system.hpp"
-
#include "kernel/filesystem/dentry.hpp"
#include "kernel/filesystem/mount.hpp"
@@ -18,18 +16,14 @@ namespace filesystem
auto mount_table::get_root_mount() const -> kstd::shared_ptr<mount>
{
- auto it =
- std::ranges::find_if(m_mounts, [](auto const & mount) { return mount->get_dentry()->get_parent() == nullptr; });
+ auto it = std::ranges::find_if(m_mounts, [](auto const & mount) { return mount->get_mount_dentry() == nullptr; });
return it != m_mounts.end() ? *it : nullptr;
}
auto mount_table::find_mount_by_dentry(kstd::shared_ptr<dentry> const & dentry) -> kstd::shared_ptr<mount>
{
- auto it = std::ranges::find_if(m_mounts, [&](auto const & mount) { return mount->get_dentry() == dentry; });
- if (it != m_mounts.end())
- {
- return *it;
- }
- kapi::system::panic("[FILESYSTEM] dentry has mount flag set but no corresponding mount found.");
+ auto it = std::ranges::find_if(m_mounts, [&](auto const & mnt) { return mnt->get_mount_dentry() == dentry; });
+
+ return it != m_mounts.end() ? *it : nullptr;
}
} // namespace filesystem \ No newline at end of file
diff --git a/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp
new file mode 100644
index 0000000..22b1962
--- /dev/null
+++ b/kernel/src/filesystem/rootfs/rootfs_filesystem.cpp
@@ -0,0 +1,24 @@
+#include "kernel/filesystem/rootfs/rootfs_filesystem.hpp"
+
+#include "kernel/devices/device.hpp"
+#include "kernel/filesystem/inode.hpp"
+#include "kernel/filesystem/rootfs/rootfs_inode.hpp"
+
+#include <kstd/memory>
+
+#include <string_view>
+
+namespace filesystem::rootfs
+{
+ auto rootfs_filesystem::mount(kstd::shared_ptr<devices::device> const & /*device*/) -> int
+ {
+ m_root_inode = kstd::make_shared<rootfs_inode>();
+ return 0;
+ }
+
+ auto rootfs_filesystem::lookup(kstd::shared_ptr<inode> const & /*parent*/, std::string_view /*name*/)
+ -> kstd::shared_ptr<inode>
+ {
+ return nullptr;
+ }
+} // namespace filesystem::rootfs
diff --git a/kernel/src/filesystem/rootfs/rootfs_inode.cpp b/kernel/src/filesystem/rootfs/rootfs_inode.cpp
new file mode 100644
index 0000000..ed057f7
--- /dev/null
+++ b/kernel/src/filesystem/rootfs/rootfs_inode.cpp
@@ -0,0 +1,22 @@
+#include "kernel/filesystem/rootfs/rootfs_inode.hpp"
+
+#include "kernel/filesystem/inode.hpp"
+
+#include <cstddef>
+
+namespace filesystem::rootfs
+{
+ rootfs_inode::rootfs_inode()
+ : inode(inode_kind::directory)
+ {}
+
+ auto rootfs_inode::read(void * /*buffer*/, size_t /*offset*/, size_t /*size*/) const -> size_t
+ {
+ return 0;
+ }
+
+ auto rootfs_inode::write(void const * /*buffer*/, size_t /*offset*/, size_t /*size*/) -> size_t
+ {
+ return 0;
+ }
+} // namespace filesystem::rootfs
diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp
index c8e5bc5..1c4dd8b 100644
--- a/kernel/src/filesystem/vfs.cpp
+++ b/kernel/src/filesystem/vfs.cpp
@@ -10,6 +10,7 @@
#include "kernel/filesystem/filesystem.hpp"
#include "kernel/filesystem/mount.hpp"
#include "kernel/filesystem/open_file_description.hpp"
+#include "kernel/filesystem/rootfs/rootfs_filesystem.hpp"
#include <kstd/memory>
@@ -38,16 +39,20 @@ namespace filesystem
auto vfs::init_internal() -> void
{
+ auto virtual_fs = kstd::make_shared<rootfs::rootfs_filesystem>();
+ virtual_fs->mount(nullptr);
+
+ auto virtual_root_dentry = kstd::make_shared<dentry>(nullptr, virtual_fs->root_inode(), "/");
+ m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, virtual_root_dentry, virtual_fs));
+
auto storage_mgmt = devices::storage::storage_management::get();
if (auto boot_device = storage_mgmt.determine_boot_device())
{
- auto root_fs = kstd::make_shared<ext2::ext2_filesystem>();
- root_fs->mount(boot_device);
+ // TODO BA-FS26 detect fs type from boot device and load corresponding fs, for now just assume ext2
+ auto boot_root_fs = kstd::make_shared<ext2::ext2_filesystem>();
+ boot_root_fs->mount(boot_device);
- auto root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode(), "/");
- root_fs->set_root_dentry(root_dentry);
-
- m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, root_fs));
+ do_mount("/", boot_root_fs);
// TODO BA-FS26 use do_mount when tempdevfs is implemented -> just call /dev/ with all devices in devtempfs
std::ranges::for_each(storage_mgmt.all_controllers(), [&](auto controller) {
@@ -102,10 +107,10 @@ namespace filesystem
{
// TODO BA-FS26 check if mount point is already mounted and handle it (unmount old fs, fail, etc.)
+ auto new_fs_root = kstd::make_shared<dentry>(mount_dentry, filesystem->root_inode());
+ auto new_mount = kstd::make_shared<mount>(mount_dentry, new_fs_root, filesystem);
+ m_mount_table.add_mount(new_mount);
mount_dentry->set_flag(dentry::dentry_flags::dcache_mounted);
- m_mount_table.add_mount(kstd::make_shared<mount>(mount_dentry, filesystem));
-
- filesystem->set_root_dentry(kstd::make_shared<dentry>(mount_dentry->get_parent(), filesystem->root_inode()));
return 0;
}
@@ -153,20 +158,30 @@ namespace filesystem
kapi::system::panic("[FILESYSTEM] no root mount found.");
}
- auto current_dentry = root_mount->get_dentry();
+ auto current_dentry = root_mount->root_dentry();
auto current_fs = root_mount->get_filesystem();
+ while (current_dentry->has_flag(dentry::dentry_flags::dcache_mounted))
+ {
+ auto mnt = m_mount_table.find_mount_by_dentry(current_dentry);
+ if (!mnt)
+ kapi::system::panic("[FILESYSTEM] dcache_mounted set but no covering mount found.");
+ current_dentry = mnt->root_dentry();
+ current_fs = mnt->get_filesystem();
+ }
+
auto path_parts =
std::views::split(path, '/') | std::views::filter([](auto const & part) { return !part.empty(); });
for (auto const & part : path_parts)
{
- auto next_dentry = current_dentry->find_child(std::string_view{part});
+ std::string_view part_view{part};
+ auto next_dentry = current_dentry->find_child(part_view);
if (!next_dentry)
{
- if (auto found_inode = current_fs->lookup(current_dentry->get_inode(), std::string_view{part}))
+ if (auto found_inode = current_fs->lookup(current_dentry->get_inode(), part_view))
{
- next_dentry = kstd::make_shared<dentry>(current_dentry, found_inode, std::string_view{part});
+ next_dentry = kstd::make_shared<dentry>(current_dentry, found_inode, part_view);
current_dentry->add_child(next_dentry);
}
else
@@ -179,7 +194,7 @@ namespace filesystem
{
auto found_mount = m_mount_table.find_mount_by_dentry(next_dentry);
current_fs = found_mount->get_filesystem();
- current_dentry = current_fs->root_dentry();
+ current_dentry = found_mount->root_dentry();
}
else
{
diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp
index 9571a0d..19a0992 100644
--- a/kernel/src/main.cpp
+++ b/kernel/src/main.cpp
@@ -5,6 +5,7 @@
#include "kernel/devices/storage/storage_management.hpp"
#include "kernel/filesystem/device_inode.hpp"
+#include "kernel/filesystem/ext2/ext2_filesystem.hpp"
#include "kernel/filesystem/file_descriptor_table.hpp"
#include "kernel/filesystem/open_file_description.hpp"
#include "kernel/filesystem/vfs.hpp"
@@ -108,8 +109,17 @@ auto test_file_lookup() -> void
// TODO BA-FS26 implement a more complete test with multiple files and directories and mounts etc.
auto vfs = filesystem::vfs::get();
+ auto storage_mgmt = devices::storage::storage_management::get();
+
vfs.open("/a/b/c");
vfs.open("/a/d/e");
+
+ auto new_filesystem = kstd::make_shared<filesystem::ext2::ext2_filesystem>();
+ auto device = storage_mgmt.device_by_major_minor(1, 16);
+ new_filesystem->mount(device);
+ vfs.do_mount("/a/b", new_filesystem);
+ vfs.open("/a/b/c");
+
vfs.open("x/y/z");
}