aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-06-02 10:54:17 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-06-02 16:30:20 +0200
commitd2d4fa3330a09f421b8658c077166cc493532b9e (patch)
tree985c1cc9564e98d3d640008d95680cd2b8894310
parentad2319188269331f4873adbeb44380d63e8e83c5 (diff)
downloadkernel-d2d4fa3330a09f421b8658c077166cc493532b9e.tar.xz
kernel-d2d4fa3330a09f421b8658c077166cc493532b9e.zip
kernel/vfs: extract fs type registry
-rw-r--r--arch/x86_64/scripts/kernel.ld7
-rw-r--r--kernel/CMakeLists.txt1
-rw-r--r--kernel/include/kernel/filesystem/type.hpp9
-rw-r--r--kernel/include/kernel/filesystem/type_registry.hpp47
-rw-r--r--kernel/include/kernel/filesystem/vfs.hpp5
-rw-r--r--kernel/src/filesystem/devfs/filesystem.cpp6
-rw-r--r--kernel/src/filesystem/ext2/filesystem.cpp6
-rw-r--r--kernel/src/filesystem/type_registry.cpp67
-rw-r--r--kernel/src/filesystem/vfs.cpp17
-rw-r--r--kernel/src/main.cpp2
10 files changed, 136 insertions, 31 deletions
diff --git a/arch/x86_64/scripts/kernel.ld b/arch/x86_64/scripts/kernel.ld
index a1d8a65..dbb0f8f 100644
--- a/arch/x86_64/scripts/kernel.ld
+++ b/arch/x86_64/scripts/kernel.ld
@@ -74,9 +74,10 @@ SECTIONS
*(.rodata*)
. = ALIGN(8);
- PROVIDE(__start_vfs_type_descriptors = .);
- KEEP(*(vfs_type_descriptors));
- PROVIDE(__stop_vfs_type_descriptors = .);
+
+ PROVIDE(__start_fs_types = .);
+ KEEP(*(fs_types));
+ PROVIDE(__stop_fs_types = .);
} :kernel_rodata
.kernel_data ALIGN(4K) : AT (ADDR (.kernel_data) - TEACHOS_VMA)
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index cbc7fa5..3dd84ba 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -53,6 +53,7 @@ target_sources("kernel_lib" PRIVATE
"src/filesystem/mount.cpp"
"src/filesystem/open_file_descriptor.cpp"
"src/filesystem/open_file_table.cpp"
+ "src/filesystem/type_registry.cpp"
"src/filesystem/vfs.cpp"
# DevFS Filesystem
diff --git a/kernel/include/kernel/filesystem/type.hpp b/kernel/include/kernel/filesystem/type.hpp
index 87e466b..0948e54 100644
--- a/kernel/include/kernel/filesystem/type.hpp
+++ b/kernel/include/kernel/filesystem/type.hpp
@@ -28,6 +28,15 @@ namespace kernel::filesystem
[[nodiscard]] virtual auto make_instance() const -> kstd::shared_ptr<filesystem> = 0;
};
+ template<typename Type>
+ struct type_registration
+ {
+ constexpr auto static instance = Type{};
+ [[using gnu: section("fs_types"), used, visibility("hidden")]] constexpr auto static pointer{
+ kstd::make_observer<type const>(&instance),
+ };
+ };
+
} // namespace kernel::filesystem
#endif
diff --git a/kernel/include/kernel/filesystem/type_registry.hpp b/kernel/include/kernel/filesystem/type_registry.hpp
new file mode 100644
index 0000000..2f5e708
--- /dev/null
+++ b/kernel/include/kernel/filesystem/type_registry.hpp
@@ -0,0 +1,47 @@
+#ifndef TEACH_OS_KERNEL_TYPE_REGISRY_HPP
+#define TEACH_OS_KERNEL_TYPE_REGISRY_HPP
+
+#include <kernel/filesystem/type.hpp>
+
+#include <kstd/flat_map>
+#include <kstd/memory>
+#include <kstd/string>
+
+#include <span>
+#include <string_view>
+
+namespace kernel::filesystem
+{
+
+ struct type_registry
+ {
+ using value_type = type;
+ using pointer = kstd::observer_ptr<value_type const>;
+
+ auto static init() -> void;
+ auto static get() -> type_registry &;
+
+ constexpr type_registry() noexcept = default;
+
+ //! Add a type descriptor to this registry.
+ //!
+ //! This function will register the given descriptor with this registry, given that no descriptor for a filesystem
+ //! with the same name exists in this registry already.
+ //!
+ //! @param descriptor The filesystem type descriptor to add to the registry.
+ //! @return @p true iff. the descriptor was successfully added, @p false if not.
+ auto add(pointer descriptor) -> bool;
+
+ //! Get all currently registered type descriptors.
+ //!
+ //! @return A span containing all currently registered filesystem type descriptors.
+ [[nodiscard]] auto all() const noexcept -> std::span<pointer>;
+
+ private:
+ //! A map from filesystem names (identifiers) to filesystem type descriptors.
+ kstd::flat_map<std::string_view, pointer> m_descriptors{};
+ };
+
+} // namespace kernel::filesystem
+
+#endif
diff --git a/kernel/include/kernel/filesystem/vfs.hpp b/kernel/include/kernel/filesystem/vfs.hpp
index c8aae5c..ddc9a9b 100644
--- a/kernel/include/kernel/filesystem/vfs.hpp
+++ b/kernel/include/kernel/filesystem/vfs.hpp
@@ -6,11 +6,8 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/mount.hpp>
#include <kernel/filesystem/mount_table.hpp>
-#include <kernel/filesystem/type.hpp>
-#include <kstd/flat_map>
#include <kstd/memory>
-#include <kstd/string>
#include <string_view>
#include <utility>
@@ -109,8 +106,6 @@ namespace kernel::filesystem
auto graft_persistent_device_fs(kstd::shared_ptr<devfs::filesystem> const & device_fs) -> void;
- //! A map from filesystem names (identifiers) to filesystem type descriptors.
- kstd::flat_map<kstd::string, kstd::observer_ptr<type const>> m_filesystems{};
mount_table m_mount_table{};
};
} // namespace kernel::filesystem
diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp
index 1aaa0d1..ce887ff 100644
--- a/kernel/src/filesystem/devfs/filesystem.cpp
+++ b/kernel/src/filesystem/devfs/filesystem.cpp
@@ -32,10 +32,10 @@ namespace kernel::filesystem::devfs
{
return kstd::make_shared<filesystem>();
}
- } const constinit type_instance{};
+ };
- [[gnu::section("vfs_type_descriptors"), gnu::used]]
- auto const * const type_descriptor_pointer = static_cast<kernel::filesystem::type const *>(&type_instance);
+ [[gnu::used]]
+ constexpr auto registration = type_registration<type>{};
auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> operation_result
{
diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp
index 7b5d2d7..3180a19 100644
--- a/kernel/src/filesystem/ext2/filesystem.cpp
+++ b/kernel/src/filesystem/ext2/filesystem.cpp
@@ -36,10 +36,10 @@ namespace kernel::filesystem::ext2
{
return kstd::make_shared<filesystem>();
}
- } const constinit type_instance{};
+ };
- [[gnu::section("vfs_type_descriptors"), gnu::used]]
- auto const * const type_descriptor_pointer = static_cast<kernel::filesystem::type const *>(&type_instance);
+ [[gnu::used]]
+ constexpr auto registration = type_registration<type>{};
auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result
{
diff --git a/kernel/src/filesystem/type_registry.cpp b/kernel/src/filesystem/type_registry.cpp
new file mode 100644
index 0000000..033b879
--- /dev/null
+++ b/kernel/src/filesystem/type_registry.cpp
@@ -0,0 +1,67 @@
+#include <kernel/filesystem/type_registry.hpp>
+
+#include <kapi/system.hpp>
+
+#include <kstd/memory>
+#include <kstd/print>
+
+#include <algorithm>
+#include <optional>
+#include <ranges>
+#include <span>
+
+namespace kernel::filesystem
+{
+
+ extern "C"
+ {
+ extern type_registry::pointer const __start_fs_types;
+ extern type_registry::pointer const __stop_fs_types;
+ }
+
+ namespace
+ {
+ auto constinit instance = std::optional<type_registry>{};
+ }
+
+ auto type_registry::init() -> void
+ {
+ if (instance)
+ {
+ kapi::system::panic("[FILESYSTEM] tried to initialize type registry more than once!");
+ }
+
+ instance.emplace();
+
+ auto type_descriptors = std::span{&__start_fs_types, &__stop_fs_types} | //
+ std::views::filter([](auto p) { return p != nullptr; });
+
+ std::ranges::for_each(type_descriptors, [](auto descriptor) {
+ kstd::println("[FILESYSTEM] registering '{}'", descriptor->name());
+ instance->add(descriptor);
+ });
+ }
+
+ auto type_registry::get() -> type_registry &
+ {
+ if (!instance)
+ {
+ kapi::system::panic("[FILESYSTEM] type registry has not been initialized!");
+ }
+
+ return *instance;
+ }
+
+ auto type_registry::add(pointer descriptor) -> bool
+ {
+ auto result = m_descriptors.emplace(descriptor->name(), descriptor);
+ return result.second;
+ }
+
+ [[nodiscard]] auto type_registry::all() const noexcept -> std::span<pointer>
+ {
+ // TODO: implement value accessor for flat_map
+ return {};
+ }
+
+} // namespace kernel::filesystem
diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp
index 8dcae2c..8d1fd23 100644
--- a/kernel/src/filesystem/vfs.cpp
+++ b/kernel/src/filesystem/vfs.cpp
@@ -8,29 +8,20 @@
#include <kernel/filesystem/mount_table.hpp>
#include <kernel/filesystem/path.hpp>
#include <kernel/filesystem/rootfs/filesystem.hpp>
-#include <kernel/filesystem/type.hpp>
#include <kapi/system.hpp>
#include <kstd/memory>
#include <kstd/print>
-#include <kstd/string>
#include <kstd/vector>
#include <algorithm>
#include <cstdint>
#include <optional>
#include <ranges>
-#include <span>
#include <string_view>
#include <utility>
-extern "C"
-{
- extern kernel::filesystem::type const * const __start_vfs_type_descriptors;
- extern kernel::filesystem::type const * const __stop_vfs_type_descriptors;
-}
-
namespace
{
constinit auto static active_vfs = std::optional<kernel::filesystem::vfs>{};
@@ -50,14 +41,6 @@ namespace kernel::filesystem
vfs::vfs()
{
- // Register all compiled-in filesystems
- auto type_descriptors = std::span{&__start_vfs_type_descriptors, &__stop_vfs_type_descriptors} |
- std::views::filter([](auto p) { return p != nullptr; });
- std::ranges::for_each(type_descriptors, [this](auto descriptor) {
- kstd::println("[FILESYSTEM] registering '{}'", descriptor->name());
- m_filesystems.emplace(descriptor->name(), descriptor);
- });
-
// mount rootfs at /
auto root_fs = kstd::make_shared<rootfs::filesystem>();
root_fs->mount(nullptr);
diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp
index 6985e94..5063d18 100644
--- a/kernel/src/main.cpp
+++ b/kernel/src/main.cpp
@@ -1,3 +1,4 @@
+#include "kernel/filesystem/type_registry.hpp"
#include <kernel/devices/storage/management.hpp>
#include <kernel/filesystem/open_file_table.hpp>
#include <kernel/filesystem/vfs.hpp>
@@ -138,6 +139,7 @@ auto main() -> int
kernel::filesystem::open_file_table::init();
kstd::println("[OS] Global open file table initialized.");
+ kernel::filesystem::type_registry::init();
kernel::filesystem::vfs::init();
kstd::println("[OS] Virtual filesystem initialized.");