diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kernel/filesystems/fat32/filesystem.cpp | 63 | ||||
| -rw-r--r-- | kernel/kernel/filesystems/fat32/filesystem.tests.cpp | 44 |
2 files changed, 46 insertions, 61 deletions
diff --git a/kernel/kernel/filesystems/fat32/filesystem.cpp b/kernel/kernel/filesystems/fat32/filesystem.cpp index 63058e54..c423a2fc 100644 --- a/kernel/kernel/filesystems/fat32/filesystem.cpp +++ b/kernel/kernel/filesystems/fat32/filesystem.cpp @@ -14,13 +14,16 @@ #include <kstd/memory.hpp> #include <kstd/mutex.hpp> +#include <kstd/print.hpp> #include <kstd/result.hpp> #include <kstd/span.hpp> #include <kstd/system_error.hpp> #include <kstd/units.hpp> #include <algorithm> +#include <array> #include <bit> +#include <cstddef> #include <cstdint> #include <optional> #include <string_view> @@ -32,6 +35,48 @@ namespace kernel::filesystems::fat32 //! Hidden implementation details. namespace { + //! Convert a fixed size, space padded character array of the boot sector into a string view. + //! + //! @param array The array to convert. + //! @return A view of the array contents. + template<std::size_t Size> + [[nodiscard]] constexpr auto to_string_view(std::array<char, Size> const & array) -> std::string_view + { + return {array.data(), array.size()}; + } + + // TODO: Remove later, just for demo + auto print_boot_sector(boot_sector const & boot_sector) -> void + { + kstd::println("[OS:FAT32] jump_boot: {:#04X} {:#04X} {:#04X}", boot_sector.jump_boot[0], boot_sector.jump_boot[1], + boot_sector.jump_boot[2]); + kstd::println("[OS:FAT32] oem_name: '{}'", to_string_view(boot_sector.oem_name)); + kstd::println("[OS:FAT32] bytes_per_sector: {}", boot_sector.bytes_per_sector); + kstd::println("[OS:FAT32] sectors_per_cluster: {}", boot_sector.sectors_per_cluster); + kstd::println("[OS:FAT32] reserved_sector_count: {}", boot_sector.reserved_sector_count); + kstd::println("[OS:FAT32] number_of_fats: {}", boot_sector.number_of_fats); + kstd::println("[OS:FAT32] root_entry_count: {}", boot_sector.root_entry_count); + kstd::println("[OS:FAT32] total_sectors_16: {}", boot_sector.total_sectors_16); + kstd::println("[OS:FAT32] media: {:#04X}", boot_sector.media); + kstd::println("[OS:FAT32] fat_size_16: {}", boot_sector.fat_size_16); + kstd::println("[OS:FAT32] sectors_per_track: {}", boot_sector.sectors_per_track); + kstd::println("[OS:FAT32] number_of_heads: {}", boot_sector.number_of_heads); + kstd::println("[OS:FAT32] hidden_sectors: {}", boot_sector.hidden_sectors); + kstd::println("[OS:FAT32] total_sectors_32: {}", boot_sector.total_sectors_32); + kstd::println("[OS:FAT32] fat_size_32: {}", boot_sector.fat_size_32); + kstd::println("[OS:FAT32] extended_flags: {:#06X}", boot_sector.extended_flags); + kstd::println("[OS:FAT32] filesystem_version: {:#06X}", boot_sector.filesystem_version); + kstd::println("[OS:FAT32] root_cluster: {}", boot_sector.root_cluster); + kstd::println("[OS:FAT32] filesystem_info_sector: {}", boot_sector.filesystem_info_sector); + kstd::println("[OS:FAT32] backup_boot_sector: {}", boot_sector.backup_boot_sector); + kstd::println("[OS:FAT32] drive_number: {:#04X}", boot_sector.drive_number); + kstd::println("[OS:FAT32] extended_boot_signature: {:#04X}", boot_sector.extended_boot_signature); + kstd::println("[OS:FAT32] volume_id: {:#010X}", boot_sector.volume_id); + kstd::println("[OS:FAT32] volume_label: '{}'", to_string_view(boot_sector.volume_label)); + kstd::println("[OS:FAT32] filesystem_type: '{}'", to_string_view(boot_sector.filesystem_type)); + kstd::println("[OS:FAT32] boot_signature: {:#06X}", boot_sector.boot_signature); + } + //! Compare two names, ignoring the case of ASCII letters. //! //! Short names are stored in upper case, but are matched case-insensitively, e.g. "hello.txt" finds "HELLO.TXT". @@ -109,29 +154,13 @@ namespace kernel::filesystems::fat32 auto filesystem::probe(inode_ptr const & inode) const -> kstd::result<std::uint32_t> { - if (!inode) - { - return kstd::failure(vfs::errc::invalid_inode); - } - auto const boot_sector = read_boot_sector(inode); if (!boot_sector) { return kstd::failure(boot_sector.error()); } - // The boot signature alone is shared with every MBR, so the layout must describe a valid fat32 volume as well. - auto state = driver_state{}; - state.boot_sector = *boot_sector; - if (auto layout_result = compute_layout(state); !layout_result) - { - return kstd::failure(layout_result.error()); - } - - if (!is_valid_cluster(state.boot_sector.root_cluster, state)) - { - return kstd::failure(errc::invalid_cluster); - } + print_boot_sector(*boot_sector); return 0; } diff --git a/kernel/kernel/filesystems/fat32/filesystem.tests.cpp b/kernel/kernel/filesystems/fat32/filesystem.tests.cpp index 12958e75..6e83ffe7 100644 --- a/kernel/kernel/filesystems/fat32/filesystem.tests.cpp +++ b/kernel/kernel/filesystems/fat32/filesystem.tests.cpp @@ -183,50 +183,6 @@ SCENARIO("Fat32 filesystem rejects invalid boot signature", "[filesystem][fat32] } } -SCENARIO("Fat32 filesystem probe validates the layout", "[filesystem][fat32][filesystem]") -{ - auto const block_size = 512_B; - - GIVEN("no backing inode") - { - auto fs = kstd::make_shared<kernel::filesystems::fat32::filesystem>(); - - THEN("probe fails with invalid_inode") - { - REQUIRE(fs->probe(nullptr).error() == kernel::vfs::errc::invalid_inode); - } - } - - GIVEN("a block device") - { - auto device = kstd::make_shared<kernel::tests::devices::block_device>("mock", block_size, 18 * block_size); - auto dev_inode = kstd::make_shared<kernel::vfs::device_inode>(device); - auto fs = kstd::make_shared<kernel::filesystems::fat32::filesystem>(); - auto boot_sector = kernel::tests::filesystems::fat32::mock_boot_sector(); - - THEN("a minimal fat32 layout is accepted") - { - kernel::tests::filesystems::fat32::setup_mock_fat32_layout(*device, boot_sector); - REQUIRE(fs->probe(dev_inode) == 0u); - } - - THEN("a boot sector carrying only the boot signature, like a master boot record, is rejected") - { - auto signature_only = kernel::filesystems::fat32::boot_sector{}; - signature_only.boot_signature = kernel::filesystems::fat32::constants::boot_signature; - kernel::tests::filesystems::fat32::setup_mock_fat32_layout(*device, signature_only); - REQUIRE(fs->probe(dev_inode).error() == kernel::filesystems::fat32::errc::invalid_boot_sector); - } - - THEN("a root cluster outside the data region is rejected") - { - boot_sector.root_cluster = 18; - kernel::tests::filesystems::fat32::setup_mock_fat32_layout(*device, boot_sector); - REQUIRE(fs->probe(dev_inode).error() == kernel::filesystems::fat32::errc::invalid_cluster); - } - } -} - SCENARIO("Fat32 filesystem lookup on a mock layout", "[filesystem][fat32][filesystem][lookup]") { auto const block_size = 512_B; |
