diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kernel/filesystem/devfs/filesystem.cpp | 10 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/error.cpp | 8 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/error.hpp | 3 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/filesystem.cpp | 30 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/ext2/filesystem.hpp | 34 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/filesystem.cpp | 9 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/rootfs/filesystem.cpp | 11 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/type.hpp | 12 |
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; }; |
