aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-07-14 19:30:03 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-07-14 19:30:03 +0200
commitd6735726d9cc6e98142e94001250076592279d36 (patch)
tree95d308a027495790af57479cacb064badea334d0 /kernel
parentcdb8a0928ddfe626a1ac0acd1ae63bc8e5b77355 (diff)
parent9558074af8ceef4dc2c3b168a0263775f8a377e0 (diff)
downloadkernel-d6735726d9cc6e98142e94001250076592279d36.tar.xz
kernel-d6735726d9cc6e98142e94001250076592279d36.zip
Merge branch 'fmorgner/develop/kstd-system-error' into 'develop'
kstd: implement system_error infrastructure See merge request teachos/kernel!54
Diffstat (limited to 'kernel')
-rw-r--r--kernel/CMakeLists.txt64
-rw-r--r--kernel/kapi/acpi.cpp2
-rw-r--r--kernel/kapi/cpu.cpp2
-rw-r--r--kernel/kapi/devices.cpp6
-rw-r--r--kernel/kapi/devices/bus.cpp8
-rw-r--r--kernel/kapi/devices/device.cpp4
-rw-r--r--kernel/kapi/filesystem.cpp68
-rw-r--r--kernel/kapi/filesystem.tests.cpp104
-rw-r--r--kernel/kapi/interrupts.cpp6
-rw-r--r--kernel/kapi/memory.cpp4
-rw-r--r--kernel/kapi/system.cpp11
-rw-r--r--kernel/kapi/system.tests.cpp2
-rw-r--r--kernel/kernel/acpi/manager.cpp4
-rw-r--r--kernel/kernel/acpi/manager.hpp6
-rw-r--r--kernel/kernel/devices/block_device.cpp2
-rw-r--r--kernel/kernel/devices/block_device.hpp2
-rw-r--r--kernel/kernel/devices/block_device.tests.cpp8
-rw-r--r--kernel/kernel/devices/block_device_utils.cpp6
-rw-r--r--kernel/kernel/devices/block_device_utils.hpp2
-rw-r--r--kernel/kernel/devices/block_device_utils.tests.cpp6
-rw-r--r--kernel/kernel/devices/storage/controller.cpp4
-rw-r--r--kernel/kernel/devices/storage/controller.hpp4
-rw-r--r--kernel/kernel/devices/storage/management.cpp4
-rw-r--r--kernel/kernel/devices/storage/management.hpp4
-rw-r--r--kernel/kernel/devices/storage/ram_disk/controller.cpp2
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.cpp4
-rw-r--r--kernel/kernel/filesystem/dentry.cpp4
-rw-r--r--kernel/kernel/filesystem/dentry.hpp6
-rw-r--r--kernel/kernel/filesystem/dentry.tests.cpp4
-rw-r--r--kernel/kernel/filesystem/devfs/filesystem.cpp30
-rw-r--r--kernel/kernel/filesystem/devfs/filesystem.hpp10
-rw-r--r--kernel/kernel/filesystem/devfs/filesystem.tests.cpp36
-rw-r--r--kernel/kernel/filesystem/devfs/inode.cpp6
-rw-r--r--kernel/kernel/filesystem/devfs/inode.hpp6
-rw-r--r--kernel/kernel/filesystem/devfs/inode.tests.cpp6
-rw-r--r--kernel/kernel/filesystem/device_inode.cpp7
-rw-r--r--kernel/kernel/filesystem/device_inode.hpp9
-rw-r--r--kernel/kernel/filesystem/device_inode.tests.cpp6
-rw-r--r--kernel/kernel/filesystem/error.hpp135
-rw-r--r--kernel/kernel/filesystem/ext2/error.hpp109
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.cpp100
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.hpp21
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.tests.cpp37
-rw-r--r--kernel/kernel/filesystem/ext2/inode.cpp22
-rw-r--r--kernel/kernel/filesystem/ext2/inode.hpp7
-rw-r--r--kernel/kernel/filesystem/ext2/inode.tests.cpp44
-rw-r--r--kernel/kernel/filesystem/filesystem.cpp16
-rw-r--r--kernel/kernel/filesystem/filesystem.hpp28
-rw-r--r--kernel/kernel/filesystem/inode.hpp6
-rw-r--r--kernel/kernel/filesystem/mount.cpp4
-rw-r--r--kernel/kernel/filesystem/mount.hpp4
-rw-r--r--kernel/kernel/filesystem/mount.tests.cpp6
-rw-r--r--kernel/kernel/filesystem/mount_table.cpp4
-rw-r--r--kernel/kernel/filesystem/mount_table.hpp4
-rw-r--r--kernel/kernel/filesystem/mount_table.tests.cpp6
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.cpp33
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.hpp7
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.tests.cpp14
-rw-r--r--kernel/kernel/filesystem/open_file_table.cpp27
-rw-r--r--kernel/kernel/filesystem/open_file_table.hpp13
-rw-r--r--kernel/kernel/filesystem/open_file_table.tests.cpp27
-rw-r--r--kernel/kernel/filesystem/path.hpp2
-rw-r--r--kernel/kernel/filesystem/rootfs/filesystem.cpp13
-rw-r--r--kernel/kernel/filesystem/rootfs/filesystem.hpp12
-rw-r--r--kernel/kernel/filesystem/rootfs/filesystem.tests.cpp20
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.cpp6
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.hpp11
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.tests.cpp6
-rw-r--r--kernel/kernel/filesystem/type.hpp2
-rw-r--r--kernel/kernel/filesystem/type_registry.cpp4
-rw-r--r--kernel/kernel/filesystem/type_registry.hpp6
-rw-r--r--kernel/kernel/filesystem/type_registry.tests.cpp2
-rw-r--r--kernel/kernel/filesystem/vfs.cpp141
-rw-r--r--kernel/kernel/filesystem/vfs.hpp50
-rw-r--r--kernel/kernel/filesystem/vfs.tests.cpp203
-rw-r--r--kernel/kernel/main.cpp37
-rw-r--r--kernel/kernel/memory.cpp4
-rw-r--r--kernel/kernel/memory/block_list_allocator.cpp4
-rw-r--r--kernel/kernel/memory/block_list_allocator.hpp4
-rw-r--r--kernel/kernel/memory/block_list_allocator.tests.cpp2
-rw-r--r--kernel/kernel/memory/heap_allocator.hpp2
-rw-r--r--kernel/kernel/memory/mmio_allocator.cpp2
-rw-r--r--kernel/kernel/memory/mmio_allocator.hpp4
-rw-r--r--kernel/kernel/memory/operators.cpp2
-rw-r--r--kernel/kernel/test_support/devices/block_device.cpp4
-rw-r--r--kernel/kernel/test_support/devices/block_device.hpp4
-rw-r--r--kernel/kernel/test_support/devices/character_device.cpp2
-rw-r--r--kernel/kernel/test_support/devices/character_device.hpp4
-rw-r--r--kernel/kernel/test_support/filesystem/filesystem.cpp6
-rw-r--r--kernel/kernel/test_support/filesystem/filesystem.hpp6
-rw-r--r--kernel/kernel/test_support/filesystem/inode.cpp6
-rw-r--r--kernel/kernel/test_support/filesystem/inode.hpp6
-rw-r--r--kernel/kernel/test_support/kapi/memory.cpp2
-rw-r--r--kernel/kernel/test_support/page_mapper.cpp2
-rw-r--r--kernel/kernel/test_support/page_mapper.hpp2
-rw-r--r--kernel/kernel/test_support/simulated_memory.cpp2
-rw-r--r--kernel/kernel/test_support/simulated_memory.hpp2
-rw-r--r--kernel/kstd/print.cpp4
-rw-r--r--kernel/kstd/print.tests.cpp2
99 files changed, 1022 insertions, 714 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index d50944e4..34d71de1 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -140,79 +140,32 @@ endif()
if(BUILD_TESTING)
find_package("Catch2")
include("Catch")
+ include("BuildHostTests")
- enable_coverage("kernel_lib")
-
- add_executable("kernel_tests")
- add_executable("kernel::tests" ALIAS "kernel_tests")
+ teachos_add_tests("kernel")
target_sources("kernel_tests" PRIVATE
- # Platform-defined KAPI
"kernel/test_support/kapi/cpu.cpp"
"kernel/test_support/kapi/cio.cpp"
"kernel/test_support/kapi/interrupts.cpp"
"kernel/test_support/kapi/memory.cpp"
- # Device Subsystem Support
"kernel/test_support/devices/block_device.cpp"
"kernel/test_support/devices/character_device.cpp"
- # Filesystem Subsystem Support
"kernel/test_support/filesystem/inode.cpp"
"kernel/test_support/filesystem/filesystem.cpp"
"kernel/test_support/filesystem/ext2.cpp"
"kernel/test_support/filesystem/storage_boot_module_fixture.cpp"
"kernel/test_support/filesystem/storage_boot_module_vfs_fixture.cpp"
- # I/O Support
"kernel/test_support/log_buffer.cpp"
"kernel/test_support/output_device.cpp"
- # Memory Support
"kernel/test_support/page_mapper.cpp"
"kernel/test_support/simulated_memory.cpp"
- # Support System Listener
"kernel/test_support/state_reset_listener.cpp"
-
- # KAPI Shim Tests
- "kapi/cpu.tests.cpp"
- "kapi/system.tests.cpp"
- "kapi/filesystem.tests.cpp"
-
- # KSTD Shim Tests
- "kstd/print.tests.cpp"
-
- # Memory Subsystem Tests
- "kernel/memory/bitmap_allocator.tests.cpp"
- "kernel/memory/block_list_allocator.tests.cpp"
-
- # Filesystem Subsystem Tests
- "kernel/filesystem/devfs/filesystem.tests.cpp"
- "kernel/filesystem/devfs/inode.tests.cpp"
- "kernel/filesystem/ext2/filesystem.tests.cpp"
- "kernel/filesystem/ext2/inode.tests.cpp"
- "kernel/filesystem/path.tests.cpp"
- "kernel/filesystem/rootfs/filesystem.tests.cpp"
- "kernel/filesystem/rootfs/inode.tests.cpp"
- "kernel/filesystem/dentry.tests.cpp"
- "kernel/filesystem/device_inode.tests.cpp"
- "kernel/filesystem/mount_table.tests.cpp"
- "kernel/filesystem/mount.tests.cpp"
- "kernel/filesystem/open_file_descriptor.tests.cpp"
- "kernel/filesystem/open_file_table.tests.cpp"
- "kernel/filesystem/type_registry.tests.cpp"
- "kernel/filesystem/vfs.tests.cpp"
-
- # Storage Subsystem Tests
- "kernel/devices/block_device_utils.tests.cpp"
- "kernel/devices/block_device.tests.cpp"
- "kernel/devices/storage/ram_disk/device.tests.cpp"
- )
-
- target_link_libraries("kernel_tests" PRIVATE
- "kernel::lib"
- "Catch2::Catch2WithMain"
)
target_compile_definitions("kernel_tests" PRIVATE
@@ -224,13 +177,8 @@ if(BUILD_TESTING)
CXX_CLANG_TIDY ""
)
- enable_coverage("kernel_tests")
-
- file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bht_results")
-
- catch_discover_tests("kernel::tests"
- REPORTER junit
- OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/bht_results"
- OUTPUT_SUFFIX ".xml"
- )
+ if(COMMAND "enable_coverage")
+ enable_coverage("kernel_lib")
+ enable_coverage("kernel_tests")
+ endif()
endif()
diff --git a/kernel/kapi/acpi.cpp b/kernel/kapi/acpi.cpp
index b6d5cdf9..19188590 100644
--- a/kernel/kapi/acpi.cpp
+++ b/kernel/kapi/acpi.cpp
@@ -6,7 +6,7 @@
#include <acpi/acpi.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
#include <atomic>
#include <optional>
diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp
index 7b1a43b3..44331908 100644
--- a/kernel/kapi/cpu.cpp
+++ b/kernel/kapi/cpu.cpp
@@ -2,7 +2,7 @@
#include <kapi/system.hpp>
-#include <kstd/print>
+#include <kstd/print.hpp>
namespace kapi::cpu
{
diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp
index 572227e6..577a8898 100644
--- a/kernel/kapi/devices.cpp
+++ b/kernel/kapi/devices.cpp
@@ -4,9 +4,9 @@
#include <kapi/system.hpp>
-#include <kstd/flat_map>
-#include <kstd/memory>
-#include <kstd/print>
+#include <kstd/flat_map.hpp>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
#include <atomic>
#include <cstddef>
diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp
index 59753f79..43310d2b 100644
--- a/kernel/kapi/devices/bus.cpp
+++ b/kernel/kapi/devices/bus.cpp
@@ -3,10 +3,10 @@
#include <kapi/devices.hpp>
#include <kapi/system.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/string>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/string.hpp>
+#include <kstd/vector.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp
index 8b5d6b97..5dc59a27 100644
--- a/kernel/kapi/devices/device.cpp
+++ b/kernel/kapi/devices/device.cpp
@@ -2,8 +2,8 @@
#include <kapi/devices/bus.hpp>
-#include <kstd/memory>
-#include <kstd/string>
+#include <kstd/memory.hpp>
+#include <kstd/string.hpp>
#include <cstddef>
diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp
index 68b51c97..efde1336 100644
--- a/kernel/kapi/filesystem.cpp
+++ b/kernel/kapi/filesystem.cpp
@@ -4,73 +4,53 @@
#include <kernel/filesystem/open_file_table.hpp>
#include <kernel/filesystem/vfs.hpp>
-#include <kstd/memory>
-#include <kstd/unikstd.h>
+#include <kstd/memory.hpp>
+#include <kstd/system_error.hpp>
#include <cstddef>
+#include <expected>
#include <string_view>
namespace kapi::filesystem
{
- auto mount(std::string_view source, std::string_view target) -> kstd::ssize_t
+ auto mount(std::string_view source, std::string_view target) -> std::expected<void, kstd::error_code>
{
- if (kernel::filesystem::vfs::get().do_mount(source, target) == kernel::filesystem::vfs::operation_result::success)
- {
- return 0;
- }
- return -1;
+ return kernel::filesystem::vfs::get().mount(source, target);
}
- auto umount(std::string_view target) -> kstd::ssize_t
+ auto umount(std::string_view target) -> std::expected<void, kstd::error_code>
{
- if (kernel::filesystem::vfs::get().unmount(target) == kernel::filesystem::vfs::operation_result::success)
- {
- return 0;
- }
- return -1;
+ return kernel::filesystem::vfs::get().unmount(target);
}
- auto open(std::string_view path) -> kstd::ssize_t
+ auto open(std::string_view path) -> std::expected<std::size_t, kstd::error_code>
{
- if (auto dentry = kernel::filesystem::vfs::get().open(path))
- {
+ return kernel::filesystem::vfs::get().open(path).and_then([](auto dentry) {
auto open_file_descriptor = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry);
return kernel::filesystem::open_file_table::get().add_file(open_file_descriptor);
- }
-
- return -1;
+ });
}
- auto close(size_t file_descriptor) -> kstd::ssize_t
+ auto close(size_t file_descriptor) -> std::expected<void, kstd::error_code>
{
- if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor))
- {
- if (kernel::filesystem::vfs::get().close(open_file_descriptor->get_dentry()->absolute_path()) ==
- kernel::filesystem::vfs::operation_result::success)
- {
- return kernel::filesystem::open_file_table::get().remove_file(file_descriptor);
- }
- }
- return -1;
+ return kernel::filesystem::open_file_table::get()
+ .file(file_descriptor)
+ .transform([](auto file) { return file->get_dentry()->absolute_path(); })
+ .and_then([](auto path) { return kernel::filesystem::vfs::get().close(path); })
+ .and_then([=]() { return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); });
}
- auto read(size_t file_descriptor, void * buffer, size_t size) -> kstd::ssize_t
+ auto read(size_t file_descriptor, void * buffer, size_t size) -> std::expected<std::size_t, kstd::error_code>
{
- if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor))
- {
- return open_file_descriptor->read(buffer, size);
- }
-
- return -1;
+ return kernel::filesystem::open_file_table::get().file(file_descriptor).and_then([=](auto descriptor) {
+ return descriptor->read(buffer, size);
+ });
}
- auto write(size_t file_descriptor, void const * buffer, size_t size) -> kstd::ssize_t
+ auto write(size_t file_descriptor, void const * buffer, size_t size) -> std::expected<std::size_t, kstd::error_code>
{
- if (auto open_file_descriptor = kernel::filesystem::open_file_table::get().file(file_descriptor))
- {
- return open_file_descriptor->write(buffer, size);
- }
-
- return -1;
+ return kernel::filesystem::open_file_table::get().file(file_descriptor).and_then([=](auto descriptor) {
+ return descriptor->write(buffer, size);
+ });
}
} // namespace kapi::filesystem \ No newline at end of file
diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp
index d241afa8..d1e01db6 100644
--- a/kernel/kapi/filesystem.tests.cpp
+++ b/kernel/kapi/filesystem.tests.cpp
@@ -2,6 +2,8 @@
#include <kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp>
+#include <kstd/system_error.hpp>
+
#include <catch2/catch_test_macros.hpp>
#include <algorithm>
@@ -25,159 +27,149 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
THEN("files can be opened, read and closed again")
{
- auto fd = kapi::filesystem::open("/information/info_1.txt");
- REQUIRE(fd >= 0);
+ auto fd = kapi::filesystem::open("/information/info_1.txt").value();
auto buffer = std::vector<std::byte>(6);
auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
- REQUIRE(bytes_read >= 0);
+ REQUIRE(bytes_read);
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(*bytes_read)};
REQUIRE(buffer_as_str == "info_1");
- REQUIRE(kapi::filesystem::close(fd) == 0);
+ REQUIRE(kapi::filesystem::close(fd));
}
THEN("files can be opened through absolute symbolic link, read and closed again")
{
- auto fd = kapi::filesystem::open("/symlinks/information_directory_absolute/info_1.txt");
- REQUIRE(fd >= 0);
+ auto fd = kapi::filesystem::open("/symlinks/information_directory_absolute/info_1.txt").value();
auto buffer = std::vector<std::byte>(6);
auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
- REQUIRE(bytes_read >= 0);
+ REQUIRE(bytes_read);
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(*bytes_read)};
REQUIRE(buffer_as_str == "info_1");
- REQUIRE(kapi::filesystem::close(fd) == 0);
+ REQUIRE(kapi::filesystem::close(fd));
}
THEN("files can be opened through relative symbolic link, read and closed again")
{
- auto fd = kapi::filesystem::open("/symlinks/information_directory_relative/info_1.txt");
- REQUIRE(fd >= 0);
+ auto fd = kapi::filesystem::open("/symlinks/information_directory_relative/info_1.txt").value();
auto buffer = std::vector<std::byte>(6);
auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
- REQUIRE(bytes_read >= 0);
+ REQUIRE(bytes_read);
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(*bytes_read)};
REQUIRE(buffer_as_str == "info_1");
- REQUIRE(kapi::filesystem::close(fd) == 0);
+ REQUIRE(kapi::filesystem::close(fd));
}
THEN("files can be opened through relative symbolic link over multiple mount points, read and closed again")
{
- kapi::filesystem::mount("/archiv/2024.img", "/information");
+ CHECK(kapi::filesystem::mount("/archiv/2024.img", "/information"));
- auto fd = kapi::filesystem::open("/information/symlinks/traverse_back_twice/information/sheep_1.txt");
- REQUIRE(fd >= 0);
+ auto fd = kapi::filesystem::open("/information/symlinks/traverse_back_twice/information/sheep_1.txt").value();
auto buffer = std::vector<std::byte>(7);
auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
- REQUIRE(bytes_read >= 0);
+ REQUIRE(bytes_read);
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(*bytes_read)};
REQUIRE(buffer_as_str == "sheep_1");
- REQUIRE(kapi::filesystem::close(fd) == 0);
+ REQUIRE(kapi::filesystem::close(fd));
}
THEN("a filesystem can be mounted, files can be opened, read and closed again and unmounted")
{
- REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information") == 0);
+ REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information"));
- auto fd = kapi::filesystem::open("/information/monkey_house/monkey_1.txt");
- REQUIRE(fd >= 0);
+ auto fd = kapi::filesystem::open("/information/monkey_house/monkey_1.txt").value();
auto buffer = std::vector<std::byte>(8);
auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
- REQUIRE(bytes_read >= 0);
+ REQUIRE(bytes_read);
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(*bytes_read)};
REQUIRE(buffer_as_str == "monkey_1");
- REQUIRE(kapi::filesystem::close(fd) == 0);
- REQUIRE(kapi::filesystem::umount("/information") == 0);
+ REQUIRE(kapi::filesystem::close(fd));
+ REQUIRE(kapi::filesystem::umount("/information"));
}
THEN("a filesystem cannot be unmounted if files are still open and can be unmounted after files are closed")
{
- REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information") == 0);
+ REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information"));
- auto fd = kapi::filesystem::open("/information/monkey_house/monkey_1.txt");
- REQUIRE(fd >= 0);
+ auto fd = kapi::filesystem::open("/information/monkey_house/monkey_1.txt").value();
- REQUIRE(kapi::filesystem::umount("/information") < 0);
+ REQUIRE(!kapi::filesystem::umount("/information"));
- REQUIRE(kapi::filesystem::close(fd) == 0);
- REQUIRE(kapi::filesystem::umount("/information") == 0);
+ REQUIRE(kapi::filesystem::close(fd));
+ REQUIRE(kapi::filesystem::umount("/information"));
}
THEN("device can be opened as file and read from")
{
- auto fd = kapi::filesystem::open("/dev/ram0");
- REQUIRE(fd >= 0);
+ auto fd = kapi::filesystem::open("/dev/ram0").value();
auto buffer = std::vector<std::byte>(512);
auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size());
- REQUIRE(bytes_read >= 0);
+ REQUIRE(bytes_read);
- REQUIRE(kapi::filesystem::close(fd) == 0);
+ REQUIRE(kapi::filesystem::close(fd));
}
THEN("device can be opened as file and written to and read from again")
{
- auto read_fd = kapi::filesystem::open("/dev/ram16");
- REQUIRE(read_fd >= 0);
+ auto read_fd = kapi::filesystem::open("/dev/ram16").value();
auto buffer = std::vector<std::byte>(512, std::byte{0xAB});
auto bytes_written = kapi::filesystem::write(read_fd, buffer.data(), buffer.size());
- REQUIRE(bytes_written >= 0);
+ REQUIRE(bytes_written);
- auto write_fd = kapi::filesystem::open("/dev/ram16");
- REQUIRE(write_fd >= 0);
+ auto write_fd = kapi::filesystem::open("/dev/ram16").value();
auto read_buffer = std::vector<std::byte>(512);
auto bytes_read = kapi::filesystem::read(write_fd, read_buffer.data(), read_buffer.size());
- REQUIRE(bytes_read >= 0);
+ REQUIRE(bytes_read);
REQUIRE(std::equal(buffer.begin(), buffer.end(), read_buffer.begin()));
- REQUIRE(kapi::filesystem::close(write_fd) == 0);
- REQUIRE(kapi::filesystem::close(read_fd) == 0);
+ REQUIRE(kapi::filesystem::close(write_fd));
+ REQUIRE(kapi::filesystem::close(read_fd));
}
THEN("invalid paths cannot be mounted or unmounted")
{
- REQUIRE(kapi::filesystem::mount("/dev/ram16", "invalid_path") < 0);
+ REQUIRE(!kapi::filesystem::mount("/dev/ram16", "invalid_path"));
}
THEN("invalid paths cannot be unmounted")
{
- REQUIRE(kapi::filesystem::umount("invalid_path") < 0);
+ REQUIRE(!kapi::filesystem::umount("invalid_path"));
}
THEN("non existent files cannot be opened")
{
auto fd = kapi::filesystem::open("/information/non_existent.txt");
- REQUIRE(fd < 0);
+ REQUIRE(!fd);
}
THEN("not opened files cannot closed")
{
- REQUIRE(kapi::filesystem::close(999) < 0);
+ REQUIRE(!kapi::filesystem::close(999));
}
THEN("same file cannot be closed twice")
{
- auto fd = kapi::filesystem::open("/information/info_1.txt");
- REQUIRE(fd >= 0);
+ auto fd = kapi::filesystem::open("/information/info_1.txt").value();
- REQUIRE(kapi::filesystem::close(fd) == 0);
- REQUIRE(kapi::filesystem::close(fd) < 0);
+ REQUIRE(kapi::filesystem::close(fd));
+ REQUIRE(!kapi::filesystem::close(fd));
}
THEN("not opened files cannot be read from")
@@ -185,7 +177,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
std::vector<std::byte> buffer(10);
auto const invalid_fd = 999uz;
auto bytes_read = kapi::filesystem::read(invalid_fd, buffer.data(), buffer.size());
- REQUIRE(bytes_read < 0);
+ REQUIRE(!bytes_read);
}
THEN("not opened files cannot be written to")
@@ -193,7 +185,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
std::vector<std::byte> buffer(10);
auto const invalid_fd = 999uz;
auto bytes_written = kapi::filesystem::write(invalid_fd, buffer.data(), buffer.size());
- REQUIRE(bytes_written < 0);
+ REQUIRE(!bytes_written);
}
}
}
diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp
index 4efcaa37..18a1b29d 100644
--- a/kernel/kapi/interrupts.cpp
+++ b/kernel/kapi/interrupts.cpp
@@ -1,8 +1,8 @@
#include <kapi/interrupts.hpp>
-#include <kstd/flat_map>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/flat_map.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <algorithm>
#include <cstdint>
diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp
index 5ea08b16..91a6c2c7 100644
--- a/kernel/kapi/memory.cpp
+++ b/kernel/kapi/memory.cpp
@@ -5,8 +5,8 @@
#include <kapi/system.hpp>
-#include <kstd/print>
-#include <kstd/units>
+#include <kstd/print.hpp>
+#include <kstd/units.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kapi/system.cpp b/kernel/kapi/system.cpp
index 9819ceb7..629e5990 100644
--- a/kernel/kapi/system.cpp
+++ b/kernel/kapi/system.cpp
@@ -2,7 +2,8 @@
#include <kapi/cpu.hpp>
-#include <kstd/print>
+#include <kstd/print.hpp>
+#include <kstd/system_error.hpp>
#include <source_location>
#include <string_view>
@@ -18,4 +19,12 @@ namespace kapi::system
cpu::halt();
}
+ [[gnu::weak]]
+ auto panic(std::string_view message, kstd::error_code error, std::source_location location) -> void
+ {
+ kstd::println(kstd::print_sink::stderr, "[PANIC] in {} : {} ({}) @ {}:{}", location.function_name(), message, error,
+ location.file_name(), location.line());
+ cpu::halt();
+ }
+
} // namespace kapi::system
diff --git a/kernel/kapi/system.tests.cpp b/kernel/kapi/system.tests.cpp
index 1e300316..a05e348b 100644
--- a/kernel/kapi/system.tests.cpp
+++ b/kernel/kapi/system.tests.cpp
@@ -3,7 +3,7 @@
#include <kernel/test_support/cio.hpp>
#include <kernel/test_support/cpu.hpp>
-#include <kstd/print>
+#include <kstd/print.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/acpi/manager.cpp b/kernel/kernel/acpi/manager.cpp
index bb895fda..e99baed8 100644
--- a/kernel/kernel/acpi/manager.cpp
+++ b/kernel/kernel/acpi/manager.cpp
@@ -5,8 +5,8 @@
#include <acpi/acpi.hpp>
-#include <kstd/memory>
-#include <kstd/print>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kernel/acpi/manager.hpp b/kernel/kernel/acpi/manager.hpp
index 1e8c1e85..ba05c682 100644
--- a/kernel/kernel/acpi/manager.hpp
+++ b/kernel/kernel/acpi/manager.hpp
@@ -3,9 +3,9 @@
#include <acpi/acpi.hpp>
-#include <kstd/flat_map>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/flat_map.hpp>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <string_view>
diff --git a/kernel/kernel/devices/block_device.cpp b/kernel/kernel/devices/block_device.cpp
index 13d73acd..a3531121 100644
--- a/kernel/kernel/devices/block_device.cpp
+++ b/kernel/kernel/devices/block_device.cpp
@@ -3,7 +3,7 @@
#include <kapi/devices/device.hpp>
#include <kapi/system.hpp>
-#include <kstd/string>
+#include <kstd/string.hpp>
#include <cstddef>
diff --git a/kernel/kernel/devices/block_device.hpp b/kernel/kernel/devices/block_device.hpp
index a6d68ee2..31599502 100644
--- a/kernel/kernel/devices/block_device.hpp
+++ b/kernel/kernel/devices/block_device.hpp
@@ -3,7 +3,7 @@
#include <kapi/devices/device.hpp>
-#include <kstd/string>
+#include <kstd/string.hpp>
#include <cstddef>
diff --git a/kernel/kernel/devices/block_device.tests.cpp b/kernel/kernel/devices/block_device.tests.cpp
index a2ddd2bb..98722638 100644
--- a/kernel/kernel/devices/block_device.tests.cpp
+++ b/kernel/kernel/devices/block_device.tests.cpp
@@ -2,10 +2,10 @@
#include <kernel/test_support/cpu.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/string>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/string.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/devices/block_device_utils.cpp b/kernel/kernel/devices/block_device_utils.cpp
index 18d1e9d7..68a0a306 100644
--- a/kernel/kernel/devices/block_device_utils.cpp
+++ b/kernel/kernel/devices/block_device_utils.cpp
@@ -5,9 +5,9 @@
#include <kapi/devices/device.hpp>
#include <kapi/system.hpp>
-#include <kstd/cstring>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/cstring.hpp>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kernel/devices/block_device_utils.hpp b/kernel/kernel/devices/block_device_utils.hpp
index 8be75b6f..88e23347 100644
--- a/kernel/kernel/devices/block_device_utils.hpp
+++ b/kernel/kernel/devices/block_device_utils.hpp
@@ -3,7 +3,7 @@
#include <kapi/devices/device.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
#include <cstddef>
diff --git a/kernel/kernel/devices/block_device_utils.tests.cpp b/kernel/kernel/devices/block_device_utils.tests.cpp
index e2e1e65e..c8c4acfb 100644
--- a/kernel/kernel/devices/block_device_utils.tests.cpp
+++ b/kernel/kernel/devices/block_device_utils.tests.cpp
@@ -4,9 +4,9 @@
#include <kernel/test_support/devices/block_device.hpp>
#include <kernel/test_support/devices/character_device.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/devices/storage/controller.cpp b/kernel/kernel/devices/storage/controller.cpp
index 171b918e..5ea9eb71 100644
--- a/kernel/kernel/devices/storage/controller.cpp
+++ b/kernel/kernel/devices/storage/controller.cpp
@@ -2,8 +2,8 @@
#include <kapi/devices/device.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kernel/devices/storage/controller.hpp b/kernel/kernel/devices/storage/controller.hpp
index bea18f38..13494a52 100644
--- a/kernel/kernel/devices/storage/controller.hpp
+++ b/kernel/kernel/devices/storage/controller.hpp
@@ -3,8 +3,8 @@
#include <kapi/devices/device.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <cstddef>
diff --git a/kernel/kernel/devices/storage/management.cpp b/kernel/kernel/devices/storage/management.cpp
index 06efc27d..90c3696f 100644
--- a/kernel/kernel/devices/storage/management.cpp
+++ b/kernel/kernel/devices/storage/management.cpp
@@ -7,8 +7,8 @@
#include <kapi/devices/device.hpp>
#include <kapi/system.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kernel/devices/storage/management.hpp b/kernel/kernel/devices/storage/management.hpp
index 9a840875..a9704462 100644
--- a/kernel/kernel/devices/storage/management.hpp
+++ b/kernel/kernel/devices/storage/management.hpp
@@ -5,8 +5,8 @@
#include <kapi/devices/device.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <cstddef>
diff --git a/kernel/kernel/devices/storage/ram_disk/controller.cpp b/kernel/kernel/devices/storage/ram_disk/controller.cpp
index 30441fa5..c1075733 100644
--- a/kernel/kernel/devices/storage/ram_disk/controller.cpp
+++ b/kernel/kernel/devices/storage/ram_disk/controller.cpp
@@ -4,7 +4,7 @@
#include <kapi/boot_module/boot_module_registry.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kernel/devices/storage/ram_disk/device.cpp b/kernel/kernel/devices/storage/ram_disk/device.cpp
index 1557204b..1b53b0d3 100644
--- a/kernel/kernel/devices/storage/ram_disk/device.cpp
+++ b/kernel/kernel/devices/storage/ram_disk/device.cpp
@@ -5,8 +5,8 @@
#include <kapi/boot_module/boot_module.hpp>
#include <kapi/system.hpp>
-#include <kstd/cstring>
-#include <kstd/string>
+#include <kstd/cstring.hpp>
+#include <kstd/string.hpp>
#include <cstddef>
diff --git a/kernel/kernel/filesystem/dentry.cpp b/kernel/kernel/filesystem/dentry.cpp
index 01de276c..9321453a 100644
--- a/kernel/kernel/filesystem/dentry.cpp
+++ b/kernel/kernel/filesystem/dentry.cpp
@@ -4,8 +4,8 @@
#include <kapi/system.hpp>
-#include <kstd/memory>
-#include <kstd/string>
+#include <kstd/memory.hpp>
+#include <kstd/string.hpp>
#include <algorithm>
#include <cstdint>
diff --git a/kernel/kernel/filesystem/dentry.hpp b/kernel/kernel/filesystem/dentry.hpp
index 096a6bbb..ea689485 100644
--- a/kernel/kernel/filesystem/dentry.hpp
+++ b/kernel/kernel/filesystem/dentry.hpp
@@ -3,9 +3,9 @@
#include <kernel/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/string>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/string.hpp>
+#include <kstd/vector.hpp>
#include <cstdint>
#include <string_view>
diff --git a/kernel/kernel/filesystem/dentry.tests.cpp b/kernel/kernel/filesystem/dentry.tests.cpp
index b7690f57..55cdf21e 100644
--- a/kernel/kernel/filesystem/dentry.tests.cpp
+++ b/kernel/kernel/filesystem/dentry.tests.cpp
@@ -3,8 +3,8 @@
#include <kernel/test_support/cpu.hpp>
#include <kernel/test_support/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/print>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp
index ce887ff3..7ffcb3c4 100644
--- a/kernel/kernel/filesystem/devfs/filesystem.cpp
+++ b/kernel/kernel/filesystem/devfs/filesystem.cpp
@@ -4,12 +4,15 @@
#include <kernel/devices/storage/management.hpp>
#include <kernel/filesystem/devfs/inode.hpp>
#include <kernel/filesystem/device_inode.hpp>
+#include <kernel/filesystem/error.hpp>
#include <kernel/filesystem/inode.hpp>
#include <kernel/filesystem/type.hpp>
#include <kapi/devices/device.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
#include <algorithm>
#include <string_view>
@@ -37,25 +40,30 @@ namespace kernel::filesystem::devfs
[[gnu::used]]
constexpr auto registration = type_registration<type>{};
- auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> operation_result
+ auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> kstd::result<void>
{
m_root_inode = kstd::make_shared<inode>();
build_device_inode_table();
- return operation_result::success;
+ return kstd::success();
}
auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
- -> kstd::shared_ptr<kernel::filesystem::inode>
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>
{
- if (!parent || !parent->is_directory())
+ if (!parent)
{
- return nullptr;
+ return kstd::failure(vfs_errc::invalid_inode);
+ }
+
+ if (!parent->is_directory())
+ {
+ return kstd::failure(vfs_errc::not_a_directory);
}
if (parent.get() != m_root_inode.get())
{
- return nullptr;
+ return kstd::failure(vfs_errc::invalid_inode);
}
auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) {
@@ -65,7 +73,13 @@ namespace kernel::filesystem::devfs
}
return false;
});
- return (it != m_inodes.end()) ? *it : nullptr;
+
+ if (it != m_inodes.end())
+ {
+ return *it;
+ }
+
+ return kstd::failure(vfs_errc::no_such_file_or_directory);
}
auto filesystem::build_device_inode_table() -> void
diff --git a/kernel/kernel/filesystem/devfs/filesystem.hpp b/kernel/kernel/filesystem/devfs/filesystem.hpp
index dbaa387b..dadeaf7d 100644
--- a/kernel/kernel/filesystem/devfs/filesystem.hpp
+++ b/kernel/kernel/filesystem/devfs/filesystem.hpp
@@ -5,8 +5,10 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <string_view>
@@ -25,7 +27,7 @@ namespace kernel::filesystem::devfs
@param backing_inode Backing inode passed by the vfs (not required by devfs).
@return The result of the mount operation.
*/
- auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result override;
+ auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> kstd::result<void> override;
/**
@brief Looks up an inode by @p name within a @p parent directory.
@@ -34,7 +36,7 @@ namespace kernel::filesystem::devfs
@return A pointer to the found inode, or a null pointer if not found.
*/
[[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
- -> kstd::shared_ptr<kernel::filesystem::inode> override;
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
private:
auto build_device_inode_table() -> void;
diff --git a/kernel/kernel/filesystem/devfs/filesystem.tests.cpp b/kernel/kernel/filesystem/devfs/filesystem.tests.cpp
index 36cb4117..d5028231 100644
--- a/kernel/kernel/filesystem/devfs/filesystem.tests.cpp
+++ b/kernel/kernel/filesystem/devfs/filesystem.tests.cpp
@@ -17,40 +17,40 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture,
THEN("mount succeeds")
{
- REQUIRE(result == kernel::filesystem::filesystem::operation_result::success);
- REQUIRE(fs.root_inode() != nullptr);
+ REQUIRE(result);
+ REQUIRE(fs.root_inode());
}
THEN("lookup on root finds ram0 device inode")
{
auto inode = fs.lookup(fs.root_inode(), "ram0");
- REQUIRE(inode != nullptr);
- REQUIRE(inode->is_device());
+ REQUIRE(inode);
+ REQUIRE(inode.value()->is_device());
}
- THEN("lookup of an unknown device returns null")
+ THEN("lookup of an unknown device returns error")
{
auto inode = fs.lookup(fs.root_inode(), "ram99");
- REQUIRE(inode == nullptr);
+ REQUIRE(!inode);
}
- THEN("lookup with wrong parent returns null")
+ THEN("lookup with wrong parent returns error")
{
auto other_fs = kernel::filesystem::devfs::filesystem{};
- other_fs.mount(nullptr);
+ CHECK(other_fs.mount(nullptr));
auto inode = fs.lookup(other_fs.root_inode(), "ram0");
- REQUIRE(inode == nullptr);
+ REQUIRE(!inode);
}
- THEN("lookup with a non-directory parent returns null")
+ THEN("lookup with a non-directory parent returns error")
{
auto non_directory_inode = fs.lookup(fs.root_inode(), "ram0");
- REQUIRE(non_directory_inode != nullptr);
- REQUIRE_FALSE(non_directory_inode->is_directory());
+ REQUIRE(non_directory_inode);
+ REQUIRE_FALSE(non_directory_inode.value()->is_directory());
- auto result = fs.lookup(non_directory_inode, "anything");
- REQUIRE(result == nullptr);
+ auto result = fs.lookup(*non_directory_inode, "anything");
+ REQUIRE(!result);
}
}
@@ -60,13 +60,13 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture,
auto fs = kernel::filesystem::devfs::filesystem{};
auto result = fs.mount(nullptr);
- REQUIRE(result == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(result);
THEN("lookup finds all generated RAM devices")
{
- REQUIRE(fs.lookup(fs.root_inode(), "ram0") != nullptr);
- REQUIRE(fs.lookup(fs.root_inode(), "ram16") != nullptr);
- REQUIRE(fs.lookup(fs.root_inode(), "ram32") != nullptr);
+ REQUIRE(fs.lookup(fs.root_inode(), "ram0"));
+ REQUIRE(fs.lookup(fs.root_inode(), "ram16"));
+ REQUIRE(fs.lookup(fs.root_inode(), "ram32"));
}
}
}
diff --git a/kernel/kernel/filesystem/devfs/inode.cpp b/kernel/kernel/filesystem/devfs/inode.cpp
index 7bbfbbed..2e4ee7de 100644
--- a/kernel/kernel/filesystem/devfs/inode.cpp
+++ b/kernel/kernel/filesystem/devfs/inode.cpp
@@ -1,15 +1,17 @@
#include <kernel/filesystem/devfs/inode.hpp>
+#include <kstd/result.hpp>
+
#include <cstddef>
namespace kernel::filesystem::devfs
{
- auto inode::read(void *, size_t, size_t) const -> size_t
+ auto inode::read(void *, size_t, size_t) const -> kstd::result<size_t>
{
return 0;
}
- auto inode::write(void const *, size_t, size_t) -> size_t
+ auto inode::write(void const *, size_t, size_t) -> kstd::result<size_t>
{
return 0;
}
diff --git a/kernel/kernel/filesystem/devfs/inode.hpp b/kernel/kernel/filesystem/devfs/inode.hpp
index e4288918..3472079f 100644
--- a/kernel/kernel/filesystem/devfs/inode.hpp
+++ b/kernel/kernel/filesystem/devfs/inode.hpp
@@ -3,6 +3,8 @@
#include <kernel/filesystem/inode.hpp>
+#include <kstd/result.hpp>
+
#include <cstddef>
namespace kernel::filesystem::devfs
@@ -20,7 +22,7 @@ namespace kernel::filesystem::devfs
@param size Number of bytes requested.
@return Number of bytes read (always 0 because this inode does not expose file data).
*/
- auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
+ auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
/**
@brief Writes to the devfs directory inode.
@@ -29,7 +31,7 @@ namespace kernel::filesystem::devfs
@param size Number of bytes requested.
@return Number of bytes written (always 0 because writes are not supported for this inode).
*/
- auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+ auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
/**
@brief Check if this inode represents a directory.
diff --git a/kernel/kernel/filesystem/devfs/inode.tests.cpp b/kernel/kernel/filesystem/devfs/inode.tests.cpp
index ae26e742..ecf9a79b 100644
--- a/kernel/kernel/filesystem/devfs/inode.tests.cpp
+++ b/kernel/kernel/filesystem/devfs/inode.tests.cpp
@@ -1,8 +1,8 @@
#include <kernel/filesystem/devfs/inode.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp
index 81a784cd..644e3df7 100644
--- a/kernel/kernel/filesystem/device_inode.cpp
+++ b/kernel/kernel/filesystem/device_inode.cpp
@@ -5,7 +5,8 @@
#include <kapi/devices/device.hpp>
#include <kapi/system.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
#include <cstddef>
@@ -20,7 +21,7 @@ namespace kernel::filesystem
}
}
- auto device_inode::read(void * buffer, size_t offset, size_t size) const -> size_t
+ auto device_inode::read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t>
{
if (m_device->is_block_device())
{
@@ -32,7 +33,7 @@ namespace kernel::filesystem
}
}
- auto device_inode::write(void const * buffer, size_t offset, size_t size) -> size_t
+ auto device_inode::write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t>
{
if (m_device->is_block_device())
{
diff --git a/kernel/kernel/filesystem/device_inode.hpp b/kernel/kernel/filesystem/device_inode.hpp
index f4aa2d1e..5b22366a 100644
--- a/kernel/kernel/filesystem/device_inode.hpp
+++ b/kernel/kernel/filesystem/device_inode.hpp
@@ -5,7 +5,8 @@
#include <kapi/devices/device.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
#include <cstddef>
@@ -32,7 +33,7 @@ namespace kernel::filesystem
@param size The number of bytes to read.
@return The number of bytes read.
*/
- auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
+ auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
/**
@brief Write data to the device inode (and in the background from the associated device) from a @p buffer, starting
@@ -42,7 +43,7 @@ namespace kernel::filesystem
@param size The number of bytes to write.
@return The number of bytes written.
*/
- auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+ auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
/**
@brief Get the associated device.
@@ -52,7 +53,7 @@ namespace kernel::filesystem
/**
@brief Check if this inode represents a device.
- @return returns true, since this indoe is a device inode and represents a device.
+ @return returns true, since this inode is a device inode and represents a device.
*/
[[nodiscard]] auto is_device() const -> bool override;
diff --git a/kernel/kernel/filesystem/device_inode.tests.cpp b/kernel/kernel/filesystem/device_inode.tests.cpp
index 025a22a2..d78d4a07 100644
--- a/kernel/kernel/filesystem/device_inode.tests.cpp
+++ b/kernel/kernel/filesystem/device_inode.tests.cpp
@@ -4,9 +4,9 @@
#include <kernel/test_support/devices/block_device.hpp>
#include <kernel/test_support/devices/character_device.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/filesystem/error.hpp b/kernel/kernel/filesystem/error.hpp
new file mode 100644
index 00000000..56f56ce4
--- /dev/null
+++ b/kernel/kernel/filesystem/error.hpp
@@ -0,0 +1,135 @@
+#ifndef TEACHOS_KERNEL_FILESYSTEM_ERROR_HPP
+#define TEACHOS_KERNEL_FILESYSTEM_ERROR_HPP
+
+#include <kstd/system_error.hpp>
+
+#include <string_view>
+#include <type_traits>
+
+namespace kernel::filesystem
+{
+
+ enum struct vfs_errc : int
+ {
+ invalid_path = 1,
+ no_such_file_or_directory,
+ mount_point_not_found,
+ mount_busy,
+ has_child_mounts,
+ invalid_filesystem,
+ unmount_failed,
+ too_many_symbolic_link_levels,
+ unsupported_filesystem,
+ invalid_file_descriptor,
+ invalid_inode,
+ not_a_directory,
+ is_a_directory,
+ };
+
+ namespace detail
+ {
+ struct vfs_category_t final : kstd::error_category
+ {
+ [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
+ {
+ return "vfs";
+ }
+
+ [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
+ {
+ switch (static_cast<vfs_errc>(value))
+ {
+ case vfs_errc::invalid_path:
+ return "invalid path";
+ case vfs_errc::no_such_file_or_directory:
+ return "no such file or directory";
+ case vfs_errc::mount_point_not_found:
+ return "mount point not found";
+ case vfs_errc::mount_busy:
+ return "mount point is busy";
+ case vfs_errc::has_child_mounts:
+ return "mount point has child mounts";
+ case vfs_errc::invalid_filesystem:
+ return "invalid filesystem";
+ case vfs_errc::unmount_failed:
+ return "unmount failed";
+ case vfs_errc::too_many_symbolic_link_levels:
+ return "too many symbolic link levels";
+ case vfs_errc::unsupported_filesystem:
+ return "unsupported filesystem";
+ case vfs_errc::invalid_file_descriptor:
+ return "invalid file descriptor";
+ case vfs_errc::invalid_inode:
+ return "invalid inode";
+ case vfs_errc::not_a_directory:
+ return "not a directory";
+ case vfs_errc::is_a_directory:
+ return "is a directory";
+ default:
+ return "unknown VFS error";
+ }
+ }
+
+ [[nodiscard]] constexpr auto default_error_condition(int value) const noexcept -> kstd::error_condition override
+ {
+ switch (static_cast<vfs_errc>(value))
+ {
+ case vfs_errc::invalid_path:
+ case vfs_errc::invalid_filesystem:
+ case vfs_errc::invalid_inode:
+ return make_error_condition(kstd::errc::invalid_argument);
+ case vfs_errc::no_such_file_or_directory:
+ case vfs_errc::mount_point_not_found:
+ return make_error_condition(kstd::errc::no_such_file_or_directory);
+ case kernel::filesystem::vfs_errc::mount_busy:
+ case kernel::filesystem::vfs_errc::has_child_mounts:
+ case vfs_errc::unmount_failed:
+ return make_error_condition(kstd::errc::device_or_resource_busy);
+ case vfs_errc::too_many_symbolic_link_levels:
+ return make_error_condition(kstd::errc::too_many_symbolic_link_levels);
+ case vfs_errc::unsupported_filesystem:
+ return make_error_condition(kstd::errc::not_supported);
+ case vfs_errc::invalid_file_descriptor:
+ return make_error_condition(kstd::errc::bad_file_descriptor);
+ case vfs_errc::not_a_directory:
+ return make_error_condition(kstd::errc::not_a_directory);
+ case vfs_errc::is_a_directory:
+ return make_error_condition(kstd::errc::is_a_directory);
+ default:
+ return kstd::error_condition{value, *this};
+ }
+ }
+ } constexpr inline vfs_category_instance{};
+ } // namespace detail
+
+ [[nodiscard]] constexpr auto inline vfs_category() noexcept -> kstd::error_category const &
+ {
+ return detail::vfs_category_instance;
+ }
+
+ [[nodiscard]] constexpr auto inline make_error_code(vfs_errc error) noexcept -> kstd::error_code
+ {
+ return {static_cast<int>(error), vfs_category()};
+ }
+
+ [[nodiscard]] constexpr auto inline make_error_condition(vfs_errc error) noexcept -> kstd::error_condition
+ {
+ return {static_cast<int>(error), vfs_category()};
+ }
+
+} // namespace kernel::filesystem
+
+namespace kstd
+{
+ template<>
+ struct is_error_code_enum<kernel::filesystem::vfs_errc> : std::true_type
+ {
+ };
+
+ template<>
+ struct is_error_condition_enum<kernel::filesystem::vfs_errc> : std::true_type
+ {
+ };
+} // namespace kstd
+
+#endif
diff --git a/kernel/kernel/filesystem/ext2/error.hpp b/kernel/kernel/filesystem/ext2/error.hpp
new file mode 100644
index 00000000..79f40517
--- /dev/null
+++ b/kernel/kernel/filesystem/ext2/error.hpp
@@ -0,0 +1,109 @@
+#ifndef TEACHOS_KERNEL_FILESYSTEM_EXT2_ERROR_HPP
+#define TEACHOS_KERNEL_FILESYSTEM_EXT2_ERROR_HPP
+
+#include <kernel/filesystem/error.hpp>
+
+#include <kstd/system_error.hpp>
+
+#include <string_view>
+#include <type_traits>
+
+namespace kernel::filesystem::ext2
+{
+
+ enum struct ext2_errc : int
+ {
+ invalid_magic_number = 1,
+ invalid_root_inode,
+ invalid_block_group_index,
+ invalid_block_index,
+ invalid_block_number,
+ failed_to_read_superblock,
+ failed_to_read_block_group_descriptors,
+ };
+
+ namespace detail
+ {
+ struct ext2_category_t final : kstd::error_category
+ {
+ [[nodiscard]] constexpr auto name() const noexcept -> std::string_view override
+ {
+ return "ext2";
+ }
+
+ [[nodiscard]] constexpr auto message(int value) const noexcept -> std::string_view override
+ {
+ switch (static_cast<ext2_errc>(value))
+ {
+ case ext2_errc::invalid_magic_number:
+ return "invalid filesystem magic";
+ case ext2_errc::invalid_root_inode:
+ return "invalid root inode";
+ case ext2_errc::invalid_block_group_index:
+ return "block group index out of bounds";
+ case ext2_errc::invalid_block_index:
+ return "block index out of bounds";
+ case ext2_errc::invalid_block_number:
+ return "block number out of bounds";
+ case ext2_errc::failed_to_read_superblock:
+ return "failed to read superblock";
+ case ext2_errc::failed_to_read_block_group_descriptors:
+ return "failed to read block group descriptors";
+ default:
+ return "unknown ext2 error";
+ };
+ }
+
+ [[nodiscard]] constexpr auto equivalent(int code, kstd::error_condition const & condition) const noexcept
+ -> bool override
+ {
+ switch (static_cast<ext2_errc>(code))
+ {
+ case ext2_errc::invalid_magic_number:
+ case ext2_errc::invalid_root_inode:
+ if (condition.category() == kernel::filesystem::vfs_category())
+ {
+ return condition.value() == static_cast<int>(kernel::filesystem::vfs_errc::invalid_filesystem);
+ }
+ else if (condition.category() == kstd::generic_category())
+ {
+ return condition.value() == static_cast<int>(kstd::errc::invalid_argument);
+ }
+ break;
+ case ext2_errc::invalid_block_group_index:
+ case ext2_errc::invalid_block_index:
+ case ext2_errc::invalid_block_number:
+ case ext2_errc::failed_to_read_superblock:
+ case ext2_errc::failed_to_read_block_group_descriptors:
+ if (condition.category() == kstd::generic_category())
+ {
+ return condition.value() == static_cast<int>(kstd::errc::io_error);
+ }
+ break;
+ }
+ return kstd::error_category::equivalent(code, condition);
+ }
+ } constexpr inline ext2_category_instance{};
+ } // namespace detail
+
+ [[nodiscard]] constexpr auto inline ext2_category() noexcept -> kstd::error_category const &
+ {
+ return detail::ext2_category_instance;
+ }
+
+ [[nodiscard]] constexpr auto inline make_error_code(ext2_errc error) noexcept -> kstd::error_code
+ {
+ return {static_cast<int>(error), ext2_category()};
+ }
+
+} // namespace kernel::filesystem::ext2
+
+namespace kstd
+{
+ template<>
+ struct is_error_code_enum<kernel::filesystem::ext2::ext2_errc> : std::true_type
+ {
+ };
+} // namespace kstd
+
+#endif
diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp
index 3180a19a..34ee1f75 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.cpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.cpp
@@ -1,6 +1,8 @@
#include <kernel/filesystem/ext2/filesystem.hpp>
+#include <kernel/filesystem/error.hpp>
#include <kernel/filesystem/ext2/block_group_descriptor.hpp>
+#include <kernel/filesystem/ext2/error.hpp>
#include <kernel/filesystem/ext2/inode.hpp>
#include <kernel/filesystem/ext2/linked_directory_entry.hpp>
#include <kernel/filesystem/ext2/superblock.hpp>
@@ -8,14 +10,17 @@
#include <kernel/filesystem/inode.hpp>
#include <kernel/filesystem/type.hpp>
-#include <kstd/memory>
-#include <kstd/unikstd.h>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <array>
#include <cstddef>
#include <cstdint>
+#include <expected>
#include <string_view>
+#include <tuple>
namespace kernel::filesystem::ext2
{
@@ -41,15 +46,19 @@ namespace kernel::filesystem::ext2
[[gnu::used]]
constexpr auto registration = type_registration<type>{};
- auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result
+ auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> kstd::result<void>
{
- kernel::filesystem::filesystem::mount(backing_inode);
+ std::ignore = kernel::filesystem::filesystem::mount(backing_inode);
- m_backing_inode->read(&m_superblock, constants::superblock_offset, sizeof(m_superblock));
+ if (auto read_result = m_backing_inode->read(&m_superblock, constants::superblock_offset, sizeof(m_superblock));
+ !read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
if (m_superblock.magic != constants::magic_number)
{
- return operation_result::invalid_magic_number;
+ return kstd::failure(ext2_errc::invalid_magic_number);
}
auto const blocks_per_group = m_superblock.blocks_per_group;
@@ -57,40 +66,58 @@ namespace kernel::filesystem::ext2
m_block_group_descriptors = kstd::vector<block_group_descriptor>(num_block_groups);
- m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset(),
- num_block_groups * sizeof(block_group_descriptor));
+ if (auto read_result =
+ m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset(),
+ num_block_groups * sizeof(block_group_descriptor));
+ !read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
- m_root_inode = read_inode(constants::root_inode_number);
+ if (auto root_inode = read_inode(constants::root_inode_number))
+ {
+ m_root_inode = root_inode.value();
+ }
if (!m_root_inode || !m_root_inode->is_directory())
{
- return operation_result::invalid_root_inode;
+ return kstd::failure(ext2_errc::invalid_root_inode);
}
- return operation_result::success;
+
+ return {};
}
auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
- -> kstd::shared_ptr<kernel::filesystem::inode>
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>
{
- if (!parent || !parent->is_directory())
+ if (!parent)
{
- return nullptr;
+ return kstd::failure(vfs_errc::invalid_inode);
}
- auto * ext2_parent = static_cast<inode *>(parent.get());
- if (!ext2_parent)
+ if (!parent->is_directory())
{
- return nullptr;
+ return kstd::failure(vfs_errc::not_a_directory);
}
+ auto * ext2_parent = static_cast<inode *>(parent.get());
auto const & inode_data = ext2_parent->data();
kstd::vector<uint8_t> buffer(block_size());
for (uint32_t i = 0; i < inode_block_count(inode_data); ++i)
{
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();
- m_backing_inode->read(buffer.data(), block_offset, block_size());
+
+ if (!global_block_number)
+ {
+ return kstd::failure(global_block_number.error());
+ }
+
+ auto const block_offset = global_block_number.value() * block_size();
+ if (auto read_result = m_backing_inode->read(buffer.data(), block_offset, block_size()); !read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
auto const * entry = reinterpret_cast<linked_directory_entry const *>(buffer.data());
auto bytes_read = 0uz;
@@ -108,10 +135,10 @@ namespace kernel::filesystem::ext2
}
}
- return nullptr;
+ return kstd::failure(vfs_errc::no_such_file_or_directory);
}
- auto filesystem::read_inode(uint32_t inode_number) const -> kstd::shared_ptr<inode>
+ auto filesystem::read_inode(uint32_t inode_number) const -> kstd::result<kstd::shared_ptr<inode>>
{
auto const inodes_per_group = m_superblock.inodes_per_group;
auto const block_group_index = (inode_number - 1) / inodes_per_group;
@@ -119,7 +146,7 @@ namespace kernel::filesystem::ext2
if (block_group_index >= m_block_group_descriptors.size())
{
- return nullptr;
+ return kstd::failure(ext2_errc::invalid_block_group_index);
}
auto const & block_group_descriptor = m_block_group_descriptors.at(block_group_index);
@@ -128,7 +155,10 @@ namespace kernel::filesystem::ext2
auto const inode_offset = inode_table_offset + inode_index_within_group * inode_size();
auto new_inode_data = inode_data{};
- m_backing_inode->read(&new_inode_data, inode_offset, sizeof(inode_data));
+ if (auto read_result = m_backing_inode->read(&new_inode_data, inode_offset, sizeof(inode_data)); !read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
return kstd::make_shared<inode>(this, new_inode_data);
}
@@ -143,7 +173,7 @@ namespace kernel::filesystem::ext2
}
auto filesystem::map_inode_block_index_to_global_block_number(size_t inode_block_index, inode_data data) const
- -> kstd::ssize_t
+ -> std::expected<std::size_t, kstd::error_code>
{
if (inode_block_index < constants::direct_block_count)
{
@@ -171,7 +201,15 @@ namespace kernel::filesystem::ext2
auto const idx = inode_block_index / stride;
inode_block_index %= stride;
- block_number = read_block_number_at_index(block_number, idx);
+ if (auto read_result = read_block_number_at_index(block_number, idx); !read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
+ else
+ {
+ block_number = read_result.value();
+ }
+
if (block_number == 0)
{
return 0;
@@ -186,16 +224,20 @@ namespace kernel::filesystem::ext2
return block_number;
}
- return -1;
+ return kstd::failure(ext2_errc::invalid_block_index);
}
- auto filesystem::read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t
+ auto filesystem::read_block_number_at_index(uint32_t block_number, size_t index) const -> kstd::result<uint32_t>
{
uint32_t block_number_buffer = 0;
auto const block_start_offset = block_number * block_size();
auto const number_start_address = block_start_offset + index * sizeof(uint32_t);
- m_backing_inode->read(&block_number_buffer, number_start_address, sizeof(uint32_t));
+ if (auto read_result = m_backing_inode->read(&block_number_buffer, number_start_address, sizeof(uint32_t));
+ !read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
return block_number_buffer;
}
diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp
index 2284d7bf..5e5913bf 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.hpp
@@ -7,9 +7,10 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/unikstd.h>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <array>
#include <cstddef>
@@ -47,14 +48,14 @@ namespace kernel::filesystem::ext2
@brief A filesystem implementation for the ext2 filesystem format. This class provides methods for mounting an ext2
filesystem, and looking up inodes.
*/
- struct filesystem : kernel::filesystem::filesystem
+ struct filesystem final : kernel::filesystem::filesystem
{
/**
@brief Initializes the ext2 filesystem with the given @p backing_inode.
@param backing_inode The backing inode to mount.
@return The result of the mount operation.
*/
- auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result override;
+ auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> kstd::result<void> override;
/**
@brief Looks up an inode by @p name within a @p parent directory.
@@ -63,7 +64,7 @@ namespace kernel::filesystem::ext2
@return A pointer to the found inode, or a null pointer if not found.
*/
[[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
- -> kstd::shared_ptr<kernel::filesystem::inode> override;
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
/**
@brief Gets the size of a block in the filesystem.
@@ -81,10 +82,10 @@ namespace kernel::filesystem::ext2
@brief Maps an inode block index to a global block number.
@param inode_block_index The index of the block within the inode.
@param data The inode data.
- @return The global block number.
+ @return The global block number on success, an error otherwise.
*/
[[nodiscard]] auto map_inode_block_index_to_global_block_number(size_t inode_block_index, inode_data data) const
- -> kstd::ssize_t;
+ -> kstd::result<std::size_t>;
private:
struct indirect_level
@@ -95,8 +96,8 @@ namespace kernel::filesystem::ext2
[[nodiscard]] auto indirect_levels() const -> std::array<indirect_level, 3>;
- [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr<kernel::filesystem::ext2::inode>;
- [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t;
+ [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::result<kstd::shared_ptr<inode>>;
+ [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> kstd::result<uint32_t>;
[[nodiscard]] auto inode_size() const -> uint16_t;
[[nodiscard]] auto inode_block_count(inode_data const & data) const -> uint32_t;
diff --git a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp
index 83410702..1702526e 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp
@@ -2,14 +2,15 @@
#include <kernel/devices/storage/management.hpp>
#include <kernel/filesystem/device_inode.hpp>
+#include <kernel/filesystem/ext2/error.hpp>
#include <kernel/filesystem/ext2/inode.hpp>
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/test_support/devices/block_device.hpp>
#include <kernel/test_support/filesystem/ext2.hpp>
#include <kernel/test_support/filesystem/storage_boot_module_fixture.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -33,7 +34,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture,
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
THEN("the root inode is available and is a directory")
{
@@ -44,25 +45,25 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture,
THEN("lookup resolves known entries from the image")
{
auto information = fs.lookup(fs.root_inode(), "information");
- REQUIRE(information != nullptr);
- REQUIRE(information->is_directory());
+ REQUIRE(information);
+ REQUIRE(information.value()->is_directory());
- auto info_1 = fs.lookup(information, "info_1.txt");
- REQUIRE(info_1 != nullptr);
- REQUIRE(info_1->is_regular());
+ auto info_1 = fs.lookup(*information, "info_1.txt");
+ REQUIRE(info_1);
+ REQUIRE(info_1.value()->is_regular());
}
THEN("lookup returns null for invalid inputs")
{
- REQUIRE(fs.lookup(nullptr, "information") == nullptr);
+ REQUIRE(!fs.lookup(nullptr, "information"));
auto information = fs.lookup(fs.root_inode(), "information");
- REQUIRE(information != nullptr);
- auto info_1 = fs.lookup(information, "info_1.txt");
- REQUIRE(info_1 != nullptr);
+ REQUIRE(information);
+ auto info_1 = fs.lookup(*information, "info_1.txt");
+ REQUIRE(info_1);
- REQUIRE(fs.lookup(info_1, "anything") == nullptr);
- REQUIRE(fs.lookup(fs.root_inode(), "does_not_exist") == nullptr);
+ REQUIRE(!fs.lookup(*info_1, "anything"));
+ REQUIRE(!fs.lookup(fs.root_inode(), "does_not_exist"));
}
}
}
@@ -81,7 +82,7 @@ SCENARIO("Ext2 filesystem rejects invalid magic", "[filesystem][ext2][filesystem
THEN("mount fails with invalid_magic_number")
{
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::invalid_magic_number);
+ REQUIRE(fs.mount(dev_inode).error() == kernel::filesystem::ext2::ext2_errc::invalid_magic_number);
}
}
}
@@ -100,7 +101,7 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
auto inode_data = kernel::filesystem::ext2::inode_data{};
inode_data.block[0] = 7;
@@ -130,10 +131,10 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys
REQUIRE(fs.map_inode_block_index_to_global_block_number(triply_start, inode_data) == 53);
}
- THEN("mapping returns zero for out-of-range indexes")
+ THEN("mapping returns error for out-of-range indexes")
{
auto const beyond_triply = triply_start + numbers_per_block * numbers_per_block * numbers_per_block;
- REQUIRE(fs.map_inode_block_index_to_global_block_number(beyond_triply, inode_data) == -1);
+ REQUIRE(!fs.map_inode_block_index_to_global_block_number(beyond_triply, inode_data));
}
}
}
diff --git a/kernel/kernel/filesystem/ext2/inode.cpp b/kernel/kernel/filesystem/ext2/inode.cpp
index 35a32ee4..6dadbec5 100644
--- a/kernel/kernel/filesystem/ext2/inode.cpp
+++ b/kernel/kernel/filesystem/ext2/inode.cpp
@@ -5,7 +5,8 @@
#include <kapi/system.hpp>
-#include <kstd/cstring>
+#include <kstd/cstring.hpp>
+#include <kstd/result.hpp>
#include <algorithm>
#include <cstddef>
@@ -23,7 +24,7 @@ namespace kernel::filesystem::ext2
}
}
- auto inode::read(void * buffer, size_t offset, size_t size) const -> size_t
+ auto inode::read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t>
{
auto const max_readable = this->size() - offset;
auto const requested_size = std::min(size, max_readable);
@@ -43,7 +44,7 @@ namespace kernel::filesystem::ext2
while (bytes_read < requested_size)
{
auto const block_number = m_filesystem->map_inode_block_index_to_global_block_number(block_index, m_data);
- if (block_number == -1)
+ if (!block_number)
{
break;
}
@@ -56,11 +57,16 @@ namespace kernel::filesystem::ext2
}
else
{
- auto const block_start_offset = block_number * m_filesystem->block_size();
+ auto const block_start_offset = block_number.value() * m_filesystem->block_size();
auto const read_offset = block_start_offset + in_block_offset;
-
- bytes_read += m_filesystem->backing_inode()->read(static_cast<uint8_t *>(buffer) + bytes_read, read_offset,
- bytes_to_read);
+ auto const read_result = m_filesystem->backing_inode()->read(static_cast<uint8_t *>(buffer) + bytes_read,
+ read_offset, bytes_to_read);
+ if (!read_result)
+ {
+ return kstd::failure(read_result.error());
+ }
+
+ bytes_read += read_result.value();
}
block_index++;
@@ -70,7 +76,7 @@ namespace kernel::filesystem::ext2
return bytes_read;
}
- auto inode::write(void const *, size_t, size_t) -> size_t
+ auto inode::write(void const *, size_t, size_t) -> kstd::result<size_t>
{
kapi::system::panic("[EXT2] inode::write is not implemented yet");
return 0;
diff --git a/kernel/kernel/filesystem/ext2/inode.hpp b/kernel/kernel/filesystem/ext2/inode.hpp
index f2496f0f..16cb04e0 100644
--- a/kernel/kernel/filesystem/ext2/inode.hpp
+++ b/kernel/kernel/filesystem/ext2/inode.hpp
@@ -3,7 +3,8 @@
#include <kernel/filesystem/inode.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
#include <array>
#include <cstddef>
@@ -54,7 +55,7 @@ namespace kernel::filesystem::ext2
@param size Number of bytes requested.
@return Number of bytes read.
*/
- auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
+ auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
/**
@brief Writes to the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size.
@@ -64,7 +65,7 @@ namespace kernel::filesystem::ext2
@param size Number of bytes requested.
@return Number of bytes written.
*/
- auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+ auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
/**
@brief Get the data associated with this inode.
diff --git a/kernel/kernel/filesystem/ext2/inode.tests.cpp b/kernel/kernel/filesystem/ext2/inode.tests.cpp
index 4aecc04a..496e7c4f 100644
--- a/kernel/kernel/filesystem/ext2/inode.tests.cpp
+++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp
@@ -10,8 +10,8 @@
#include <kernel/test_support/filesystem/ext2.hpp>
#include <kernel/test_support/filesystem/storage_boot_module_fixture.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -20,6 +20,8 @@
#include <filesystem>
#include <string_view>
+// NOLINTBEGIN(readability-magic-numbers)
+
SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]")
{
GIVEN("an ext2 filesystem")
@@ -97,29 +99,29 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(boot_device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
auto information = fs.lookup(fs.root_inode(), "information");
- REQUIRE(information != nullptr);
- auto file = fs.lookup(information, "info_1.txt");
- REQUIRE(file != nullptr);
- REQUIRE(file->is_regular());
+ REQUIRE(information);
+ auto file = fs.lookup(*information, "info_1.txt");
+ REQUIRE(file);
+ REQUIRE(file.value()->is_regular());
THEN("reading from offset zero returns expected file prefix")
{
auto buffer = kstd::vector<std::byte>(6);
- auto const bytes_read = file->read(buffer.data(), 0, buffer.size());
+ auto const bytes_read = file.value()->read(buffer.data(), 0, buffer.size());
REQUIRE(bytes_read == 6);
- auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
REQUIRE(text == "info_1");
}
THEN("reading with an offset returns the expected byte")
{
auto buffer = kstd::vector<std::byte>(1);
- auto const bytes_read = file->read(buffer.data(), 5, buffer.size());
+ auto const bytes_read = file.value()->read(buffer.data(), 5, buffer.size());
REQUIRE(bytes_read == 1);
REQUIRE(static_cast<char>(buffer[0]) == '1');
@@ -139,7 +141,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
auto data = kernel::filesystem::ext2::inode_data{};
data.block[0] = 30;
@@ -159,7 +161,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
auto const bytes_read = inode.read(buffer.data(), 0, buffer.size());
REQUIRE(bytes_read == data.size);
- auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
REQUIRE(text.substr(0, 5) == "Hello");
REQUIRE(std::ranges::all_of(text.substr(5, block_size - 5), [](char c) { return c == '\0'; }));
REQUIRE(text.substr(2 * block_size, 6) == "World!");
@@ -176,7 +178,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
auto data = kernel::filesystem::ext2::inode_data{};
data.block[0] = 30;
@@ -200,7 +202,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
auto const bytes_read = inode.read(buffer.data(), 0, buffer.size());
REQUIRE(bytes_read == data.size);
- auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
REQUIRE(text.substr(0, 5) == "Hello");
REQUIRE(std::ranges::all_of(text.substr(5, 12 * block_size - 5), [](char c) { return c == '\0'; }));
REQUIRE(text.substr(12 * block_size, 4) == "Blub");
@@ -221,7 +223,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
auto data = kernel::filesystem::ext2::inode_data{};
data.block[12] = 0;
@@ -252,7 +254,7 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]")
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
auto inode_data = kernel::filesystem::ext2::inode_data{};
inode_data.size = block_size * 2;
@@ -269,7 +271,7 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]")
auto const bytes_read = inode.read(buffer.data(), block_size - 6, buffer.size());
REQUIRE(bytes_read == 12);
- auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
REQUIRE(text == "Hello World!");
}
}
@@ -313,7 +315,7 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
auto data = kernel::filesystem::ext2::inode_data{};
data.size = 256;
@@ -349,7 +351,7 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
auto fs = kernel::filesystem::ext2::filesystem{};
- REQUIRE(fs.mount(dev_inode) == kernel::filesystem::filesystem::operation_result::success);
+ REQUIRE(fs.mount(dev_inode));
auto data = kernel::filesystem::ext2::inode_data{};
data.size = 256;
@@ -373,4 +375,6 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev
REQUIRE(inode.size() == 256);
}
}
-} \ No newline at end of file
+}
+
+// NOLINTEND(readability-magic-numbers) \ No newline at end of file
diff --git a/kernel/kernel/filesystem/filesystem.cpp b/kernel/kernel/filesystem/filesystem.cpp
index 24d0e229..ac0d0ebc 100644
--- a/kernel/kernel/filesystem/filesystem.cpp
+++ b/kernel/kernel/filesystem/filesystem.cpp
@@ -1,11 +1,14 @@
#include <kernel/filesystem/filesystem.hpp>
+#include <kernel/filesystem/error.hpp>
#include <kernel/filesystem/ext2/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
#include <kapi/system.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
#include <array>
@@ -18,7 +21,8 @@ namespace kernel::filesystem
};
} // namespace
- auto filesystem::probe_and_mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::shared_ptr<filesystem>
+ auto filesystem::probe_and_mount(kstd::shared_ptr<inode> const & backing_inode)
+ -> kstd::result<kstd::shared_ptr<filesystem>>
{
if (!backing_inode)
{
@@ -28,16 +32,16 @@ namespace kernel::filesystem
for (auto & factory : filesystem_factories)
{
auto fs = factory();
- if (fs->mount(backing_inode) == operation_result::success)
+ if (fs->mount(backing_inode))
{
return fs;
}
}
- return nullptr;
+ return kstd::failure(vfs_errc::unsupported_filesystem);
}
- auto filesystem::mount(kstd::shared_ptr<inode> const & backing_inode) -> operation_result
+ auto filesystem::mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::result<void>
{
if (!backing_inode)
{
@@ -45,7 +49,7 @@ namespace kernel::filesystem
}
m_backing_inode = backing_inode;
- return operation_result::success;
+ return kstd::success();
}
auto filesystem::root_inode() const -> kstd::shared_ptr<inode> const &
diff --git a/kernel/kernel/filesystem/filesystem.hpp b/kernel/kernel/filesystem/filesystem.hpp
index bec1b160..1264d00d 100644
--- a/kernel/kernel/filesystem/filesystem.hpp
+++ b/kernel/kernel/filesystem/filesystem.hpp
@@ -3,8 +3,10 @@
#include <kernel/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <string_view>
@@ -16,14 +18,6 @@ namespace kernel::filesystem
*/
struct filesystem
{
- enum class operation_result : int
- {
- success = 0,
- invalid_magic_number = -1,
- invalid_root_inode = -2,
- unmount_failed = -3
- };
-
/**
@brief Virtual destructor for the filesystem.
*/
@@ -34,19 +28,19 @@ namespace kernel::filesystem
and returns a pointer to the mounted filesystem instance. This method iterates through known filesystem types and
attempts to initialize it with the backing inode until the mount was successful or all types have been tried.
@param backing_inode The inode to probe and mount.
- @return A pointer to the mounted filesystem instance if successful, or a null pointer if no recognizable filesystem
- is found on the backing inode.
+ @return A pointer to the mounted filesystem instance if successful, an error otherwise.
@warning Panics if @p backing_inode is null.
*/
- auto static probe_and_mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::shared_ptr<filesystem>;
+ auto static probe_and_mount(kstd::shared_ptr<inode> const & backing_inode)
+ -> kstd::result<kstd::shared_ptr<filesystem>>;
/**
@brief Initializes the filesystem with the given @p backing_inode.
@param backing_inode The inode to use as the backing inode for the filesystem. (This is typically the inode
representing the block device or another inode which contains the filesystem data.)
- @return The result of the mount operation.
+ @return Nothing on success, and error otherwise.
*/
- virtual auto mount(kstd::shared_ptr<inode> const & backing_inode) -> operation_result;
+ virtual auto mount(kstd::shared_ptr<inode> const & backing_inode) -> kstd::result<void>;
/**
@brief Looks up a child inode within the given @p parent inode with the specified @p name. This method must be
@@ -54,10 +48,10 @@ namespace kernel::filesystem
finding the requested inode.
@param parent The parent inode.
@param name The name of the child inode to look up.
- @return A pointer to the requested child inode, or a null pointer if not found.
+ @return A pointer to the requested child inode, an error otherwise.
*/
[[nodiscard]] virtual auto lookup(kstd::shared_ptr<inode> const & parent, std::string_view name) const
- -> kstd::shared_ptr<inode> = 0;
+ -> kstd::result<kstd::shared_ptr<inode>> = 0;
/**
@brief Returns a reference to the root inode of the filesystem.
diff --git a/kernel/kernel/filesystem/inode.hpp b/kernel/kernel/filesystem/inode.hpp
index b34b921e..cfddebf6 100644
--- a/kernel/kernel/filesystem/inode.hpp
+++ b/kernel/kernel/filesystem/inode.hpp
@@ -1,6 +1,8 @@
#ifndef TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP
#define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP
+#include <kstd/result.hpp>
+
#include <cstddef>
namespace kernel::filesystem
@@ -28,7 +30,7 @@ namespace kernel::filesystem
@param size Number of bytes requested.
@return Number of bytes read.
*/
- virtual auto read(void * buffer, size_t offset, size_t size) const -> size_t = 0;
+ virtual auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> = 0;
/**
@brief Writes to the inode into a @p buffer, starting at the specified @p offset and for a given @p size. This
@@ -38,7 +40,7 @@ namespace kernel::filesystem
@param size Number of bytes to write.
@return Number of bytes written.
*/
- virtual auto write(void const * buffer, size_t offset, size_t size) -> size_t = 0;
+ virtual auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> = 0;
/**
@brief Returns whether the inode is a directory.
diff --git a/kernel/kernel/filesystem/mount.cpp b/kernel/kernel/filesystem/mount.cpp
index ead7479d..009ab230 100644
--- a/kernel/kernel/filesystem/mount.cpp
+++ b/kernel/kernel/filesystem/mount.cpp
@@ -5,8 +5,8 @@
#include <kapi/system.hpp>
-#include <kstd/memory>
-#include <kstd/string>
+#include <kstd/memory.hpp>
+#include <kstd/string.hpp>
#include <cstddef>
#include <string_view>
diff --git a/kernel/kernel/filesystem/mount.hpp b/kernel/kernel/filesystem/mount.hpp
index ced4f814..589094e0 100644
--- a/kernel/kernel/filesystem/mount.hpp
+++ b/kernel/kernel/filesystem/mount.hpp
@@ -4,8 +4,8 @@
#include <kernel/filesystem/dentry.hpp>
#include <kernel/filesystem/filesystem.hpp>
-#include <kstd/memory>
-#include <kstd/string>
+#include <kstd/memory.hpp>
+#include <kstd/string.hpp>
#include <atomic>
#include <cstddef>
diff --git a/kernel/kernel/filesystem/mount.tests.cpp b/kernel/kernel/filesystem/mount.tests.cpp
index c9ff82e9..800a0cfc 100644
--- a/kernel/kernel/filesystem/mount.tests.cpp
+++ b/kernel/kernel/filesystem/mount.tests.cpp
@@ -5,9 +5,9 @@
#include <kernel/test_support/filesystem/filesystem.hpp>
#include <kernel/test_support/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/filesystem/mount_table.cpp b/kernel/kernel/filesystem/mount_table.cpp
index e4baac7a..d3f252b4 100644
--- a/kernel/kernel/filesystem/mount_table.cpp
+++ b/kernel/kernel/filesystem/mount_table.cpp
@@ -3,8 +3,8 @@
#include <kernel/filesystem/dentry.hpp>
#include <kernel/filesystem/mount.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <algorithm>
#include <ranges>
diff --git a/kernel/kernel/filesystem/mount_table.hpp b/kernel/kernel/filesystem/mount_table.hpp
index 4f2d1b7f..46e2a439 100644
--- a/kernel/kernel/filesystem/mount_table.hpp
+++ b/kernel/kernel/filesystem/mount_table.hpp
@@ -3,8 +3,8 @@
#include <kernel/filesystem/mount.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/vector.hpp>
#include <string_view>
diff --git a/kernel/kernel/filesystem/mount_table.tests.cpp b/kernel/kernel/filesystem/mount_table.tests.cpp
index 19b47b23..39ad6b01 100644
--- a/kernel/kernel/filesystem/mount_table.tests.cpp
+++ b/kernel/kernel/filesystem/mount_table.tests.cpp
@@ -5,9 +5,9 @@
#include <kernel/test_support/filesystem/filesystem.hpp>
#include <kernel/test_support/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/filesystem/open_file_descriptor.cpp b/kernel/kernel/filesystem/open_file_descriptor.cpp
index a5567bf4..ecf3e725 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.cpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.cpp
@@ -2,8 +2,9 @@
#include <kernel/filesystem/dentry.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
#include <kstd/os/error.hpp>
+#include <kstd/result.hpp>
#include <cstddef>
@@ -19,18 +20,32 @@ namespace kernel::filesystem
}
}
- auto open_file_descriptor::read(void * buffer, size_t size) -> size_t
+ auto open_file_descriptor::read(void * buffer, size_t size) -> kstd::result<size_t>
{
- auto read_bytes = m_dentry->get_inode()->read(buffer, m_offset, size);
- m_offset += read_bytes;
- return read_bytes;
+ if (auto result = m_dentry->get_inode()->read(buffer, m_offset, size); !result)
+ {
+ return kstd::failure(result.error());
+ }
+ else
+ {
+ auto read_bytes = result.value();
+ m_offset += read_bytes;
+ return read_bytes;
+ }
}
- auto open_file_descriptor::write(void const * buffer, size_t size) -> size_t
+ auto open_file_descriptor::write(void const * buffer, size_t size) -> kstd::result<size_t>
{
- auto written_bytes = m_dentry->get_inode()->write(buffer, m_offset, size);
- m_offset += written_bytes;
- return written_bytes;
+ if (auto result = m_dentry->get_inode()->write(buffer, m_offset, size); !result)
+ {
+ return kstd::failure(result.error());
+ }
+ else
+ {
+ auto written_bytes = result.value();
+ m_offset += written_bytes;
+ return written_bytes;
+ }
}
auto open_file_descriptor::offset() const -> size_t
diff --git a/kernel/kernel/filesystem/open_file_descriptor.hpp b/kernel/kernel/filesystem/open_file_descriptor.hpp
index fd10e646..f6899a31 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.hpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.hpp
@@ -3,7 +3,8 @@
#include <kernel/filesystem/dentry.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
#include <cstddef>
@@ -34,7 +35,7 @@ namespace kernel::filesystem
@param size The number of bytes to read.
@return The number of bytes read.
*/
- auto read(void * buffer, size_t size) -> size_t;
+ auto read(void * buffer, size_t size) -> kstd::result<size_t>;
/**
@brief Writes data to the open file descriptor from a @p buffer, starting at the current file offset and for a
@@ -44,7 +45,7 @@ namespace kernel::filesystem
@param size The number of bytes to write.
@return The number of bytes written.
*/
- auto write(void const * buffer, size_t size) -> size_t;
+ auto write(void const * buffer, size_t size) -> kstd::result<size_t>;
/**
@brief Returns the current file offset for this open file descriptor.
diff --git a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp
index 8c24cf0e..06488ba0 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp
@@ -6,9 +6,9 @@
#include <kernel/test_support/filesystem/inode.hpp>
#include <kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -81,8 +81,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope
auto & vfs = kernel::filesystem::vfs::get();
auto dentry = vfs.open("/information/info_1.txt");
- REQUIRE(dentry != nullptr);
- auto ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry);
+ REQUIRE(dentry);
+ auto ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry.value());
THEN("the file can be read and the offset is updated")
{
@@ -91,7 +91,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope
REQUIRE(bytes_read == 7);
REQUIRE(ofd->offset() == 7);
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), static_cast<size_t>(bytes_read)};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), *bytes_read};
REQUIRE(buffer_as_str == "info_1\n");
}
@@ -106,7 +106,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope
REQUIRE(bytes_read_2 == buffer.size() / 2);
REQUIRE(ofd->offset() == buffer.size());
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), bytes_read_1 + bytes_read_2};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), *bytes_read_1 + *bytes_read_2};
REQUIRE(buffer_as_str == "info");
}
}
diff --git a/kernel/kernel/filesystem/open_file_table.cpp b/kernel/kernel/filesystem/open_file_table.cpp
index 2afe3aa4..dea504e4 100644
--- a/kernel/kernel/filesystem/open_file_table.cpp
+++ b/kernel/kernel/filesystem/open_file_table.cpp
@@ -1,11 +1,13 @@
#include <kernel/filesystem/open_file_table.hpp>
+#include <kernel/filesystem/error.hpp>
#include <kernel/filesystem/open_file_descriptor.hpp>
#include <kapi/system.hpp>
-#include <kstd/memory>
-#include <kstd/unikstd.h>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
#include <algorithm>
#include <cstddef>
@@ -38,11 +40,12 @@ namespace kernel::filesystem
return *global_open_file_table;
}
- auto open_file_table::add_file(kstd::shared_ptr<open_file_descriptor> const & file_descriptor) -> kstd::ssize_t
+ auto open_file_table::add_file(kstd::shared_ptr<open_file_descriptor> const & file_descriptor)
+ -> kstd::result<std::size_t>
{
if (!file_descriptor)
{
- return -1;
+ return kstd::failure(vfs_errc::invalid_file_descriptor);
}
auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; });
@@ -56,25 +59,25 @@ namespace kernel::filesystem
return m_open_files.size() - 1;
}
- auto open_file_table::file(size_t fd) const -> kstd::shared_ptr<open_file_descriptor>
+ auto open_file_table::file(size_t fd) const -> kstd::result<kstd::shared_ptr<open_file_descriptor>>
{
- if (fd >= m_open_files.size())
+ if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr)
{
- return nullptr;
+ return kstd::failure(vfs_errc::invalid_file_descriptor);
}
- return m_open_files.at(fd);
+ return kstd::success(m_open_files.at(fd));
}
- auto open_file_table::remove_file(size_t fd) -> kstd::ssize_t
+ auto open_file_table::remove_file(size_t fd) -> kstd::result<void>
{
- if (fd >= m_open_files.size())
+ if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr)
{
- return -1;
+ return kstd::failure(vfs_errc::invalid_file_descriptor);
}
m_open_files.at(fd) = nullptr;
- return 0;
+ return kstd::success();
}
} // namespace kernel::filesystem
diff --git a/kernel/kernel/filesystem/open_file_table.hpp b/kernel/kernel/filesystem/open_file_table.hpp
index 7e754ac1..7c9a0c0c 100644
--- a/kernel/kernel/filesystem/open_file_table.hpp
+++ b/kernel/kernel/filesystem/open_file_table.hpp
@@ -3,9 +3,10 @@
#include <kernel/filesystem/open_file_descriptor.hpp>
-#include <kstd/memory>
-#include <kstd/unikstd.h>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <cstddef>
@@ -40,21 +41,21 @@ namespace kernel::filesystem
@param fd The file descriptor to add.
@return The file descriptor index assigned to the file, or -1 on failure.
*/
- auto add_file(kstd::shared_ptr<open_file_descriptor> const & fd) -> kstd::ssize_t;
+ auto add_file(kstd::shared_ptr<open_file_descriptor> const & fd) -> kstd::result<std::size_t>;
/**
@brief Get a file from the open file table.
@param fd The file descriptor index to retrieve.
@return A pointer to the requested file descriptor, or a null pointer if not found.
*/
- [[nodiscard]] auto file(size_t fd) const -> kstd::shared_ptr<open_file_descriptor>;
+ [[nodiscard]] auto file(size_t fd) const -> kstd::result<kstd::shared_ptr<open_file_descriptor>>;
/**
@brief Remove a file from the open file table.
@param fd The file descriptor index to remove.
@return 0 on success, or -1 on failure.
*/
- auto remove_file(size_t fd) -> kstd::ssize_t;
+ auto remove_file(size_t fd) -> kstd::result<void>;
private:
open_file_table() = default;
diff --git a/kernel/kernel/filesystem/open_file_table.tests.cpp b/kernel/kernel/filesystem/open_file_table.tests.cpp
index 3e91111d..69188528 100644
--- a/kernel/kernel/filesystem/open_file_table.tests.cpp
+++ b/kernel/kernel/filesystem/open_file_table.tests.cpp
@@ -4,9 +4,10 @@
#include <kernel/filesystem/open_file_descriptor.hpp>
#include <kernel/test_support/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -36,7 +37,7 @@ SCENARIO("Open file table add/get file", "[filesystem][open_file_table]")
THEN("the file descriptor can be retrieved using the returned file descriptor")
{
- auto retrieved_descriptor = table.file(fd_1);
+ auto retrieved_descriptor = table.file(*fd_1);
REQUIRE(retrieved_descriptor == file_descriptor_1);
}
}
@@ -46,16 +47,16 @@ SCENARIO("Open file table add/get file", "[filesystem][open_file_table]")
{
auto & table = kernel::filesystem::open_file_table::get();
- THEN("adding a null file descriptor returns an error code")
+ THEN("adding a null file descriptor returns an error")
{
auto fd = table.add_file(nullptr);
- REQUIRE(fd == -1);
+ REQUIRE(fd.error() == kstd::errc::bad_file_descriptor);
}
- THEN("retrieving a file descriptor with an out-of-bounds file descriptor returns a null pointer")
+ THEN("retrieving a file descriptor with an out-of-bounds file descriptor returns an error")
{
auto retrieved_descriptor = table.file(1000);
- REQUIRE(retrieved_descriptor == nullptr);
+ REQUIRE(retrieved_descriptor.error() == kstd::errc::bad_file_descriptor);
}
}
}
@@ -72,23 +73,23 @@ SCENARIO("Open file table remove file", "[filesystem][open_file_table]")
WHEN("removing the file descriptor using the file descriptor")
{
- table.remove_file(fd);
+ CHECK(table.remove_file(*fd));
THEN("the file descriptor can no longer be retrieved using the file descriptor")
{
- auto retrieved_descriptor = table.file(fd);
- REQUIRE(retrieved_descriptor == nullptr);
+ auto retrieved_descriptor = table.file(*fd);
+ REQUIRE(retrieved_descriptor.error() == kstd::errc::bad_file_descriptor);
}
}
WHEN("removing a file descriptor the other file descriptor keep the same index")
{
auto fd2 = table.add_file(file_descriptor);
- table.remove_file(fd);
+ CHECK(table.remove_file(*fd));
THEN("the second file descriptor can still be retrieved using its file descriptor")
{
- auto retrieved_descriptor = table.file(fd2);
+ auto retrieved_descriptor = table.file(*fd2);
REQUIRE(retrieved_descriptor == file_descriptor);
}
}
diff --git a/kernel/kernel/filesystem/path.hpp b/kernel/kernel/filesystem/path.hpp
index 4845bf1a..438c22f3 100644
--- a/kernel/kernel/filesystem/path.hpp
+++ b/kernel/kernel/filesystem/path.hpp
@@ -3,7 +3,7 @@
#include <kernel/filesystem/constants.hpp>
-#include <kstd/string>
+#include <kstd/string.hpp>
#include <ranges>
#include <string_view>
diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp
index 7fe5c1ea..fef43e28 100644
--- a/kernel/kernel/filesystem/rootfs/filesystem.cpp
+++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp
@@ -1,11 +1,14 @@
#include <kernel/filesystem/rootfs/filesystem.hpp>
+#include <kernel/filesystem/error.hpp>
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
#include <kernel/filesystem/rootfs/inode.hpp>
#include <kernel/filesystem/type.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
#include <string_view>
@@ -33,15 +36,15 @@ namespace kernel::filesystem::rootfs
[[gnu::used]]
constexpr auto registration = type_registration<type>{};
- auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> operation_result
+ auto filesystem::mount(kstd::shared_ptr<kernel::filesystem::inode> const &) -> kstd::result<void>
{
m_root_inode = kstd::make_shared<inode>();
- return operation_result::success;
+ return kstd::success();
}
auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const &, std::string_view) const
- -> kstd::shared_ptr<kernel::filesystem::inode>
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>>
{
- return nullptr;
+ return kstd::failure(vfs_errc::no_such_file_or_directory);
}
} // namespace kernel::filesystem::rootfs
diff --git a/kernel/kernel/filesystem/rootfs/filesystem.hpp b/kernel/kernel/filesystem/rootfs/filesystem.hpp
index 3c2dcb1c..8507d8b8 100644
--- a/kernel/kernel/filesystem/rootfs/filesystem.hpp
+++ b/kernel/kernel/filesystem/rootfs/filesystem.hpp
@@ -4,9 +4,11 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/string>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/string.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <string_view>
@@ -25,7 +27,7 @@ namespace kernel::filesystem::rootfs
@param backing_inode The backing inode to mount (not required by rootfs).
@return The result of the mount operation.
*/
- auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> operation_result override;
+ auto mount(kstd::shared_ptr<kernel::filesystem::inode> const & backing_inode) -> kstd::result<void> override;
/**
@brief Looks up an inode by @p name within a @p parent directory.
@@ -34,7 +36,7 @@ namespace kernel::filesystem::rootfs
@return Always returns nullptr.
*/
[[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
- -> kstd::shared_ptr<kernel::filesystem::inode> override;
+ -> kstd::result<kstd::shared_ptr<kernel::filesystem::inode>> override;
};
} // namespace kernel::filesystem::rootfs
diff --git a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp
index ae320e95..347502ca 100644
--- a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp
+++ b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp
@@ -2,9 +2,9 @@
#include <kernel/filesystem/filesystem.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -17,22 +17,22 @@ SCENARIO("Rootfs filesystem mount and lookup", "[filesystem][rootfs][filesystem]
THEN("the filesystem can be mounted successfully")
{
- REQUIRE(result == kernel::filesystem::filesystem::operation_result::success);
- REQUIRE(fs.root_inode() != nullptr);
+ REQUIRE(result);
+ REQUIRE(fs.root_inode());
}
- THEN("looking up a non-existent directory returns null")
+ THEN("looking up a non-existent directory returns an error")
{
auto non_existent_inode_1 = fs.lookup(fs.root_inode(), "");
- REQUIRE(non_existent_inode_1 == nullptr);
+ REQUIRE(!non_existent_inode_1);
auto non_existent_inode_2 = fs.lookup(fs.root_inode(), "nonexistent");
- REQUIRE(non_existent_inode_2 == nullptr);
+ REQUIRE(!non_existent_inode_2);
}
- THEN("looking up with a null parent inode returns null")
+ THEN("looking up with a null parent inode returns an error")
{
auto result = fs.lookup(nullptr, "dev");
- REQUIRE(result == nullptr);
+ REQUIRE(!result);
}
}
}
diff --git a/kernel/kernel/filesystem/rootfs/inode.cpp b/kernel/kernel/filesystem/rootfs/inode.cpp
index f64fb87c..e3e9d641 100644
--- a/kernel/kernel/filesystem/rootfs/inode.cpp
+++ b/kernel/kernel/filesystem/rootfs/inode.cpp
@@ -2,16 +2,18 @@
#include <kernel/filesystem/rootfs/inode.hpp>
+#include <kstd/result.hpp>
+
#include <cstddef>
namespace kernel::filesystem::rootfs
{
- auto inode::read(void *, size_t, size_t) const -> size_t
+ auto inode::read(void *, size_t, size_t) const -> kstd::result<size_t>
{
return 0;
}
- auto inode::write(void const *, size_t, size_t) -> size_t
+ auto inode::write(void const *, size_t, size_t) -> kstd::result<size_t>
{
return 0;
}
diff --git a/kernel/kernel/filesystem/rootfs/inode.hpp b/kernel/kernel/filesystem/rootfs/inode.hpp
index 0f21eaa0..777f13f9 100644
--- a/kernel/kernel/filesystem/rootfs/inode.hpp
+++ b/kernel/kernel/filesystem/rootfs/inode.hpp
@@ -3,9 +3,10 @@
#include <kernel/filesystem/inode.hpp>
-#include <kstd/memory>
-#include <kstd/string>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/string.hpp>
+#include <kstd/vector.hpp>
#include <cstddef>
@@ -23,7 +24,7 @@ namespace kernel::filesystem::rootfs
@param size Number of bytes requested.
@return Number of bytes read (always 0 because this inode does not expose file data).
*/
- auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
+ auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
/**
@brief Writes to the rootfs directory inode.
@@ -32,7 +33,7 @@ namespace kernel::filesystem::rootfs
@param size Number of bytes requested.
@return Number of bytes written (always 0 because writes are not supported for this inode).
*/
- auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+ auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
/**
@brief Check if this inode represents a directory.
diff --git a/kernel/kernel/filesystem/rootfs/inode.tests.cpp b/kernel/kernel/filesystem/rootfs/inode.tests.cpp
index f4b634fa..0b48ca71 100644
--- a/kernel/kernel/filesystem/rootfs/inode.tests.cpp
+++ b/kernel/kernel/filesystem/rootfs/inode.tests.cpp
@@ -1,8 +1,8 @@
#include <kernel/filesystem/rootfs/inode.hpp>
-#include <kstd/memory>
-#include <kstd/print>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/filesystem/type.hpp b/kernel/kernel/filesystem/type.hpp
index 0948e549..ebf43176 100644
--- a/kernel/kernel/filesystem/type.hpp
+++ b/kernel/kernel/filesystem/type.hpp
@@ -3,7 +3,7 @@
#include <kernel/filesystem/filesystem.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
#include <string_view>
diff --git a/kernel/kernel/filesystem/type_registry.cpp b/kernel/kernel/filesystem/type_registry.cpp
index 74b12090..6850090a 100644
--- a/kernel/kernel/filesystem/type_registry.cpp
+++ b/kernel/kernel/filesystem/type_registry.cpp
@@ -2,8 +2,8 @@
#include <kapi/system.hpp>
-#include <kstd/memory>
-#include <kstd/print>
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kernel/filesystem/type_registry.hpp b/kernel/kernel/filesystem/type_registry.hpp
index 3be72950..bda2326b 100644
--- a/kernel/kernel/filesystem/type_registry.hpp
+++ b/kernel/kernel/filesystem/type_registry.hpp
@@ -3,9 +3,9 @@
#include <kernel/filesystem/type.hpp>
-#include <kstd/flat_map>
-#include <kstd/memory>
-#include <kstd/string>
+#include <kstd/flat_map.hpp>
+#include <kstd/memory.hpp>
+#include <kstd/string.hpp>
#include <cstddef>
#include <span>
diff --git a/kernel/kernel/filesystem/type_registry.tests.cpp b/kernel/kernel/filesystem/type_registry.tests.cpp
index 8382579f..dbd3cdfd 100644
--- a/kernel/kernel/filesystem/type_registry.tests.cpp
+++ b/kernel/kernel/filesystem/type_registry.tests.cpp
@@ -3,7 +3,7 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/type.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp
index e5dff8c4..d128bbf5 100644
--- a/kernel/kernel/filesystem/vfs.cpp
+++ b/kernel/kernel/filesystem/vfs.cpp
@@ -3,6 +3,7 @@
#include <kernel/filesystem/constants.hpp>
#include <kernel/filesystem/dentry.hpp>
#include <kernel/filesystem/devfs/filesystem.hpp>
+#include <kernel/filesystem/error.hpp>
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/mount.hpp>
#include <kernel/filesystem/mount_table.hpp>
@@ -11,11 +12,14 @@
#include <kapi/system.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <algorithm>
#include <cstdint>
+#include <expected>
#include <optional>
#include <ranges>
#include <string_view>
@@ -42,26 +46,33 @@ namespace kernel::filesystem
{
// mount rootfs at /
auto root_fs = kstd::make_shared<rootfs::filesystem>();
- root_fs->mount(nullptr);
+ if (auto result = root_fs->mount(nullptr); !result)
+ {
+ kapi::system::panic("[FILESYSTEM] failed to mount root FS", result.error());
+ }
auto root_fs_root_dentry = kstd::make_shared<dentry>(nullptr, root_fs->root_inode(), "/");
- auto root_mount = kstd::make_shared<mount>(nullptr, root_fs_root_dentry, root_fs, nullptr, nullptr);
+ auto root_mount = kstd::make_shared<struct mount>(nullptr, root_fs_root_dentry, root_fs, nullptr, nullptr);
m_mount_table.add_mount(root_mount);
// mount devfs at /dev (inside rootfs, temporary, will be shadowed)
auto device_fs = kstd::make_shared<devfs::filesystem>();
- device_fs->mount(nullptr);
+ if (auto result = device_fs->mount(nullptr); !result)
+ {
+ kapi::system::panic("[FILESYSTEM] failed to mount device FS", result.error());
+ }
graft_persistent_device_fs(device_fs);
// mount boot fs at / (shadows rootfs), re-graft devfs
- auto [boot_device_dentry, boot_device_mount_context] = resolve_path_internal("/dev/ram0");
+ auto [boot_device_dentry, boot_device_mount_context] =
+ resolve_path_internal("/dev/ram0").value_or(std::pair{nullptr, nullptr});
if (boot_device_dentry && boot_device_mount_context)
{
if (auto boot_root_fs = kernel::filesystem::filesystem::probe_and_mount(boot_device_dentry->get_inode()))
{
if (auto root_dentry = resolve_path("/"))
{
- do_mount_internal(root_dentry, root_mount, boot_root_fs, boot_device_mount_context);
+ do_mount_internal(*root_dentry, root_mount, *boot_root_fs, boot_device_mount_context);
graft_persistent_device_fs(device_fs);
}
}
@@ -78,85 +89,100 @@ namespace kernel::filesystem
return *active_vfs;
}
- auto vfs::open(std::string_view path) -> kstd::shared_ptr<dentry>
+ auto vfs::open(std::string_view path) -> kstd::result<dentry_ptr>
{
- auto [dentry, mount] = resolve_path_internal(path);
- if (!dentry || !mount)
+ auto resolved_path = resolve_path_internal(path);
+ if (!resolved_path)
{
- return nullptr;
+ return kstd::failure(resolved_path.error());
}
+
+ auto [dentry, mount] = resolved_path.value();
mount->increment_ref_count();
return dentry;
}
- auto vfs::close(std::string_view path) -> operation_result
+ auto vfs::close(std::string_view path) -> kstd::result<void>
{
if (auto mount = find_mount(path))
{
- mount->decrement_ref_count();
- return operation_result::success;
+ mount.value()->decrement_ref_count();
+ return kstd::success();
}
- return operation_result::invalid_path;
+ return kstd::failure(vfs_errc::invalid_path);
}
- auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result
+ auto vfs::mount(std::string_view source, std::string_view target) -> kstd::result<void>
{
if (!path::is_valid_path(source) || !path::is_valid_path(target))
{
- return operation_result::invalid_path;
+ return kstd::failure(vfs_errc::invalid_path);
}
- auto [mount_point_dentry, mount_context] = resolve_path_internal(target);
- if (mount_point_dentry && mount_context)
+ auto resolved_target = resolve_path_internal(target);
+ if (!resolved_target)
{
- auto [source_dentry, source_mount_context] = resolve_path_internal(source);
- if (source_dentry && source_mount_context)
- {
- if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode()))
- {
- do_mount_internal(mount_point_dentry, mount_context, fs, source_mount_context);
- return operation_result::success;
- }
- return operation_result::invalid_filesystem;
- }
- return operation_result::non_existent_path;
+ return kstd::failure(resolved_target.error());
+ }
+ auto [mount_point_dentry, mount_context] = *resolved_target;
+
+ auto resolved_source = resolve_path_internal(source);
+ if (!resolved_source)
+ {
+ return kstd::failure(resolved_source.error());
+ }
+ auto [source_dentry, source_mount_context] = *resolved_source;
+
+ auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode());
+ if (!fs)
+ {
+ return kstd::failure(fs.error());
}
- return operation_result::mount_point_not_found;
+
+ do_mount_internal(mount_point_dentry, mount_context, *fs, source_mount_context);
+ return kstd::success();
}
- auto vfs::unmount(std::string_view path) -> operation_result
+ auto vfs::unmount(std::string_view path) -> kstd::result<void>
{
if (!path::is_valid_path(path))
{
- return operation_result::invalid_path;
+ return kstd::failure(vfs_errc::invalid_path);
}
auto remove_result = m_mount_table.remove_mount(path);
if (remove_result == mount_table::operation_result::removed)
{
- return operation_result::success;
+ return kstd::success();
}
else if (remove_result == mount_table::operation_result::mount_not_found)
{
- return operation_result::mount_point_not_found;
+ return kstd::failure(vfs_errc::mount_point_not_found);
+ }
+ else if (remove_result == mount_table::operation_result::cannot_be_unmounted)
+ {
+ return kstd::failure(vfs_errc::mount_busy);
+ }
+ else if (remove_result == mount_table::operation_result::has_child_mounts)
+ {
+ return kstd::failure(vfs_errc::has_child_mounts);
}
- return operation_result::unmount_failed;
+ return kstd::failure(vfs_errc::unmount_failed);
}
- auto vfs::do_mount_internal(kstd::shared_ptr<dentry> const & mount_point_dentry,
- kstd::shared_ptr<mount> const & parent_mount, kstd::shared_ptr<filesystem> const & fs,
- kstd::shared_ptr<mount> const & source_mount) -> void
+ auto vfs::do_mount_internal(dentry_ptr const & mount_point_dentry, mount_ptr const & parent_mount, fs_ptr const & fs,
+ mount_ptr const & source_mount) -> void
{
auto new_fs_root =
kstd::make_shared<dentry>(mount_point_dentry->parent(), fs->root_inode(), mount_point_dentry->name());
- auto new_mount = kstd::make_shared<mount>(mount_point_dentry, new_fs_root, fs, parent_mount, source_mount);
+ auto new_mount = kstd::make_shared<struct mount>(mount_point_dentry, new_fs_root, fs, parent_mount, source_mount);
m_mount_table.add_mount(new_mount);
}
auto vfs::graft_persistent_device_fs(kstd::shared_ptr<devfs::filesystem> const & device_fs) -> void
{
- auto [root_mount_point_dentry, root_mount] = resolve_path_internal("/");
+ auto [root_mount_point_dentry, root_mount] = resolve_path_internal("/").value_or(std::pair{nullptr, nullptr});
if (root_mount_point_dentry && root_mount)
{
auto dev_dentry = root_mount_point_dentry->find_child("dev");
@@ -170,12 +196,11 @@ namespace kernel::filesystem
}
}
- auto vfs::resolve_path_internal(std::string_view path) const
- -> std::pair<kstd::shared_ptr<dentry>, kstd::shared_ptr<mount>>
+ auto vfs::resolve_path_internal(std::string_view path) const -> kstd::result<std::pair<dentry_ptr, mount_ptr>>
{
if (!path::is_valid_absolute_path(path))
{
- return {nullptr, nullptr};
+ return kstd::failure(vfs_errc::invalid_path);
}
auto current_mount = m_mount_table.find_mount("/");
@@ -197,6 +222,11 @@ namespace kernel::filesystem
auto part = path_parts_vector.back();
path_parts_vector.pop_back();
+ if (!current_dentry->get_inode()->is_directory())
+ {
+ return kstd::failure(vfs_errc::not_a_directory);
+ }
+
if (part == ".")
{
continue;
@@ -231,10 +261,10 @@ namespace kernel::filesystem
auto found_inode = current_fs->lookup(current_dentry->get_inode(), part);
if (!found_inode)
{
- return {nullptr, nullptr};
+ return kstd::failure(found_inode.error());
}
- next_dentry = kstd::make_shared<dentry>(current_dentry, found_inode, part);
+ next_dentry = kstd::make_shared<dentry>(current_dentry, *found_inode, part);
current_dentry->add_child(next_dentry);
}
else if (next_dentry->has_flag(dentry::dentry_flags::is_mount_point))
@@ -252,12 +282,17 @@ namespace kernel::filesystem
{
if (symlink_counter++ > constants::symloop_max)
{
- return {nullptr, nullptr};
+ return kstd::failure(vfs_errc::too_many_symbolic_link_levels);
}
kstd::vector<uint8_t> buffer(constants::symlink_max_path_length);
auto const bytes_read = next_dentry->get_inode()->read(buffer.data(), 0, buffer.size());
- auto const symbolic_link_path = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read};
+ if (!bytes_read)
+ {
+ return kstd::failure(bytes_read.error());
+ }
+
+ auto const symbolic_link_path = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
auto symbolic_link_parts = path::split(symbolic_link_path);
kstd::vector symbolic_link_parts_vector(symbolic_link_parts.begin(), symbolic_link_parts.end());
@@ -275,17 +310,17 @@ namespace kernel::filesystem
current_dentry = next_dentry;
}
- return {current_dentry, current_mount};
+ return std::pair{current_dentry, current_mount};
}
- auto vfs::resolve_path(std::string_view path) const -> kstd::shared_ptr<dentry>
+ auto vfs::resolve_path(std::string_view path) const -> kstd::result<dentry_ptr>
{
- return resolve_path_internal(path).first;
+ return resolve_path_internal(path).transform([](auto result) { return result.first; });
}
- auto vfs::find_mount(std::string_view path) const -> kstd::shared_ptr<mount>
+ auto vfs::find_mount(std::string_view path) const -> kstd::result<mount_ptr>
{
- return resolve_path_internal(path).second;
+ return resolve_path_internal(path).transform([](auto result) { return result.second; });
}
} // namespace kernel::filesystem
diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp
index ddc9a9bc..9dfd3637 100644
--- a/kernel/kernel/filesystem/vfs.hpp
+++ b/kernel/kernel/filesystem/vfs.hpp
@@ -7,7 +7,9 @@
#include <kernel/filesystem/mount.hpp>
#include <kernel/filesystem/mount_table.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/system_error.hpp>
#include <string_view>
#include <utility>
@@ -17,23 +19,14 @@ namespace kernel::filesystem
/**
@brief The virtual filesystem (VFS) is responsible for managing mounted filesystems and providing a unified interface
for file operations across different filesystem types. The VFS maintains a mount table to keep track of mounted
- filesystems and their associated mount points. It provides methods for opening files by path, which involvesresolving
+ filesystems and their associated mount points. It provides methods for opening files by path, which involves resolving
the path to the appropriate mounted filesystem and delegating the file operation to that filesystem's implementation.
*/
struct vfs
{
- /**
- @brief Results for VFS operations.
- */
- enum class operation_result : int
- {
- success = 0,
- invalid_path = -1,
- non_existent_path = -2,
- mount_point_not_found = -3,
- unmount_failed = -4,
- invalid_filesystem = -5
- };
+ using dentry_ptr = kstd::shared_ptr<dentry>;
+ using mount_ptr = kstd::shared_ptr<struct mount>;
+ using fs_ptr = kstd::shared_ptr<filesystem>;
vfs();
@@ -58,31 +51,31 @@ namespace kernel::filesystem
/**
@brief Open a file by its @p path. This method resolves the path and returns the corresponding dentry.
@param path The path to the file to open.
- @return A shared pointer to the dentry or a null pointer if the file could not be opened.
+ @return A shared pointer to the dentry on success or an error code on failure.
*/
- auto open(std::string_view path) -> kstd::shared_ptr<dentry>;
+ auto open(std::string_view path) -> kstd::result<dentry_ptr>;
/**
@brief Close a file by its associated @p path.
@param path The path to the file to close.
- @return The result of the close operation.
+ @return Nothing on success or an error code on failure.
*/
- auto close(std::string_view path) -> operation_result;
+ auto close(std::string_view path) -> kstd::result<void>;
/**
@brief Mount a @p source path to a specific @p target path.
@param source The source of the filesystem to mount.
@param target The path where the filesystem should be mounted.
- @return The result of the mount operation.
+ @return Nothing on success or an error code on failure.
*/
- auto do_mount(std::string_view source, std::string_view target) -> operation_result;
+ auto mount(std::string_view source, std::string_view target) -> kstd::result<void>;
/**
@brief Unmount the filesystem mounted at the specified @p path.
@param path The path where the filesystem is mounted.
- @return The result of the unmount operation.
+ @return Nothing on success or an error code on failure.
*/
- auto unmount(std::string_view path) -> operation_result;
+ auto unmount(std::string_view path) -> kstd::result<void>;
private:
/**
@@ -96,13 +89,14 @@ namespace kernel::filesystem
* - find_mount() for the mount context only.
*/
[[nodiscard]] auto resolve_path_internal(std::string_view path) const
- -> std::pair<kstd::shared_ptr<dentry>, kstd::shared_ptr<mount>>;
- [[nodiscard]] auto resolve_path(std::string_view path) const -> kstd::shared_ptr<dentry>;
- [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr<mount>;
+ -> kstd::result<std::pair<dentry_ptr, mount_ptr>>;
+
+ [[nodiscard]] auto resolve_path(std::string_view path) const -> kstd::result<dentry_ptr>;
+
+ [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::result<mount_ptr>;
- auto do_mount_internal(kstd::shared_ptr<dentry> const & mount_point_dentry,
- kstd::shared_ptr<mount> const & parent_mount, kstd::shared_ptr<filesystem> const & fs,
- kstd::shared_ptr<mount> const & source_mount = nullptr) -> void;
+ auto do_mount_internal(dentry_ptr const & mount_point_dentry, mount_ptr const & parent_mount, fs_ptr const & fs,
+ mount_ptr const & source_mount = nullptr) -> void;
auto graft_persistent_device_fs(kstd::shared_ptr<devfs::filesystem> const & device_fs) -> void;
diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp
index f1d0df0d..c99cea90 100644
--- a/kernel/kernel/filesystem/vfs.tests.cpp
+++ b/kernel/kernel/filesystem/vfs.tests.cpp
@@ -1,10 +1,12 @@
#include <kernel/filesystem/vfs.hpp>
+#include <kernel/filesystem/error.hpp>
#include <kernel/filesystem/open_file_descriptor.hpp>
#include <kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp>
-#include <kstd/memory>
-#include <kstd/vector>
+#include <kstd/memory.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -73,7 +75,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
auto & vfs = kernel::filesystem::vfs::get();
auto image_1 = vfs.open("/dev/image_1.txt");
- REQUIRE(image_1 == nullptr);
+ REQUIRE(image_1.error() == kstd::errc::no_such_file_or_directory);
auto dev = vfs.open("/dev/ram0");
REQUIRE(dev != nullptr);
@@ -102,15 +104,15 @@ 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("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram16", "/information"));
auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt");
- REQUIRE(mounted_monkey_1 != nullptr);
- REQUIRE(vfs.close(mounted_monkey_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(mounted_monkey_1);
+ REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path()));
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/information"));
auto unmounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt");
- REQUIRE(unmounted_monkey_1 == nullptr);
+ REQUIRE(unmounted_monkey_1.error() == kstd::errc::no_such_file_or_directory);
auto info_1 = vfs.open("/information/info_1.txt");
REQUIRE(info_1 != nullptr);
@@ -118,70 +120,68 @@ 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("/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);
+ REQUIRE(vfs.mount("/dev/ram16", "/information"));
+ REQUIRE(vfs.mount("/dev/ram32", "/information/monkey_house/infrastructure"));
auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt");
auto mounted_fish1 = vfs.open("/information/monkey_house/infrastructure/enclosures/aquarium/tank_1/fish_1.txt");
- REQUIRE(mounted_monkey_1 != nullptr);
- REQUIRE(mounted_fish1 != nullptr);
+ REQUIRE(mounted_monkey_1);
+ REQUIRE(mounted_fish1);
- REQUIRE(vfs.close(mounted_monkey_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.close(mounted_fish1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path()));
+ REQUIRE(vfs.close(mounted_fish1.value()->absolute_path()));
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed);
- REQUIRE(vfs.unmount("/information/monkey_house/infrastructure") ==
- kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(!vfs.unmount("/information"));
+ REQUIRE(vfs.unmount("/information/monkey_house/infrastructure"));
+ REQUIRE(vfs.unmount("/information"));
}
THEN("image can be mounted, unmount only if no files are open")
{
- REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram16", "/information"));
auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt");
- REQUIRE(mounted_monkey_1 != nullptr);
+ REQUIRE(mounted_monkey_1);
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed);
+ REQUIRE(!vfs.unmount("/information"));
- REQUIRE(vfs.close(mounted_monkey_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path()));
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/information"));
}
THEN("file with invalid path or not opened file cannot be closed")
{
- REQUIRE(vfs.close("invalid_path") == kernel::filesystem::vfs::operation_result::invalid_path);
+ REQUIRE(!vfs.close("invalid_path"));
REQUIRE_THROWS_AS(vfs.close("/information/info_1.txt"), std::runtime_error);
}
THEN("file cannot be closed twice")
{
auto info_1 = vfs.open("/information/info_1.txt");
- REQUIRE(info_1 != nullptr);
+ REQUIRE(info_1);
- REQUIRE(vfs.close(info_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
- REQUIRE_THROWS_AS(vfs.close(info_1->absolute_path()), std::runtime_error);
+ REQUIRE(vfs.close(info_1.value()->absolute_path()));
+ REQUIRE_THROWS_AS(vfs.close(info_1.value()->absolute_path()), std::runtime_error);
}
THEN("images can be stacked mounted and correct file system is unmounted again")
{
- 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);
+ REQUIRE(vfs.mount("/dev/ram16", "/information"));
+ REQUIRE(vfs.mount("/dev/ram32", "/information"));
auto mounted_tickets = vfs.open("/information/entrance/tickets.txt");
- REQUIRE(mounted_tickets != nullptr);
+ REQUIRE(mounted_tickets);
- REQUIRE(vfs.close(mounted_tickets->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(mounted_tickets.value()->absolute_path()));
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/information"));
mounted_tickets = vfs.open("/information/entrance/tickets.txt");
- REQUIRE(mounted_tickets == nullptr);
+ REQUIRE(mounted_tickets.error() == kstd::errc::no_such_file_or_directory);
auto mounted_monkey = vfs.open("/information/monkey_house/monkey_1.txt");
- REQUIRE(mounted_monkey != nullptr);
+ REQUIRE(mounted_monkey);
}
THEN("image can be mounted on / file opened and unmounted again")
@@ -189,17 +189,17 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
auto info_1 = vfs.open("/information/info_1.txt");
REQUIRE(info_1 != nullptr);
- REQUIRE(vfs.do_mount("/dev/ram16", "/") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram16", "/"));
info_1 = vfs.open("/information/info_1.txt");
- REQUIRE(info_1 == nullptr);
+ REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory);
auto water = vfs.open("/monkey_house/infrastructure/water.txt");
REQUIRE(water != nullptr);
- REQUIRE(vfs.close(water->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(water.value()->absolute_path()));
- REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/"));
info_1 = vfs.open("/information/info_1.txt");
REQUIRE(info_1 != nullptr);
@@ -210,22 +210,22 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
auto info_1 = vfs.open("/information/info_1.txt");
REQUIRE(info_1 != nullptr);
- REQUIRE(vfs.do_mount("/dev/ram16", "/") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram16", "/"));
info_1 = vfs.open("/information/info_1.txt");
- REQUIRE(info_1 == nullptr);
+ REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory);
auto water = vfs.open("/monkey_house/infrastructure/water.txt");
REQUIRE(water != nullptr);
- REQUIRE(vfs.close(water->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(water.value()->absolute_path()));
auto dev_ram_16 = vfs.open("/dev/ram16");
- REQUIRE(dev_ram_16 == nullptr);
+ REQUIRE(dev_ram_16.error() == kstd::errc::no_such_file_or_directory);
- REQUIRE(vfs.do_mount("/dev/ram32", "/") == kernel::filesystem::vfs::operation_result::non_existent_path);
+ REQUIRE(vfs.mount("/dev/ram32", "/").error() == kstd::errc::no_such_file_or_directory);
- REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/"));
auto dev_ram_32 = vfs.open("/dev/ram32");
REQUIRE(dev_ram_32 != nullptr);
@@ -236,58 +236,53 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
auto info_1 = vfs.open("/information/info_1.txt");
REQUIRE(info_1 != nullptr);
- REQUIRE(vfs.close(info_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(info_1.value()->absolute_path()));
- REQUIRE(vfs.unmount("/dev") == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/dev"));
+ REQUIRE(vfs.unmount("/"));
info_1 = vfs.open("/information/info_1.txt");
- REQUIRE(info_1 == nullptr);
+ REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory);
- REQUIRE(vfs.do_mount("/dev/ram0", "/") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram0", "/"));
info_1 = vfs.open("/information/info_1.txt");
REQUIRE(info_1 != nullptr);
auto dev_ram_0 = vfs.open("/dev/ram0");
- REQUIRE(dev_ram_0 == nullptr);
+ REQUIRE(dev_ram_0.error() == kstd::errc::no_such_file_or_directory);
}
THEN("mount with null file system fails")
{
- REQUIRE(vfs.do_mount("/closed.txt", "/information") ==
- kernel::filesystem::vfs::operation_result::invalid_filesystem);
+ REQUIRE(vfs.mount("/closed.txt", "/information").error() == kstd::errc::not_supported);
}
THEN("mount with invalid path fails")
{
- 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::mount_point_not_found);
+ REQUIRE(vfs.mount("/dev/ram16", "").error() == kstd::errc::invalid_argument);
+ REQUIRE(vfs.mount("/dev/ram16", "information").error() == kstd::errc::invalid_argument);
}
THEN("mount with non-existent source path fails")
{
- REQUIRE(vfs.do_mount("/dev/nonexistent", "/information") ==
- kernel::filesystem::vfs::operation_result::non_existent_path);
+ REQUIRE(vfs.mount("/dev/nonexistent", "/information").error() == kstd::errc::no_such_file_or_directory);
}
THEN("mount with non-existent mount point fails")
{
- REQUIRE(vfs.do_mount("/dev/ram16", "/information/nonexistent") ==
- kernel::filesystem::vfs::operation_result::mount_point_not_found);
+ REQUIRE(vfs.mount("/dev/ram16", "/information/nonexistent").error() == kstd::errc::no_such_file_or_directory);
}
THEN("unmount with invalid path fails")
{
- REQUIRE(vfs.unmount("") == kernel::filesystem::vfs::operation_result::invalid_path);
- REQUIRE(vfs.unmount("information") == kernel::filesystem::vfs::operation_result::mount_point_not_found);
+ REQUIRE(vfs.unmount("").error() == kstd::errc::invalid_argument);
+ REQUIRE(vfs.unmount("information").error() == kstd::errc::no_such_file_or_directory);
}
THEN("unmounting non-existent mount point returns expected error code")
{
- REQUIRE(vfs.unmount("/information/nonexistent") ==
- kernel::filesystem::vfs::operation_result::mount_point_not_found);
+ REQUIRE(vfs.unmount("/information/nonexistent").error() == kstd::errc::no_such_file_or_directory);
}
THEN("a file can be access if . in the path")
@@ -307,7 +302,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
THEN("a file can be accessed over multiple mounts if path contains .. or . ")
{
- REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram16", "/information"));
auto img = vfs.open("/information/monkey_house/caretaker/../../../../../../archiv/2024.img");
REQUIRE(img != nullptr);
@@ -321,9 +316,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
THEN("a file can be accessed over multiple mounts (device and file) if path contains .. ")
{
- REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.do_mount("/archiv/2024.img", "/information/monkey_house/infrastructure") ==
- kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram16", "/information"));
+ REQUIRE(vfs.mount("/archiv/2024.img", "/information/monkey_house/infrastructure"));
auto pig_1 = vfs.open("/information/monkey_house/infrastructure/stable/pig_1.txt");
REQUIRE(pig_1 != nullptr);
@@ -345,70 +339,69 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
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);
+ REQUIRE(vfs.mount("/archiv/2024.img", "/information"));
auto info_1 = vfs.open("/information/info_1.txt");
- REQUIRE(info_1 == nullptr);
+ REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory);
auto dentry = vfs.open("/information/sheep_1.txt");
REQUIRE(dentry != nullptr);
- auto sheep_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry);
+ auto sheep_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry.value());
kstd::vector<std::byte> buffer(7);
auto bytes_read = sheep_1_ofd->read(buffer.data(), buffer.size());
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), bytes_read};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), *bytes_read};
REQUIRE(buffer_as_str == "sheep_1");
- REQUIRE(vfs.close(dentry->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(dentry.value()->absolute_path()));
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/information"));
auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt");
- REQUIRE(unmounted_sheep_1 == nullptr);
+ REQUIRE(unmounted_sheep_1.error() == kstd::errc::no_such_file_or_directory);
}
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);
+ REQUIRE(vfs.mount("/archiv/2024.img", "/information"));
+ REQUIRE(vfs.mount("/archiv/2025.img", "/information/stable"));
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);
- auto sheep_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(sheep_1);
- auto goat_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(goat_1);
+ auto sheep_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(sheep_1.value());
+ auto goat_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(goat_1.value());
kstd::vector<std::byte> sheep_buffer(7);
auto bytes_read = sheep_1_ofd->read(sheep_buffer.data(), sheep_buffer.size());
- std::string_view buffer_as_str{reinterpret_cast<char *>(sheep_buffer.data()), bytes_read};
+ 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_ofd->read(goat_buffer.data(), goat_buffer.size());
- buffer_as_str = std::string_view{reinterpret_cast<char *>(goat_buffer.data()), bytes_read};
+ buffer_as_str = std::string_view{reinterpret_cast<char *>(goat_buffer.data()), *bytes_read};
REQUIRE(buffer_as_str == "goat_1");
- REQUIRE(vfs.close(sheep_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.close(goat_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(sheep_1.value()->absolute_path()));
+ REQUIRE(vfs.close(goat_1.value()->absolute_path()));
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed);
+ REQUIRE(vfs.unmount("/information").error() == kstd::errc::device_or_resource_busy);
- REQUIRE(vfs.unmount("/information/stable") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/information/stable"));
auto unmounted_goat_1 = vfs.open("/information/stable/petting_zoo/goat_1.txt");
- REQUIRE(unmounted_goat_1 == nullptr);
+ REQUIRE(unmounted_goat_1.error() == kstd::errc::no_such_file_or_directory);
auto still_mounted_sheep_1 = vfs.open("/information/sheep_1.txt");
REQUIRE(still_mounted_sheep_1 != nullptr);
- REQUIRE(vfs.close(still_mounted_sheep_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(still_mounted_sheep_1.value()->absolute_path()));
- REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/information"));
auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt");
- REQUIRE(unmounted_sheep_1 == nullptr);
+ REQUIRE(unmounted_sheep_1.error() == kstd::errc::no_such_file_or_directory);
}
}
@@ -423,23 +416,21 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
THEN("cannot unmount a filesystem if files are mounted")
{
- REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/enclosures") ==
- kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram16", "/entrance"));
+ REQUIRE(vfs.mount("/entrance/archiv/2024.img", "/enclosures"));
- REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::unmount_failed);
- REQUIRE(vfs.unmount("/enclosures") == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/entrance").error() == kstd::errc::device_or_resource_busy);
+ REQUIRE(vfs.unmount("/enclosures"));
+ REQUIRE(vfs.unmount("/entrance"));
}
THEN("can mount filesystem onto the directory that contains it")
{
- REQUIRE(vfs.do_mount("/dev/ram16", "/entrance") == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/entrance") ==
- kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.mount("/dev/ram16", "/entrance"));
+ REQUIRE(vfs.mount("/entrance/archiv/2024.img", "/entrance"));
- REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.unmount("/entrance") == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.unmount("/entrance"));
+ REQUIRE(vfs.unmount("/entrance"));
}
}
@@ -487,21 +478,21 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
{
auto & vfs = kernel::filesystem::vfs::get();
auto invalid_symlink = vfs.open("/symlinks/invalid_absolute");
- REQUIRE(invalid_symlink == nullptr);
+ REQUIRE(invalid_symlink.error() == kstd::errc::no_such_file_or_directory);
}
THEN("symbolic link containing an invalid relative path is handled correctly")
{
auto & vfs = kernel::filesystem::vfs::get();
auto invalid_symlink = vfs.open("/symlinks/invalid_relative");
- REQUIRE(invalid_symlink == nullptr);
+ REQUIRE(invalid_symlink.error() == kstd::errc::no_such_file_or_directory);
}
THEN("circular symbolic links are detected and handled correctly")
{
auto & vfs = kernel::filesystem::vfs::get();
auto circular_symlink = vfs.open("/symlinks/symloop_a");
- REQUIRE(circular_symlink == nullptr);
+ REQUIRE(circular_symlink.error() == kstd::errc::too_many_symbolic_link_levels);
}
}
@@ -511,7 +502,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
REQUIRE_NOTHROW(setup_modules_from_img_and_init_vfs({"test_img_module_1"}, {image_path_1}));
auto & vfs = kernel::filesystem::vfs::get();
- vfs.do_mount("/archiv/2024.img", "/information");
+ REQUIRE(vfs.mount("/archiv/2024.img", "/information"));
THEN("file can be opened through symbolic link pointing to the parent filesystem")
{
@@ -528,7 +519,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
setup_modules_from_img_and_init_vfs({"test_img_module_1", "test_img_module_2"}, {image_path_1, image_path_2}));
auto & vfs = kernel::filesystem::vfs::get();
- vfs.do_mount("/dev/ram16", "/information");
+ REQUIRE(vfs.mount("/dev/ram16", "/information"));
THEN("file can be opened through symbolic link pointing to the parent filesystem and back into the mounted "
"filesystem again")
diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp
index 8dc13490..8dce5143 100644
--- a/kernel/kernel/main.cpp
+++ b/kernel/kernel/main.cpp
@@ -13,10 +13,11 @@
#include <kapi/memory.hpp>
#include <kapi/system.hpp>
-#include <kstd/format>
-#include <kstd/print>
-#include <kstd/units>
-#include <kstd/vector>
+#include <kstd/format.hpp>
+#include <kstd/print.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/units.hpp>
+#include <kstd/vector.hpp>
#include <cstddef>
#include <string_view>
@@ -28,33 +29,33 @@ auto run_demo() -> void
// 1) open a file
kstd::println("attempting to open /entrance/tickets.txt");
auto fd_1 = kapi::filesystem::open("/entrance/tickets.txt");
- if (fd_1 == -1)
+ if (!fd_1)
{
kapi::system::panic("demo failed");
}
else
{
- kstd::println("--> successfully opened /entrance/tickets.txt with file descriptor {}", fd_1);
+ kstd::println("--> successfully opened /entrance/tickets.txt with file descriptor {}", fd_1.value());
}
// 2) read from the file
kstd::vector<std::byte> buffer_1{10};
- auto bytes_read = kapi::filesystem::read(fd_1, buffer_1.data(), buffer_1.size());
- auto buffer_as_str = std::string_view{reinterpret_cast<char *>(buffer_1.data()), static_cast<size_t>(bytes_read)};
+ auto bytes_read = *kapi::filesystem::read(fd_1.value(), buffer_1.data(), buffer_1.size());
+ auto buffer_as_str = std::string_view{reinterpret_cast<char *>(buffer_1.data()), bytes_read};
kstd::println("--> read {} bytes from /entrance/tickets.txt: {}", bytes_read, buffer_as_str);
kstd::println("");
// 3) show that /entrance/information/info_1.txt is not accessible before mounting
kstd::println("attempting to open /entrance/information/info_1.txt before mounting");
auto fd_before_mount = kapi::filesystem::open("/entrance/information/info_1.txt");
- if (fd_before_mount == -1)
+ if (!fd_before_mount && fd_before_mount.error() == kstd::errc::no_such_file_or_directory)
{
kstd::println("--> as expected the file could not be opened before mounting");
}
// 4) mount a new filesystem on top of /entrance
kstd::println("mount /dev/ram16 to /entrance");
- if (kapi::filesystem::mount("/dev/ram16", "/entrance") == 0)
+ if (kapi::filesystem::mount("/dev/ram16", "/entrance"))
{
kstd::println("--> successfully mounted /dev/ram16 to /entrance");
}
@@ -67,9 +68,9 @@ auto run_demo() -> void
// 5) open a file from the new filesystem
kstd::println("attempting to open /entrance/information/info_1.txt");
auto fd_2 = kapi::filesystem::open("/entrance/information/info_1.txt");
- if (fd_2 != -1)
+ if (fd_2)
{
- kstd::println("--> successfully opened /entrance/information/info_1.txt with file descriptor {}", fd_2);
+ kstd::println("--> successfully opened /entrance/information/info_1.txt with file descriptor {}", fd_2.value());
}
else
{
@@ -78,16 +79,16 @@ auto run_demo() -> void
// 6) read from the new file
kstd::vector<std::byte> buffer_2{10};
- bytes_read = kapi::filesystem::read(fd_2, buffer_2.data(), buffer_2.size());
+ bytes_read = *kapi::filesystem::read(fd_2.value(), buffer_2.data(), buffer_2.size());
buffer_as_str = std::string_view{reinterpret_cast<char *>(buffer_2.data()), static_cast<size_t>(bytes_read)};
kstd::println("--> read {} bytes from /entrance/information/info_1.txt: {} ", bytes_read, buffer_as_str);
// 7) open device as file
kstd::println("attempting to open /dev/ram32 as a file");
auto fd_3 = kapi::filesystem::open("/dev/ram32");
- if (fd_3 != -1)
+ if (fd_3)
{
- kstd::println("--> successfully opened /dev/ram32 as a file with file descriptor {}", fd_3);
+ kstd::println("--> successfully opened /dev/ram32 as a file with file descriptor {}", fd_3.value());
}
else
{
@@ -96,13 +97,13 @@ auto run_demo() -> void
// 8) read from the device file
kstd::vector<std::byte> buffer_3{2};
- bytes_read = kapi::filesystem::read(fd_3, buffer_3.data(), buffer_3.size());
+ bytes_read = *kapi::filesystem::read(fd_3.value(), buffer_3.data(), buffer_3.size());
kstd::println("--> read {} bytes from /dev/ram32: {::#04x} ", bytes_read, buffer_3);
// 9) write to the device file
auto const default_buffer_value = std::byte{0xAA};
kstd::vector<std::byte> write_buffer{default_buffer_value, default_buffer_value};
- auto bytes_written = kapi::filesystem::write(fd_3, write_buffer.data(), write_buffer.size());
+ auto bytes_written = *kapi::filesystem::write(fd_3.value(), write_buffer.data(), write_buffer.size());
kstd::println("--> written {} bytes to /dev/ram32: {::#04x}", bytes_written, write_buffer);
// 10) do memory dump to show that the write to the device file had an effect
@@ -146,7 +147,7 @@ auto main() -> int
kstd::println("[OS] Virtual filesystem initialized.");
// TODO BA-FS26 remove demo code?
- // run_demo();
+ run_demo();
kapi::system::panic("Returning from kernel main!");
}
diff --git a/kernel/kernel/memory.cpp b/kernel/kernel/memory.cpp
index 6a85c0e7..663137eb 100644
--- a/kernel/kernel/memory.cpp
+++ b/kernel/kernel/memory.cpp
@@ -6,8 +6,8 @@
#include <kapi/memory.hpp>
#include <kapi/system.hpp>
-#include <kstd/print>
-#include <kstd/units>
+#include <kstd/print.hpp>
+#include <kstd/units.hpp>
#include <atomic>
#include <optional>
diff --git a/kernel/kernel/memory/block_list_allocator.cpp b/kernel/kernel/memory/block_list_allocator.cpp
index 6e68ada7..a682051f 100644
--- a/kernel/kernel/memory/block_list_allocator.cpp
+++ b/kernel/kernel/memory/block_list_allocator.cpp
@@ -5,8 +5,8 @@
#include <kapi/memory.hpp>
#include <kapi/system.hpp>
-#include <kstd/mutex>
-#include <kstd/units>
+#include <kstd/mutex.hpp>
+#include <kstd/units.hpp>
#include <bit>
#include <cstddef>
diff --git a/kernel/kernel/memory/block_list_allocator.hpp b/kernel/kernel/memory/block_list_allocator.hpp
index 51b226ee..ac6257c0 100644
--- a/kernel/kernel/memory/block_list_allocator.hpp
+++ b/kernel/kernel/memory/block_list_allocator.hpp
@@ -5,8 +5,8 @@
#include <kapi/memory.hpp>
-#include <kstd/mutex>
-#include <kstd/units>
+#include <kstd/mutex.hpp>
+#include <kstd/units.hpp>
#include <cstddef>
#include <new>
diff --git a/kernel/kernel/memory/block_list_allocator.tests.cpp b/kernel/kernel/memory/block_list_allocator.tests.cpp
index c5f84c52..6efcd31a 100644
--- a/kernel/kernel/memory/block_list_allocator.tests.cpp
+++ b/kernel/kernel/memory/block_list_allocator.tests.cpp
@@ -4,7 +4,7 @@
#include <kapi/memory.hpp>
-#include <kstd/units>
+#include <kstd/units.hpp>
#include <catch2/catch_test_macros.hpp>
diff --git a/kernel/kernel/memory/heap_allocator.hpp b/kernel/kernel/memory/heap_allocator.hpp
index fd39bef8..59fa98b0 100644
--- a/kernel/kernel/memory/heap_allocator.hpp
+++ b/kernel/kernel/memory/heap_allocator.hpp
@@ -1,7 +1,7 @@
#ifndef TEACHOS_KERNEL_MEMORY_HEAP_ALLOCATOR_HPP
#define TEACHOS_KERNEL_MEMORY_HEAP_ALLOCATOR_HPP
-#include <kstd/units>
+#include <kstd/units.hpp>
namespace kernel::memory
{
diff --git a/kernel/kernel/memory/mmio_allocator.cpp b/kernel/kernel/memory/mmio_allocator.cpp
index ba23dbde..17f436f8 100644
--- a/kernel/kernel/memory/mmio_allocator.cpp
+++ b/kernel/kernel/memory/mmio_allocator.cpp
@@ -3,7 +3,7 @@
#include <kapi/memory.hpp>
#include <kapi/system.hpp>
-#include <kstd/allocator>
+#include <kstd/allocator.hpp>
#include <cstddef>
#include <memory>
diff --git a/kernel/kernel/memory/mmio_allocator.hpp b/kernel/kernel/memory/mmio_allocator.hpp
index c7a8ed0c..862188fa 100644
--- a/kernel/kernel/memory/mmio_allocator.hpp
+++ b/kernel/kernel/memory/mmio_allocator.hpp
@@ -3,8 +3,8 @@
#include <kapi/memory.hpp>
-#include <kstd/allocator>
-#include <kstd/memory>
+#include <kstd/allocator.hpp>
+#include <kstd/memory.hpp>
#include <cstddef>
diff --git a/kernel/kernel/memory/operators.cpp b/kernel/kernel/memory/operators.cpp
index 5673d680..5de5101d 100644
--- a/kernel/kernel/memory/operators.cpp
+++ b/kernel/kernel/memory/operators.cpp
@@ -2,7 +2,7 @@
#include <kapi/system.hpp>
-#include <kstd/units>
+#include <kstd/units.hpp>
#include <cstddef>
#include <new>
diff --git a/kernel/kernel/test_support/devices/block_device.cpp b/kernel/kernel/test_support/devices/block_device.cpp
index 9a9e544d..2dda5dec 100644
--- a/kernel/kernel/test_support/devices/block_device.cpp
+++ b/kernel/kernel/test_support/devices/block_device.cpp
@@ -2,8 +2,8 @@
#include <kernel/devices/block_device.hpp>
-#include <kstd/string>
-#include <kstd/vector>
+#include <kstd/string.hpp>
+#include <kstd/vector.hpp>
#include <algorithm>
#include <cstddef>
diff --git a/kernel/kernel/test_support/devices/block_device.hpp b/kernel/kernel/test_support/devices/block_device.hpp
index 89a2bf15..d83dddd1 100644
--- a/kernel/kernel/test_support/devices/block_device.hpp
+++ b/kernel/kernel/test_support/devices/block_device.hpp
@@ -3,8 +3,8 @@
#include <kernel/devices/block_device.hpp>
-#include <kstd/string>
-#include <kstd/vector>
+#include <kstd/string.hpp>
+#include <kstd/vector.hpp>
#include <cstddef>
#include <cstdint>
diff --git a/kernel/kernel/test_support/devices/character_device.cpp b/kernel/kernel/test_support/devices/character_device.cpp
index 3806654f..fef5baf5 100644
--- a/kernel/kernel/test_support/devices/character_device.cpp
+++ b/kernel/kernel/test_support/devices/character_device.cpp
@@ -2,7 +2,7 @@
#include <kapi/devices.hpp>
-#include <kstd/string>
+#include <kstd/string.hpp>
#include <cstddef>
diff --git a/kernel/kernel/test_support/devices/character_device.hpp b/kernel/kernel/test_support/devices/character_device.hpp
index aba183a1..5790a561 100644
--- a/kernel/kernel/test_support/devices/character_device.hpp
+++ b/kernel/kernel/test_support/devices/character_device.hpp
@@ -3,8 +3,8 @@
#include <kapi/devices/device.hpp>
-#include <kstd/string>
-#include <kstd/vector>
+#include <kstd/string.hpp>
+#include <kstd/vector.hpp>
#include <cstddef>
diff --git a/kernel/kernel/test_support/filesystem/filesystem.cpp b/kernel/kernel/test_support/filesystem/filesystem.cpp
index ec706077..38cea2f1 100644
--- a/kernel/kernel/test_support/filesystem/filesystem.cpp
+++ b/kernel/kernel/test_support/filesystem/filesystem.cpp
@@ -3,14 +3,16 @@
#include <kernel/filesystem/inode.hpp>
#include <kernel/test_support/filesystem/inode.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/system_error.hpp>
+#include <expected>
#include <string_view>
namespace kernel::tests::filesystem
{
auto filesystem::lookup(kstd::shared_ptr<kernel::filesystem::inode> const &, std::string_view) const
- -> kstd::shared_ptr<kernel::filesystem::inode>
+ -> std::expected<kstd::shared_ptr<kernel::filesystem::inode>, kstd::error_code>
{
return kstd::make_shared<inode>();
}
diff --git a/kernel/kernel/test_support/filesystem/filesystem.hpp b/kernel/kernel/test_support/filesystem/filesystem.hpp
index 5f260220..e6e0f416 100644
--- a/kernel/kernel/test_support/filesystem/filesystem.hpp
+++ b/kernel/kernel/test_support/filesystem/filesystem.hpp
@@ -4,8 +4,10 @@
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/inode.hpp>
-#include <kstd/memory>
+#include <kstd/memory.hpp>
+#include <kstd/system_error.hpp>
+#include <expected>
#include <string_view>
namespace kernel::tests::filesystem
@@ -15,7 +17,7 @@ namespace kernel::tests::filesystem
filesystem() = default;
[[nodiscard]] auto lookup(kstd::shared_ptr<kernel::filesystem::inode> const & parent, std::string_view name) const
- -> kstd::shared_ptr<kernel::filesystem::inode> override;
+ -> std::expected<kstd::shared_ptr<kernel::filesystem::inode>, kstd::error_code> override;
};
} // namespace kernel::tests::filesystem
diff --git a/kernel/kernel/test_support/filesystem/inode.cpp b/kernel/kernel/test_support/filesystem/inode.cpp
index 0c8d9563..fd8e4d69 100644
--- a/kernel/kernel/test_support/filesystem/inode.cpp
+++ b/kernel/kernel/test_support/filesystem/inode.cpp
@@ -2,16 +2,18 @@
#include <kernel/filesystem/inode.hpp>
+#include <kstd/result.hpp>
+
#include <cstddef>
namespace kernel::tests::filesystem
{
- auto inode::read(void *, size_t, size_t size) const -> size_t
+ auto inode::read(void *, size_t, size_t size) const -> kstd::result<size_t>
{
return size;
}
- auto inode::write(void const *, size_t, size_t size) -> size_t
+ auto inode::write(void const *, size_t, size_t size) -> kstd::result<size_t>
{
return size;
}
diff --git a/kernel/kernel/test_support/filesystem/inode.hpp b/kernel/kernel/test_support/filesystem/inode.hpp
index 8a764375..da2e3e21 100644
--- a/kernel/kernel/test_support/filesystem/inode.hpp
+++ b/kernel/kernel/test_support/filesystem/inode.hpp
@@ -3,14 +3,16 @@
#include <kernel/filesystem/inode.hpp>
+#include <kstd/result.hpp>
+
#include <cstddef>
namespace kernel::tests::filesystem
{
struct inode : kernel::filesystem::inode
{
- auto read(void * buffer, size_t offset, size_t size) const -> size_t override;
- auto write(void const * buffer, size_t offset, size_t size) -> size_t override;
+ auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
+ auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
[[nodiscard]] auto is_regular() const -> bool override;
};
diff --git a/kernel/kernel/test_support/kapi/memory.cpp b/kernel/kernel/test_support/kapi/memory.cpp
index 7fc95cb0..33b725bd 100644
--- a/kernel/kernel/test_support/kapi/memory.cpp
+++ b/kernel/kernel/test_support/kapi/memory.cpp
@@ -5,7 +5,7 @@
#include <kapi/memory.hpp>
-#include <kstd/units>
+#include <kstd/units.hpp>
#include <optional>
diff --git a/kernel/kernel/test_support/page_mapper.cpp b/kernel/kernel/test_support/page_mapper.cpp
index 3d50ff1a..b1a6f92b 100644
--- a/kernel/kernel/test_support/page_mapper.cpp
+++ b/kernel/kernel/test_support/page_mapper.cpp
@@ -2,7 +2,7 @@
#include <kapi/memory.hpp>
-#include <kstd/units>
+#include <kstd/units.hpp>
#include <cstddef>
#include <format>
diff --git a/kernel/kernel/test_support/page_mapper.hpp b/kernel/kernel/test_support/page_mapper.hpp
index be4403b0..a9985393 100644
--- a/kernel/kernel/test_support/page_mapper.hpp
+++ b/kernel/kernel/test_support/page_mapper.hpp
@@ -5,7 +5,7 @@
#include <kapi/memory.hpp>
-#include <kstd/units>
+#include <kstd/units.hpp>
#include <cstddef>
#include <cstdint>
diff --git a/kernel/kernel/test_support/simulated_memory.cpp b/kernel/kernel/test_support/simulated_memory.cpp
index 074e6b10..07adab17 100644
--- a/kernel/kernel/test_support/simulated_memory.cpp
+++ b/kernel/kernel/test_support/simulated_memory.cpp
@@ -2,7 +2,7 @@
#include <kapi/memory.hpp>
-#include <kstd/units>
+#include <kstd/units.hpp>
#include <cerrno>
#include <cstddef>
diff --git a/kernel/kernel/test_support/simulated_memory.hpp b/kernel/kernel/test_support/simulated_memory.hpp
index a201c3d7..e7ca9f6c 100644
--- a/kernel/kernel/test_support/simulated_memory.hpp
+++ b/kernel/kernel/test_support/simulated_memory.hpp
@@ -3,7 +3,7 @@
#include <kapi/memory.hpp>
-#include <kstd/units>
+#include <kstd/units.hpp>
#include <cstddef>
diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp
index d0611b21..cff1ea34 100644
--- a/kernel/kstd/print.cpp
+++ b/kernel/kstd/print.cpp
@@ -3,8 +3,8 @@
#include <kapi/cio.hpp>
#include <kstd/bits/format/output_buffer.hpp>
-#include <kstd/format>
-#include <kstd/print>
+#include <kstd/format.hpp>
+#include <kstd/print.hpp>
#include <algorithm>
#include <array>
diff --git a/kernel/kstd/print.tests.cpp b/kernel/kstd/print.tests.cpp
index 4963f46e..a8c4ae25 100644
--- a/kernel/kstd/print.tests.cpp
+++ b/kernel/kstd/print.tests.cpp
@@ -1,4 +1,4 @@
-#include <kstd/print>
+#include <kstd/print.hpp>
#include <kernel/test_support/cio.hpp>