diff options
| author | Marcel Braun <marcel.braun@ost.ch> | 2026-04-16 22:04:32 +0200 |
|---|---|---|
| committer | Marcel Braun <marcel.braun@ost.ch> | 2026-04-16 22:04:32 +0200 |
| commit | f642efb5cf199d3bbb8e3b01c451c71a1fbeabf8 (patch) | |
| tree | 7e680dd885a59678d7075d352ee623f659d64d48 /kernel/src | |
| parent | 3c210c07c60fbe9378cfb720847e8c1d3c763ead (diff) | |
| parent | e70ea2357a80386b0a12138201b353d942910296 (diff) | |
| download | teachos-f642efb5cf199d3bbb8e3b01c451c71a1fbeabf8.tar.xz teachos-f642efb5cf199d3bbb8e3b01c451c71a1fbeabf8.zip | |
Merge branch 'syscall-interface' into 'develop-BA-FS26'
Add fs syscall handler
See merge request teachos/kernel!23
Diffstat (limited to 'kernel/src')
| -rw-r--r-- | kernel/src/filesystem/devfs/filesystem.cpp | 2 | ||||
| -rw-r--r-- | kernel/src/filesystem/ext2/filesystem.cpp | 21 | ||||
| -rw-r--r-- | kernel/src/filesystem/ext2/filesystem.tests.cpp | 13 | ||||
| -rw-r--r-- | kernel/src/filesystem/ext2/inode.cpp | 7 | ||||
| -rw-r--r-- | kernel/src/filesystem/ext2/inode.tests.cpp | 13 | ||||
| -rw-r--r-- | kernel/src/filesystem/file_descriptor_table.cpp | 8 | ||||
| -rw-r--r-- | kernel/src/filesystem/filesystem.cpp | 22 | ||||
| -rw-r--r-- | kernel/src/filesystem/rootfs/filesystem.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/filesystem/vfs.cpp | 39 | ||||
| -rw-r--r-- | kernel/src/filesystem/vfs.tests.cpp | 99 | ||||
| -rw-r--r-- | kernel/src/main.cpp | 14 | ||||
| -rw-r--r-- | kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img | 2 |
12 files changed, 152 insertions, 92 deletions
diff --git a/kernel/src/filesystem/devfs/filesystem.cpp b/kernel/src/filesystem/devfs/filesystem.cpp index 03b4218..dd60c5d 100644 --- a/kernel/src/filesystem/devfs/filesystem.cpp +++ b/kernel/src/filesystem/devfs/filesystem.cpp @@ -14,7 +14,7 @@ namespace kernel::filesystem::devfs { - auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const &) -> operation_result + auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> operation_result { m_root_inode = kstd::make_shared<inode>(); build_device_inode_table(); diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp index 0ad5c97..c0f97ed 100644 --- a/kernel/src/filesystem/ext2/filesystem.cpp +++ b/kernel/src/filesystem/ext2/filesystem.cpp @@ -1,8 +1,5 @@ #include "kernel/filesystem/ext2/filesystem.hpp" -#include "kapi/devices/device.hpp" - -#include "kernel/devices/block_device_utils.hpp" #include "kernel/filesystem/ext2/block_group_descriptor.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/ext2/linked_directory_entry.hpp" @@ -32,12 +29,11 @@ namespace kernel::filesystem::ext2 } } // namespace - auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result + auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result { - kernel::filesystem::filesystem::mount(device); + kernel::filesystem::filesystem::mount(backing_inode); - kernel::devices::block_device_utils::read(m_device, &m_superblock, constants::superblock_offset, - sizeof(m_superblock)); + m_backing_inode->read(&m_superblock, constants::superblock_offset, sizeof(m_superblock)); if (m_superblock.magic != constants::magic_number) { @@ -51,9 +47,8 @@ namespace kernel::filesystem::ext2 m_block_group_descriptors = kstd::vector<block_group_descriptor>(num_block_groups); auto const block_group_descriptor_table_offset = block_size == 1024 ? 2 * block_size : block_size; - kernel::devices::block_device_utils::read(m_device, m_block_group_descriptors.data(), - block_group_descriptor_table_offset, - num_block_groups * sizeof(block_group_descriptor)); + m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset, + num_block_groups * sizeof(block_group_descriptor)); m_root_inode = read_inode(constants::root_inode_number); @@ -86,7 +81,7 @@ namespace kernel::filesystem::ext2 { auto const global_block_number = map_inode_block_index_to_global_block_number(i, inode_data); auto const block_offset = global_block_number * block_size; - kernel::devices::block_device_utils::read(m_device, buffer.data(), block_offset, block_size); + m_backing_inode->read(buffer.data(), block_offset, block_size); auto const * entry = reinterpret_cast<linked_directory_entry const *>(buffer.data()); auto bytes_read = 0uz; @@ -125,7 +120,7 @@ namespace kernel::filesystem::ext2 auto const inode_offset = inode_table_offset + inode_index_within_group * get_inode_size(); auto new_inode = kstd::make_shared<inode>(this); - kernel::devices::block_device_utils::read(m_device, &new_inode->m_data, inode_offset, sizeof(inode_data)); + m_backing_inode->read(&new_inode->m_data, inode_offset, sizeof(inode_data)); // TODO BA-FS26 improve inode_kind really needed? or just map it to the mode bits? if (S_ISREG(new_inode->m_data.mode)) @@ -209,7 +204,7 @@ namespace kernel::filesystem::ext2 auto const block_start_offset = block_number * get_block_size(); auto const number_start_address = block_start_offset + index * sizeof(uint32_t); - kernel::devices::block_device_utils::read(m_device, &block_number_buffer, number_start_address, sizeof(uint32_t)); + m_backing_inode->read(&block_number_buffer, number_start_address, sizeof(uint32_t)); return block_number_buffer; } diff --git a/kernel/src/filesystem/ext2/filesystem.tests.cpp b/kernel/src/filesystem/ext2/filesystem.tests.cpp index b13ebf3..a7b8d5b 100644 --- a/kernel/src/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/src/filesystem/ext2/filesystem.tests.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/devices/storage/management.hpp" +#include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/test_support/devices/block_device.hpp" @@ -29,8 +30,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, auto boot_device = kernel::devices::storage::management::get().determine_boot_device(); REQUIRE(boot_device != nullptr); + auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(boot_device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); THEN("the root inode is available and is a directory") { @@ -72,11 +75,13 @@ SCENARIO("Ext2 filesystem rejects invalid magic", "[filesystem][ext2][filesystem auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "mock", block_size, 2 * block_size); REQUIRE(device != nullptr); + auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device); + auto fs = kernel::filesystem::ext2::filesystem{}; THEN("mount fails with invalid_magic_number") { - REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::invalid_magic_number); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::invalid_magic_number); } } } @@ -92,8 +97,10 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto inode_data = kernel::filesystem::ext2::inode_data{}; inode_data.block[0] = 7; diff --git a/kernel/src/filesystem/ext2/inode.cpp b/kernel/src/filesystem/ext2/inode.cpp index a29bb3b..bf3f0cf 100644 --- a/kernel/src/filesystem/ext2/inode.cpp +++ b/kernel/src/filesystem/ext2/inode.cpp @@ -2,7 +2,6 @@ #include "kapi/system.hpp" -#include "kernel/devices/block_device_utils.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/inode.hpp" @@ -41,8 +40,8 @@ namespace kernel::filesystem::ext2 auto const read_offset = block_start_offset + in_block_offset; auto const bytes_to_read = std::min(size - bytes_read, m_filesystem->get_block_size() - in_block_offset); - bytes_read += kernel::devices::block_device_utils::read( - m_filesystem->device(), static_cast<uint8_t *>(buffer) + bytes_read, read_offset, bytes_to_read); + bytes_read += + m_filesystem->backing_inode()->read(static_cast<uint8_t *>(buffer) + bytes_read, read_offset, bytes_to_read); block_index++; in_block_offset = 0; // After the first block, we always start at the beginning of the block @@ -56,4 +55,4 @@ namespace kernel::filesystem::ext2 kapi::system::panic("[EXT2] inode::write is not implemented yet"); return 0; } -} // namespace kernel::filesystem::ext2
\ No newline at end of file +} // namespace kernel::filesystem::ext2 diff --git a/kernel/src/filesystem/ext2/inode.tests.cpp b/kernel/src/filesystem/ext2/inode.tests.cpp index 795ff10..ae66aff 100644 --- a/kernel/src/filesystem/ext2/inode.tests.cpp +++ b/kernel/src/filesystem/ext2/inode.tests.cpp @@ -1,6 +1,7 @@ #include "kernel/filesystem/ext2/inode.hpp" #include "kernel/devices/storage/management.hpp" +#include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" #include "kernel/test_support/cpu.hpp" @@ -54,8 +55,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in auto boot_device = kernel::devices::storage::management::get().determine_boot_device(); REQUIRE(boot_device != nullptr); + auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(boot_device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto information = fs.lookup(fs.root_inode(), "information"); REQUIRE(information != nullptr); @@ -94,8 +97,10 @@ SCENARIO("Ext2 inode read stops when block mapping resolves to zero", "[filesyst REQUIRE(device != nullptr); kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto inode = kernel::filesystem::ext2::inode{&fs}; inode.m_data.blocks = 2; @@ -120,8 +125,10 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") REQUIRE(device != nullptr); kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device); + auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device); + auto fs = kernel::filesystem::ext2::filesystem{}; - REQUIRE(fs.mount(device) == kernel::filesystem::filesystem::operation_result::success); + REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success); auto inode = kernel::filesystem::ext2::inode{&fs}; inode.m_data.blocks = 2; diff --git a/kernel/src/filesystem/file_descriptor_table.cpp b/kernel/src/filesystem/file_descriptor_table.cpp index 1c062a1..7569cea 100644 --- a/kernel/src/filesystem/file_descriptor_table.cpp +++ b/kernel/src/filesystem/file_descriptor_table.cpp @@ -41,7 +41,6 @@ namespace kernel::filesystem { if (!file_description) { - // TODO BA-FS26 panic or errorcode? return -1; } @@ -72,20 +71,21 @@ namespace kernel::filesystem return m_open_files.at(index); } - auto file_descriptor_table::remove_file(int fd) -> void + auto file_descriptor_table::remove_file(int fd) -> int { if (fd < 0) { - return; + return -1; } auto const index = static_cast<size_t>(fd); if (index >= m_open_files.size()) { - return; + return -1; } m_open_files.at(index) = nullptr; + return 0; } } // namespace kernel::filesystem diff --git a/kernel/src/filesystem/filesystem.cpp b/kernel/src/filesystem/filesystem.cpp index d8b04eb..99e7456 100644 --- a/kernel/src/filesystem/filesystem.cpp +++ b/kernel/src/filesystem/filesystem.cpp @@ -1,6 +1,5 @@ #include "kernel/filesystem/filesystem.hpp" -#include "kapi/devices/device.hpp" #include "kapi/system.hpp" #include "kernel/filesystem/ext2/filesystem.hpp" @@ -19,18 +18,17 @@ namespace kernel::filesystem }; } // namespace - auto filesystem::probe_and_mount(kstd::shared_ptr<kapi::devices::device> const & device) - -> kstd::shared_ptr<filesystem> + auto filesystem::probe_and_mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::shared_ptr<filesystem> { - if (!device) + if (!backing_inode) { - kapi::system::panic("[FILESYSTEM] cannot mount filesystem: device is null."); + kapi::system::panic("[FILESYSTEM] cannot mount filesystem: backing inode is null."); } for (auto & factory : filesystem_factories) { auto fs = factory(); - if (fs->mount(device) == operation_result::success) + if (fs->mount(backing_inode) == operation_result::success) { return fs; } @@ -39,14 +37,14 @@ namespace kernel::filesystem return nullptr; } - auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const & device) -> operation_result + auto filesystem::mount(kstd::shared_ptr<inode> const & backing_inode) -> operation_result { - if (!device) + if (!backing_inode) { - kapi::system::panic("[FILESYSTEM] cannot mount filesystem: device is null."); + kapi::system::panic("[FILESYSTEM] cannot mount filesystem: backing inode is null."); } - m_device = device; + m_backing_inode = backing_inode; return operation_result::success; } @@ -55,8 +53,8 @@ namespace kernel::filesystem return m_root_inode; } - auto filesystem::device() const -> kstd::shared_ptr<kapi::devices::device> const & + auto filesystem::backing_inode() const -> kstd::shared_ptr<inode> const & { - return m_device; + return m_backing_inode; } } // namespace kernel::filesystem
\ No newline at end of file diff --git a/kernel/src/filesystem/rootfs/filesystem.cpp b/kernel/src/filesystem/rootfs/filesystem.cpp index dffef99..f718c72 100644 --- a/kernel/src/filesystem/rootfs/filesystem.cpp +++ b/kernel/src/filesystem/rootfs/filesystem.cpp @@ -1,7 +1,5 @@ #include "kernel/filesystem/rootfs/filesystem.hpp" -#include "kapi/devices/device.hpp" - #include "kernel/filesystem/inode.hpp" #include "kernel/filesystem/rootfs/inode.hpp" @@ -11,7 +9,7 @@ namespace kernel::filesystem::rootfs { - auto filesystem::mount(kstd::shared_ptr<kapi::devices::device> const &) -> operation_result + auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> operation_result { auto rfs_inode = kstd::make_shared<inode>(); rfs_inode->add_child("dev"); diff --git a/kernel/src/filesystem/vfs.cpp b/kernel/src/filesystem/vfs.cpp index 67d1af2..394e926 100644 --- a/kernel/src/filesystem/vfs.cpp +++ b/kernel/src/filesystem/vfs.cpp @@ -2,7 +2,6 @@ #include "kapi/system.hpp" -#include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/dentry.hpp" #include "kernel/filesystem/devfs/filesystem.hpp" #include "kernel/filesystem/filesystem.hpp" @@ -43,19 +42,17 @@ namespace kernel::filesystem auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode()); m_mount_table.add_mount(kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, "", nullptr)); - auto storage_mgmt = devices::storage::management::get(); - if (auto boot_device = storage_mgmt.determine_boot_device()) + auto device_fs = kstd::make_shared<devfs::filesystem>(); + device_fs->mount(nullptr); + do_mount_internal("/dev", root_fs_root_dentry, device_fs); + + if (auto boot_device_dentry = resolve_path("/dev/ram0")) // TODO BA-FS26 better boot device detection { - auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device); - if (boot_root_fs) + if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode())) { do_mount_internal("/", root_fs_root_dentry, boot_root_fs); } } - - auto device_fs = kstd::make_shared<devfs::filesystem>(); - device_fs->mount(nullptr); - do_mount_internal("/dev", root_fs_root_dentry, device_fs); } auto vfs::get() -> vfs & @@ -78,24 +75,26 @@ namespace kernel::filesystem return nullptr; } - auto vfs::do_mount(std::string_view path, kstd::shared_ptr<filesystem> const & filesystem) -> operation_result + auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result { - if (!filesystem) - { - return operation_result::filesystem_null; - } - - if (path.empty() || path.front() != '/' || (path.size() > 1 && path.back() == '/')) + if (target.empty() || target.front() != '/' || (target.size() > 1 && target.back() == '/')) { return operation_result::invalid_path; } - if (auto mount_point_dentry = resolve_path(path)) + if (auto mount_point_dentry = resolve_path(target)) { - do_mount_internal(path, mount_point_dentry, filesystem); - return operation_result::success; + if (auto source_dentry = resolve_path(source)) + { + if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode())) + { + do_mount_internal(target, mount_point_dentry, fs); + return operation_result::success; + } + return operation_result::invalid_filesystem; + } + return operation_result::non_existent_path; } - return operation_result::mount_point_not_found; } diff --git a/kernel/src/filesystem/vfs.tests.cpp b/kernel/src/filesystem/vfs.tests.cpp index f363041..12dce84 100644 --- a/kernel/src/filesystem/vfs.tests.cpp +++ b/kernel/src/filesystem/vfs.tests.cpp @@ -1,12 +1,14 @@ #include "kernel/filesystem/vfs.hpp" -#include "kernel/devices/storage/management.hpp" -#include "kernel/filesystem/filesystem.hpp" #include "kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp" +#include <kstd/vector> + #include <catch2/catch_test_macros.hpp> +#include <cstddef> #include <filesystem> +#include <string_view> SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS with dummy modules", "[filesystem][vfs]") @@ -67,11 +69,6 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS {image_path_1, image_path_2, image_path_3})); auto & vfs = kernel::filesystem::vfs::get(); - auto storage_mgmt = kernel::devices::storage::management::get(); - auto device_1 = storage_mgmt.device_by_major_minor(1, 16); - auto fs_1 = kernel::filesystem::filesystem::probe_and_mount(device_1); - auto device_2 = storage_mgmt.device_by_major_minor(1, 32); - auto fs_2 = kernel::filesystem::filesystem::probe_and_mount(device_2); THEN("vfs initializes first module as root") { @@ -85,7 +82,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("second image can be mounted, data retrieved and unmounted again") { - REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1 != nullptr); @@ -100,8 +97,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("third image can be mounted in a mounted file system, unmount only if no child mount exists") { - REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/information/monkey_house/infrastructure", fs_2) == + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram32", "/information/monkey_house/infrastructure") == kernel::filesystem::vfs::operation_result::success); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); @@ -118,8 +115,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("images can be stacked mounted and correct file system is unmounted again") { - REQUIRE(vfs.do_mount("/information", fs_1) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.do_mount("/information", fs_2) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/dev/ram32", "/information") == kernel::filesystem::vfs::operation_result::success); auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets != nullptr); @@ -134,19 +131,26 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("mount with null file system fails") { - REQUIRE(vfs.do_mount("/information", nullptr) == kernel::filesystem::vfs::operation_result::filesystem_null); + REQUIRE(vfs.do_mount("/closed.txt", "/information") == + kernel::filesystem::vfs::operation_result::invalid_filesystem); } THEN("mount with invalid path fails") { - REQUIRE(vfs.do_mount("", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.do_mount("information", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); - REQUIRE(vfs.do_mount("/information/", fs_1) == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("/dev/ram16", "") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("/dev/ram16", "information") == kernel::filesystem::vfs::operation_result::invalid_path); + REQUIRE(vfs.do_mount("/dev/ram16", "/information/") == kernel::filesystem::vfs::operation_result::invalid_path); + } + + THEN("mount with non-existent source path fails") + { + REQUIRE(vfs.do_mount("/dev/nonexistent", "/information") == + kernel::filesystem::vfs::operation_result::non_existent_path); } THEN("mount with non-existent mount point fails") { - REQUIRE(vfs.do_mount("/information/nonexistent", fs_1) == + REQUIRE(vfs.do_mount("/dev/ram16", "/information/nonexistent") == kernel::filesystem::vfs::operation_result::mount_point_not_found); } @@ -163,4 +167,65 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS kernel::filesystem::vfs::operation_result::mount_point_not_found); } } + + GIVEN("A real image file containing as filesystem formatted files") + { + REQUIRE(std::filesystem::exists(image_path_1)); + REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1"}, {image_path_1})); + + THEN("the file-filesystem in the image can be mounted, files can be read and unmounted again") + { + auto & vfs = kernel::filesystem::vfs::get(); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information") == kernel::filesystem::vfs::operation_result::success); + + auto sheep_1 = vfs.open("/information/sheep_1.txt"); + REQUIRE(sheep_1 != nullptr); + + kstd::vector<std::byte> buffer(7); + auto bytes_read = sheep_1->read(buffer.data(), buffer.size()); + std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), bytes_read}; + REQUIRE(buffer_as_str == "sheep_1"); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); + REQUIRE(unmounted_sheep_1 == nullptr); + } + + THEN("the file-filesystem in the image can be mounted and in this filesystem can another file-filesystem be " + "mounted, files can be read and unmounted again") + { + auto & vfs = kernel::filesystem::vfs::get(); + REQUIRE(vfs.do_mount("/archiv/2024.img", "/information") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_mount("/archiv/2025.img", "/information/stable") == + kernel::filesystem::vfs::operation_result::success); + + auto sheep_1 = vfs.open("/information/sheep_1.txt"); + auto goat_1 = vfs.open("/information/stable/petting_zoo/goat_1.txt"); + REQUIRE(sheep_1 != nullptr); + REQUIRE(goat_1 != nullptr); + + kstd::vector<std::byte> sheep_buffer(7); + auto bytes_read = sheep_1->read(sheep_buffer.data(), sheep_buffer.size()); + std::string_view buffer_as_str{reinterpret_cast<char *>(sheep_buffer.data()), bytes_read}; + REQUIRE(buffer_as_str == "sheep_1"); + + kstd::vector<std::byte> goat_buffer(6); + bytes_read = goat_1->read(goat_buffer.data(), goat_buffer.size()); + buffer_as_str = std::string_view{reinterpret_cast<char *>(goat_buffer.data()), bytes_read}; + REQUIRE(buffer_as_str == "goat_1"); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); + + REQUIRE(vfs.unmount("/information/stable") == kernel::filesystem::vfs::operation_result::success); + auto unmounted_goat_1 = vfs.open("/information/stable/petting_zoo/goat_1.txt"); + REQUIRE(unmounted_goat_1 == nullptr); + + auto still_mounted_sheep_1 = vfs.open("/information/sheep_1.txt"); + REQUIRE(still_mounted_sheep_1 != nullptr); + + REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); + auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); + REQUIRE(unmounted_sheep_1 == nullptr); + } + } } diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 79ed703..e296bd5 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -9,7 +9,6 @@ #include "kernel/devices/storage/management.hpp" #include "kernel/filesystem/device_inode.hpp" #include "kernel/filesystem/file_descriptor_table.hpp" -#include "kernel/filesystem/filesystem.hpp" #include "kernel/filesystem/open_file_description.hpp" #include "kernel/filesystem/vfs.hpp" #include "kernel/memory.hpp" @@ -138,24 +137,17 @@ auto test_file_lookup() -> void "this_is_a_very_very_long_fish_filename_that_keeps_going_and_going_until_it_almost_breaks_linux_filesystem_" "limits_for_testing_purposes_and_we_add_more_characters_to_make_it_even_longer_30.txt"); - auto storage_mgmt = kernel::devices::storage::management::get(); - auto device_1 = storage_mgmt.device_by_major_minor(1, 16); - auto fs_1 = kernel::filesystem::filesystem::probe_and_mount(device_1); - - vfs.do_mount("/enclosures/aquarium", fs_1); + vfs.do_mount("/dev/ram16", "/enclosures/aquarium"); read_and_write_file("/enclosures/aquarium/closed.txt"); read_and_write_file("/enclosures/aquarium/information/info_2.txt"); vfs.unmount("/enclosures/aquarium"); read_and_write_file("/enclosures/aquarium/tank_1/fish_4.txt"); - auto device_2 = storage_mgmt.device_by_major_minor(1, 32); - auto fs_2 = kernel::filesystem::filesystem::probe_and_mount(device_2); - - vfs.do_mount("/enclosures/elephant_house", fs_2); + vfs.do_mount("/dev/ram32", "/enclosures/elephant_house"); read_and_write_file("/enclosures/elephant_house/monkey_house/infrastructure/info.txt"); - vfs.do_mount("/enclosures/elephant_house/monkey_house", fs_1); + vfs.do_mount("/dev/ram16", "/enclosures/elephant_house/monkey_house"); read_and_write_file("/enclosures/elephant_house/monkey_house/information/info_2.txt"); auto result = vfs.unmount("/enclosures/elephant_house"); diff --git a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img index 9f1ee4a..5bbb76d 100644 --- a/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img +++ b/kernel/src/test_support/filesystem/test_assets/ext2_1KB_fs.img @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94d3988bc309eb9e81f06042c72bf4c4fb5991cd7fdd597eb00c518a96c792d8 +oid sha256:c2ef9536a439825520d9e230eedaa9ae327f9763350eddbc0f24bf5b9b5d2bf2 size 10485760 |
