aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-08-20 18:53:13 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-08-20 18:53:13 +0200
commitda18613bd4ad4784f8f6f70e998e3a91cacf31c3 (patch)
tree1ad59a649f910e08bbb8c80fdb456f6c3687e445
parent01c08dd3814825db2c6bedd4d4621831a588962c (diff)
downloadkernel-da18613bd4ad4784f8f6f70e998e3a91cacf31c3.tar.xz
kernel-da18613bd4ad4784f8f6f70e998e3a91cacf31c3.zip
kernel/fs: rework driver probing
-rw-r--r--kernel/kernel/filesystem/devfs/filesystem.cpp10
-rw-r--r--kernel/kernel/filesystem/ext2/error.cpp8
-rw-r--r--kernel/kernel/filesystem/ext2/error.hpp3
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.cpp30
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.hpp34
-rw-r--r--kernel/kernel/filesystem/filesystem.cpp9
-rw-r--r--kernel/kernel/filesystem/rootfs/filesystem.cpp11
-rw-r--r--kernel/kernel/filesystem/type.hpp12
8 files changed, 99 insertions, 18 deletions
diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp
index 5b11d6e8..92756a65 100644
--- a/kernel/kernel/filesystem/devfs/filesystem.cpp
+++ b/kernel/kernel/filesystem/devfs/filesystem.cpp
@@ -16,6 +16,7 @@
#include <kstd/system_error.hpp>
#include <algorithm>
+#include <cstdint>
#include <optional>
#include <string_view>
@@ -28,9 +29,14 @@ namespace kernel::filesystem::devfs
return "devfs";
}
- [[nodiscard]] auto requires_inode() const noexcept -> bool override
+ [[nodiscard]] auto probe(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) const noexcept
+ -> kstd::result<std::uint32_t> override
{
- return false;
+ if (backing_inode)
+ {
+ return kstd::failure(vfs_errc::invalid_argument);
+ }
+ return 0;
}
[[nodiscard]] auto make_instance() const -> kstd::shared_ptr<kernel::filesystem::filesystem> override
diff --git a/kernel/kernel/filesystem/ext2/error.cpp b/kernel/kernel/filesystem/ext2/error.cpp
index 1da4ef36..ffe49460 100644
--- a/kernel/kernel/filesystem/ext2/error.cpp
+++ b/kernel/kernel/filesystem/ext2/error.cpp
@@ -40,6 +40,8 @@ namespace kernel::filesystem::ext2
return "not enough free blocks";
case ext2_errc::not_enough_inodes:
return "not enough inodes";
+ case ext2_errc::unsupported_features_present:
+ return "unsupported features present";
default:
return "unknown ext2 error";
};
@@ -78,6 +80,12 @@ namespace kernel::filesystem::ext2
return condition.value() == static_cast<int>(kstd::errc::no_space_on_device);
}
break;
+ case ext2_errc::unsupported_features_present:
+ if (condition.category() == kstd::generic_category())
+ {
+ return condition.value() == static_cast<int>(kstd::errc::not_supported);
+ }
+ break;
}
return kstd::error_category::equivalent(code, condition);
}
diff --git a/kernel/kernel/filesystem/ext2/error.hpp b/kernel/kernel/filesystem/ext2/error.hpp
index dcdf7295..59df1669 100644
--- a/kernel/kernel/filesystem/ext2/error.hpp
+++ b/kernel/kernel/filesystem/ext2/error.hpp
@@ -20,7 +20,8 @@ namespace kernel::filesystem::ext2
failed_to_read_superblock,
failed_to_read_block_group_descriptors,
not_enough_free_blocks,
- not_enough_inodes
+ not_enough_inodes,
+ unsupported_features_present
};
[[nodiscard]] auto ext2_category() noexcept -> kstd::error_category const &;
diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp
index c1de1447..fcccad8f 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.cpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.cpp
@@ -28,6 +28,7 @@
#include <span>
#include <string_view>
#include <tuple>
+#include <utility>
using namespace kstd::units_literals;
@@ -48,6 +49,10 @@ namespace kernel::filesystem::ext2
auto const bit_index = index % 8;
bitmap.at(byte_index) |= static_cast<uint8_t>(1u << bit_index);
}
+
+ auto supported_incompatible_features = incompatible_features::file_types_in_directory_entries;
+ auto supported_ro_compatible_features = read_only_compatible_features::sparse_superblock_copies | //
+ read_only_compatible_features::large_file_support;
} // namespace
struct type final : kernel::filesystem::type
@@ -57,9 +62,30 @@ namespace kernel::filesystem::ext2
return "ext2";
}
- [[nodiscard]] auto requires_inode() const noexcept -> bool override
+ [[nodiscard]] auto probe(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) const noexcept
+ -> kstd::result<std::uint32_t> override
{
- return true;
+ auto superblock = ext2::superblock{};
+ auto bytes = std::as_writable_bytes(std::span{&superblock, 1});
+ auto read_result = backing_inode->read(bytes, constants::superblock_offset);
+
+ if (!read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
+
+ if (superblock.magic != constants::magic_number)
+ {
+ return kstd::failure(ext2_errc::invalid_magic_number);
+ }
+
+ if (superblock.feature_incompat & std::to_underlying(~supported_incompatible_features) ||
+ superblock.feature_ro_compat & std::to_underlying(~supported_ro_compatible_features))
+ {
+ return kstd::failure(ext2_errc::unsupported_features_present);
+ }
+
+ return 0;
}
[[nodiscard]] auto make_instance() const -> kstd::shared_ptr<kernel::filesystem::filesystem> override
diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp
index 7d5490b4..d70358fd 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.hpp
@@ -9,6 +9,7 @@
#include <kapi/filesystem.hpp>
+#include <kstd/bitfield_enum.hpp>
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
@@ -20,6 +21,7 @@
#include <cstdint>
#include <optional>
#include <string_view>
+#include <type_traits>
namespace kernel::filesystem::ext2
{
@@ -48,6 +50,28 @@ namespace kernel::filesystem::ext2
constexpr uint16_t inline mode_character_device = 0x2000;
} // namespace constants
+ //! Ext2 incompatibility features
+ //!
+ //! These enumerators describe the flags that might not be supported by an ext2 driver.
+ enum struct incompatible_features
+ {
+ compression = 0x0001,
+ file_types_in_directory_entries = 0x0002,
+ recovery = 0x0004,
+ external_journal_device = 0x0008,
+ meta_block_group_layout = 0x0010,
+ };
+
+ //! Ext2 read-only compatible features
+ //!
+ //! There enumerators describe the flags that might prevent read-write access for a driver.
+ enum struct read_only_compatible_features
+ {
+ sparse_superblock_copies = 0x0001,
+ large_file_support = 0x0002,
+ binary_tree_directories = 0x0003,
+ };
+
//! The Second Extended Filesystem (ext2)
struct filesystem final : kernel::filesystem::filesystem
{
@@ -170,4 +194,14 @@ namespace kernel::filesystem::ext2
};
} // namespace kernel::filesystem::ext2
+template<>
+struct kstd::is_bitfield_enum<kernel::filesystem::ext2::incompatible_features> : std::true_type
+{
+};
+
+template<>
+struct kstd::is_bitfield_enum<kernel::filesystem::ext2::read_only_compatible_features> : std::true_type
+{
+};
+
#endif
diff --git a/kernel/kernel/filesystem/filesystem.cpp b/kernel/kernel/filesystem/filesystem.cpp
index d1e0e2a0..84bbdef6 100644
--- a/kernel/kernel/filesystem/filesystem.cpp
+++ b/kernel/kernel/filesystem/filesystem.cpp
@@ -4,8 +4,6 @@
#include <kernel/filesystem/inode.hpp>
#include <kernel/filesystem/type_registry.hpp>
-#include <kapi/system.hpp>
-
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
@@ -18,7 +16,7 @@ namespace kernel::filesystem
{
for (auto & type : type_registry::get().all())
{
- if (!type || type->requires_inode() != static_cast<bool>(backing_inode))
+ if (!type || !type->probe(backing_inode))
{
continue;
}
@@ -36,11 +34,6 @@ namespace kernel::filesystem
auto filesystem::mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::result<void>
{
- if (!backing_inode)
- {
- kapi::system::panic("[FILESYSTEM] cannot mount filesystem: backing inode is null.");
- }
-
m_backing_inode = backing_inode;
return kstd::success();
}
diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp
index f44a57c8..cccfa63c 100644
--- a/kernel/kernel/filesystem/rootfs/filesystem.cpp
+++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp
@@ -12,6 +12,7 @@
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
+#include <cstdint>
#include <optional>
#include <string_view>
@@ -24,9 +25,15 @@ namespace kernel::filesystem::rootfs
return "rootfs";
}
- [[nodiscard]] auto requires_inode() const noexcept -> bool override
+ [[nodiscard]] auto probe(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) const noexcept
+ -> kstd::result<std::uint32_t> override
{
- return true;
+ if (backing_inode)
+ {
+ return kstd::failure(vfs_errc::invalid_argument);
+ }
+
+ return 0;
}
[[nodiscard]] auto make_instance() const -> kstd::shared_ptr<kernel::filesystem::filesystem> override
diff --git a/kernel/kernel/filesystem/type.hpp b/kernel/kernel/filesystem/type.hpp
index eae1a740..c2f2595b 100644
--- a/kernel/kernel/filesystem/type.hpp
+++ b/kernel/kernel/filesystem/type.hpp
@@ -2,9 +2,12 @@
#define TEACHOS_KERNEL_FILESYSTEM_TYPE_HPP
#include <kernel/filesystem/filesystem.hpp>
+#include <kernel/filesystem/inode.hpp>
#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <cstdint>
#include <string_view>
namespace kernel::filesystem
@@ -21,10 +24,13 @@ namespace kernel::filesystem
//! Get the name of the filesystem represented by this descriptor.
[[nodiscard]] virtual auto name() const noexcept -> std::string_view = 0;
- //! Check if filesystems of this type require a device to back them.
- [[nodiscard]] virtual auto requires_inode() const noexcept -> bool = 0;
+ //! Check if the filesystem is applicable.
+ //!
+ //! @return the priority of this filesystem for the given inode.
+ [[nodiscard]] virtual auto probe(kstd::shared_ptr<inode> const & backing_inode) const noexcept
+ -> kstd::result<std::uint32_t> = 0;
- //! Create a new instance of the filesytem represented by this descriptor.
+ //! Create a new instance of the filesystem represented by this descriptor.
[[nodiscard]] virtual auto make_instance() const -> kstd::shared_ptr<filesystem> = 0;
};