diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-06-02 10:54:17 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-06-02 16:30:20 +0200 |
| commit | d2d4fa3330a09f421b8658c077166cc493532b9e (patch) | |
| tree | 985c1cc9564e98d3d640008d95680cd2b8894310 | |
| parent | ad2319188269331f4873adbeb44380d63e8e83c5 (diff) | |
| download | kernel-d2d4fa3330a09f421b8658c077166cc493532b9e.tar.xz kernel-d2d4fa3330a09f421b8658c077166cc493532b9e.zip | |
kernel/vfs: extract fs type registry
| -rw-r--r-- | arch/x86_64/scripts/kernel.ld | 7 | ||||
| -rw-r--r-- | kernel/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/type.hpp | 9 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/type_registry.hpp | 47 | ||||
| -rw-r--r-- | kernel/include/kernel/filesystem/vfs.hpp | 5 | ||||
| -rw-r--r-- | kernel/src/filesystem/devfs/filesystem.cpp | 6 | ||||
| -rw-r--r-- | kernel/src/filesystem/ext2/filesystem.cpp | 6 | ||||
| -rw-r--r-- | kernel/src/filesystem/type_registry.cpp | 67 | ||||
| -rw-r--r-- | kernel/src/filesystem/vfs.cpp | 17 | ||||
| -rw-r--r-- | kernel/src/main.cpp | 2 |
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."); |
