From 47b935e2c85a794d60c22e8d96f53c0a2d364977 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 9 Jul 2026 13:55:03 +0200 Subject: kstd: rename kstd header to include hpp --- kernel/kapi/acpi.cpp | 2 +- kernel/kapi/cpu.cpp | 2 +- kernel/kapi/devices.cpp | 6 +++--- kernel/kapi/devices/bus.cpp | 8 ++++---- kernel/kapi/devices/device.cpp | 4 ++-- kernel/kapi/filesystem.cpp | 2 +- kernel/kapi/interrupts.cpp | 6 +++--- kernel/kapi/memory.cpp | 4 ++-- kernel/kapi/system.cpp | 2 +- kernel/kapi/system.tests.cpp | 2 +- kernel/kernel/acpi/manager.cpp | 4 ++-- kernel/kernel/acpi/manager.hpp | 6 +++--- kernel/kernel/devices/block_device.cpp | 2 +- kernel/kernel/devices/block_device.hpp | 2 +- kernel/kernel/devices/block_device.tests.cpp | 8 ++++---- kernel/kernel/devices/block_device_utils.cpp | 6 +++--- kernel/kernel/devices/block_device_utils.hpp | 2 +- kernel/kernel/devices/block_device_utils.tests.cpp | 6 +++--- kernel/kernel/devices/storage/controller.cpp | 4 ++-- kernel/kernel/devices/storage/controller.hpp | 4 ++-- kernel/kernel/devices/storage/management.cpp | 4 ++-- kernel/kernel/devices/storage/management.hpp | 4 ++-- kernel/kernel/devices/storage/ram_disk/controller.cpp | 2 +- kernel/kernel/devices/storage/ram_disk/device.cpp | 4 ++-- kernel/kernel/filesystem/dentry.cpp | 4 ++-- kernel/kernel/filesystem/dentry.hpp | 6 +++--- kernel/kernel/filesystem/dentry.tests.cpp | 4 ++-- kernel/kernel/filesystem/devfs/filesystem.cpp | 2 +- kernel/kernel/filesystem/devfs/filesystem.hpp | 4 ++-- kernel/kernel/filesystem/devfs/inode.tests.cpp | 6 +++--- kernel/kernel/filesystem/device_inode.cpp | 2 +- kernel/kernel/filesystem/device_inode.hpp | 2 +- kernel/kernel/filesystem/device_inode.tests.cpp | 6 +++--- kernel/kernel/filesystem/ext2/filesystem.cpp | 4 ++-- kernel/kernel/filesystem/ext2/filesystem.hpp | 4 ++-- kernel/kernel/filesystem/ext2/filesystem.tests.cpp | 4 ++-- kernel/kernel/filesystem/ext2/inode.cpp | 2 +- kernel/kernel/filesystem/ext2/inode.hpp | 2 +- kernel/kernel/filesystem/ext2/inode.tests.cpp | 4 ++-- kernel/kernel/filesystem/filesystem.cpp | 2 +- kernel/kernel/filesystem/filesystem.hpp | 4 ++-- kernel/kernel/filesystem/mount.cpp | 4 ++-- kernel/kernel/filesystem/mount.hpp | 4 ++-- kernel/kernel/filesystem/mount.tests.cpp | 6 +++--- kernel/kernel/filesystem/mount_table.cpp | 4 ++-- kernel/kernel/filesystem/mount_table.hpp | 4 ++-- kernel/kernel/filesystem/mount_table.tests.cpp | 6 +++--- kernel/kernel/filesystem/open_file_descriptor.cpp | 2 +- kernel/kernel/filesystem/open_file_descriptor.hpp | 2 +- kernel/kernel/filesystem/open_file_descriptor.tests.cpp | 6 +++--- kernel/kernel/filesystem/open_file_table.cpp | 2 +- kernel/kernel/filesystem/open_file_table.hpp | 4 ++-- kernel/kernel/filesystem/open_file_table.tests.cpp | 6 +++--- kernel/kernel/filesystem/path.hpp | 2 +- kernel/kernel/filesystem/rootfs/filesystem.cpp | 2 +- kernel/kernel/filesystem/rootfs/filesystem.hpp | 6 +++--- kernel/kernel/filesystem/rootfs/filesystem.tests.cpp | 6 +++--- kernel/kernel/filesystem/rootfs/inode.hpp | 6 +++--- kernel/kernel/filesystem/rootfs/inode.tests.cpp | 6 +++--- kernel/kernel/filesystem/type.hpp | 2 +- kernel/kernel/filesystem/type_registry.cpp | 4 ++-- kernel/kernel/filesystem/type_registry.hpp | 6 +++--- kernel/kernel/filesystem/type_registry.tests.cpp | 2 +- kernel/kernel/filesystem/vfs.cpp | 4 ++-- kernel/kernel/filesystem/vfs.hpp | 2 +- kernel/kernel/filesystem/vfs.tests.cpp | 4 ++-- kernel/kernel/main.cpp | 8 ++++---- kernel/kernel/memory.cpp | 4 ++-- kernel/kernel/memory/block_list_allocator.cpp | 4 ++-- kernel/kernel/memory/block_list_allocator.hpp | 4 ++-- kernel/kernel/memory/block_list_allocator.tests.cpp | 2 +- kernel/kernel/memory/heap_allocator.hpp | 2 +- kernel/kernel/memory/mmio_allocator.cpp | 2 +- kernel/kernel/memory/mmio_allocator.hpp | 4 ++-- kernel/kernel/memory/operators.cpp | 2 +- kernel/kernel/test_support/devices/block_device.cpp | 4 ++-- kernel/kernel/test_support/devices/block_device.hpp | 4 ++-- kernel/kernel/test_support/devices/character_device.cpp | 2 +- kernel/kernel/test_support/devices/character_device.hpp | 4 ++-- kernel/kernel/test_support/filesystem/filesystem.cpp | 2 +- kernel/kernel/test_support/filesystem/filesystem.hpp | 2 +- kernel/kernel/test_support/kapi/memory.cpp | 2 +- kernel/kernel/test_support/page_mapper.cpp | 2 +- kernel/kernel/test_support/page_mapper.hpp | 2 +- kernel/kernel/test_support/simulated_memory.cpp | 2 +- kernel/kernel/test_support/simulated_memory.hpp | 2 +- kernel/kstd/print.cpp | 4 ++-- kernel/kstd/print.tests.cpp | 2 +- 88 files changed, 163 insertions(+), 163 deletions(-) (limited to 'kernel') 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 -#include +#include #include #include 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 -#include +#include 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 -#include -#include -#include +#include +#include +#include #include #include 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 #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include 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 -#include -#include +#include +#include #include diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 68b51c97..4880ae38 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include 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 -#include -#include -#include +#include +#include +#include #include #include 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 -#include -#include +#include +#include #include #include diff --git a/kernel/kapi/system.cpp b/kernel/kapi/system.cpp index 9819ceb7..86c99515 100644 --- a/kernel/kapi/system.cpp +++ b/kernel/kapi/system.cpp @@ -2,7 +2,7 @@ #include -#include +#include #include #include 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 #include -#include +#include #include 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 -#include -#include +#include +#include #include #include 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 -#include -#include -#include +#include +#include +#include #include 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 #include -#include +#include #include 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 -#include +#include #include 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 -#include -#include -#include -#include +#include +#include +#include +#include #include 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 #include -#include -#include -#include +#include +#include +#include #include #include 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 -#include +#include #include 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 #include -#include -#include -#include +#include +#include +#include #include 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 -#include -#include +#include +#include #include #include 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 -#include -#include +#include +#include #include 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 #include -#include -#include +#include +#include #include #include 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 -#include -#include +#include +#include #include 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 -#include +#include #include #include 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 #include -#include -#include +#include +#include #include 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 -#include -#include +#include +#include #include #include 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 -#include -#include -#include +#include +#include +#include #include #include 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 #include -#include -#include +#include +#include #include diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp index ce887ff3..3b1da25c 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.cpp @@ -9,7 +9,7 @@ #include -#include +#include #include #include diff --git a/kernel/kernel/filesystem/devfs/filesystem.hpp b/kernel/kernel/filesystem/devfs/filesystem.hpp index dbaa387b..083d248c 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/kernel/filesystem/devfs/filesystem.hpp @@ -5,8 +5,8 @@ #include #include -#include -#include +#include +#include #include 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 -#include -#include -#include +#include +#include +#include #include diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp index 81a784cd..091b5499 100644 --- a/kernel/kernel/filesystem/device_inode.cpp +++ b/kernel/kernel/filesystem/device_inode.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include diff --git a/kernel/kernel/filesystem/device_inode.hpp b/kernel/kernel/filesystem/device_inode.hpp index f4aa2d1e..b461f225 100644 --- a/kernel/kernel/filesystem/device_inode.hpp +++ b/kernel/kernel/filesystem/device_inode.hpp @@ -5,7 +5,7 @@ #include -#include +#include #include 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 #include -#include -#include -#include +#include +#include +#include #include diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 3180a19a..82c6441d 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -8,9 +8,9 @@ #include #include -#include +#include #include -#include +#include #include #include diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp index 2284d7bf..fc2ba7df 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/kernel/filesystem/ext2/filesystem.hpp @@ -7,9 +7,9 @@ #include #include -#include +#include #include -#include +#include #include #include diff --git a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp index 83410702..ed3ac1ac 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp @@ -8,8 +8,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/kernel/kernel/filesystem/ext2/inode.cpp b/kernel/kernel/filesystem/ext2/inode.cpp index 35a32ee4..11f55cb6 100644 --- a/kernel/kernel/filesystem/ext2/inode.cpp +++ b/kernel/kernel/filesystem/ext2/inode.cpp @@ -5,7 +5,7 @@ #include -#include +#include #include #include diff --git a/kernel/kernel/filesystem/ext2/inode.hpp b/kernel/kernel/filesystem/ext2/inode.hpp index f2496f0f..8b63f787 100644 --- a/kernel/kernel/filesystem/ext2/inode.hpp +++ b/kernel/kernel/filesystem/ext2/inode.hpp @@ -3,7 +3,7 @@ #include -#include +#include #include #include diff --git a/kernel/kernel/filesystem/ext2/inode.tests.cpp b/kernel/kernel/filesystem/ext2/inode.tests.cpp index 4aecc04a..aa21f6ed 100644 --- a/kernel/kernel/filesystem/ext2/inode.tests.cpp +++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/kernel/kernel/filesystem/filesystem.cpp b/kernel/kernel/filesystem/filesystem.cpp index 24d0e229..f0b7fd28 100644 --- a/kernel/kernel/filesystem/filesystem.cpp +++ b/kernel/kernel/filesystem/filesystem.cpp @@ -5,7 +5,7 @@ #include -#include +#include #include diff --git a/kernel/kernel/filesystem/filesystem.hpp b/kernel/kernel/filesystem/filesystem.hpp index bec1b160..b818d992 100644 --- a/kernel/kernel/filesystem/filesystem.hpp +++ b/kernel/kernel/filesystem/filesystem.hpp @@ -3,8 +3,8 @@ #include -#include -#include +#include +#include #include 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 -#include -#include +#include +#include #include #include 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 #include -#include -#include +#include +#include #include #include 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 #include -#include -#include -#include +#include +#include +#include #include 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 #include -#include -#include +#include +#include #include #include 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 -#include -#include +#include +#include #include 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 #include -#include -#include -#include +#include +#include +#include #include diff --git a/kernel/kernel/filesystem/open_file_descriptor.cpp b/kernel/kernel/filesystem/open_file_descriptor.cpp index a5567bf4..bec484d7 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.cpp +++ b/kernel/kernel/filesystem/open_file_descriptor.cpp @@ -2,7 +2,7 @@ #include -#include +#include #include #include diff --git a/kernel/kernel/filesystem/open_file_descriptor.hpp b/kernel/kernel/filesystem/open_file_descriptor.hpp index fd10e646..beb32ec6 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.hpp +++ b/kernel/kernel/filesystem/open_file_descriptor.hpp @@ -3,7 +3,7 @@ #include -#include +#include #include diff --git a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp index 8c24cf0e..c666ef43 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp @@ -6,9 +6,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/kernel/kernel/filesystem/open_file_table.cpp b/kernel/kernel/filesystem/open_file_table.cpp index 2afe3aa4..38bd7a43 100644 --- a/kernel/kernel/filesystem/open_file_table.cpp +++ b/kernel/kernel/filesystem/open_file_table.cpp @@ -4,7 +4,7 @@ #include -#include +#include #include #include diff --git a/kernel/kernel/filesystem/open_file_table.hpp b/kernel/kernel/filesystem/open_file_table.hpp index 7e754ac1..a5e6b496 100644 --- a/kernel/kernel/filesystem/open_file_table.hpp +++ b/kernel/kernel/filesystem/open_file_table.hpp @@ -3,9 +3,9 @@ #include -#include +#include #include -#include +#include #include diff --git a/kernel/kernel/filesystem/open_file_table.tests.cpp b/kernel/kernel/filesystem/open_file_table.tests.cpp index 3e91111d..ffb4a650 100644 --- a/kernel/kernel/filesystem/open_file_table.tests.cpp +++ b/kernel/kernel/filesystem/open_file_table.tests.cpp @@ -4,9 +4,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include 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 -#include +#include #include #include diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp index 7fe5c1ea..52c2cec2 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include diff --git a/kernel/kernel/filesystem/rootfs/filesystem.hpp b/kernel/kernel/filesystem/rootfs/filesystem.hpp index 3c2dcb1c..5d59486d 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.hpp @@ -4,9 +4,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp index ae320e95..8f16077a 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp @@ -2,9 +2,9 @@ #include -#include -#include -#include +#include +#include +#include #include diff --git a/kernel/kernel/filesystem/rootfs/inode.hpp b/kernel/kernel/filesystem/rootfs/inode.hpp index 0f21eaa0..ee5b9012 100644 --- a/kernel/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/kernel/filesystem/rootfs/inode.hpp @@ -3,9 +3,9 @@ #include -#include -#include -#include +#include +#include +#include #include 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 -#include -#include -#include +#include +#include +#include #include 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 -#include +#include #include 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 -#include -#include +#include +#include #include #include 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 -#include -#include -#include +#include +#include +#include #include #include 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 #include -#include +#include #include diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index e5dff8c4..f6c64f0f 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -11,8 +11,8 @@ #include -#include -#include +#include +#include #include #include diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp index ddc9a9bc..bb1167fb 100644 --- a/kernel/kernel/filesystem/vfs.hpp +++ b/kernel/kernel/filesystem/vfs.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index f1d0df0d..849300ac 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp index 8dc13490..88f76f88 100644 --- a/kernel/kernel/main.cpp +++ b/kernel/kernel/main.cpp @@ -13,10 +13,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include 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 #include -#include -#include +#include +#include #include #include 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 #include -#include -#include +#include +#include #include #include 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 -#include -#include +#include +#include #include #include 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 -#include +#include #include 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 +#include 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 #include -#include +#include #include #include 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 -#include -#include +#include +#include #include 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 -#include +#include #include #include 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 -#include -#include +#include +#include #include #include 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 -#include -#include +#include +#include #include #include 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 -#include +#include #include 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 -#include -#include +#include +#include #include diff --git a/kernel/kernel/test_support/filesystem/filesystem.cpp b/kernel/kernel/test_support/filesystem/filesystem.cpp index ec706077..a4ea30bb 100644 --- a/kernel/kernel/test_support/filesystem/filesystem.cpp +++ b/kernel/kernel/test_support/filesystem/filesystem.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include diff --git a/kernel/kernel/test_support/filesystem/filesystem.hpp b/kernel/kernel/test_support/filesystem/filesystem.hpp index 5f260220..5809bb5e 100644 --- a/kernel/kernel/test_support/filesystem/filesystem.hpp +++ b/kernel/kernel/test_support/filesystem/filesystem.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include 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 -#include +#include #include 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 -#include +#include #include #include 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 -#include +#include #include #include 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 -#include +#include #include #include 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 -#include +#include #include 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 #include -#include -#include +#include +#include #include #include 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 +#include #include -- cgit v1.2.3 From 878af4b049e0236daa02d075e693c9c630d89aca Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 9 Jul 2026 14:33:58 +0200 Subject: cmake: extract test target creation --- kernel/CMakeLists.txt | 64 +++++---------------------------------------------- 1 file changed, 6 insertions(+), 58 deletions(-) (limited to 'kernel') 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() -- cgit v1.2.3 From f54e09351a967da21f863fd2d3b17ffd24d3ee87 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sun, 12 Jul 2026 15:24:40 +0200 Subject: kernel: integrate kstd system_error facility --- kernel/kapi/filesystem.cpp | 11 +-- kernel/kapi/filesystem.tests.cpp | 32 +++---- kernel/kernel/filesystem/error.hpp | 106 +++++++++++++++++++++ .../filesystem/open_file_descriptor.tests.cpp | 4 +- kernel/kernel/filesystem/vfs.cpp | 36 ++++--- kernel/kernel/filesystem/vfs.hpp | 8 +- kernel/kernel/filesystem/vfs.tests.cpp | 51 +++++----- kernel/kernel/main.cpp | 20 ++-- 8 files changed, 188 insertions(+), 80 deletions(-) create mode 100644 kernel/kernel/filesystem/error.hpp (limited to 'kernel') diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 4880ae38..24a3adf3 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -5,9 +5,11 @@ #include #include +#include #include #include +#include #include namespace kapi::filesystem @@ -30,15 +32,12 @@ namespace kapi::filesystem return -1; } - auto open(std::string_view path) -> kstd::ssize_t + auto open(std::string_view path) -> std::expected { - if (auto dentry = kernel::filesystem::vfs::get().open(path)) - { + return kernel::filesystem::vfs::get().open(path).transform([](auto dentry) { auto open_file_descriptor = kstd::make_shared(dentry); return kernel::filesystem::open_file_table::get().add_file(open_file_descriptor); - } - - return -1; + }); } auto close(size_t file_descriptor) -> kstd::ssize_t diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp index d241afa8..37d0c20d 100644 --- a/kernel/kapi/filesystem.tests.cpp +++ b/kernel/kapi/filesystem.tests.cpp @@ -25,8 +25,7 @@ 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(6); auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); @@ -40,8 +39,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap 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(6); auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); @@ -55,8 +53,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap 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(6); auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); @@ -72,8 +69,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap { 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(7); auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); @@ -89,8 +85,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap { REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information") == 0); - 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(8); auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); @@ -107,8 +102,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap { REQUIRE(kapi::filesystem::mount("/dev/ram16", "/information") == 0); - 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); @@ -118,8 +112,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap 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(512); auto bytes_read = kapi::filesystem::read(fd, buffer.data(), buffer.size()); @@ -130,15 +123,13 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap 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(512, std::byte{0xAB}); auto bytes_written = kapi::filesystem::write(read_fd, buffer.data(), buffer.size()); REQUIRE(bytes_written >= 0); - 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(512); auto bytes_read = kapi::filesystem::read(write_fd, read_buffer.data(), read_buffer.size()); @@ -163,7 +154,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap 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") @@ -173,8 +164,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap 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); diff --git a/kernel/kernel/filesystem/error.hpp b/kernel/kernel/filesystem/error.hpp new file mode 100644 index 00000000..267e5b7e --- /dev/null +++ b/kernel/kernel/filesystem/error.hpp @@ -0,0 +1,106 @@ +#ifndef TEACHOS_KERNEL_FILESYSTEM_ERROR_HPP +#define TEACHOS_KERNEL_FILESYSTEM_ERROR_HPP + +#include + +#include +#include + +namespace kernel::filesystem +{ + + enum struct vfs_errc : int + { + invalid_path = 1, + non_existent_path, + mount_point_not_found, + mount_busy, + has_child_mounts, + invalid_filesystem, + unmount_failed, + }; + + 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(value)) + { + case vfs_errc::invalid_path: + return "invalid path"; + case vfs_errc::non_existent_path: + return "path does not exist"; + 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"; + default: + return "unknown VFS error"; + } + } + + [[nodiscard]] constexpr auto default_error_condition(int value) const noexcept -> kstd::error_condition override + { + switch (static_cast(value)) + { + case vfs_errc::invalid_path: + case vfs_errc::invalid_filesystem: + return make_error_condition(kstd::errc::invalid_argument); + case vfs_errc::non_existent_path: + 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); + 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(error), vfs_category()}; + } + + [[nodiscard]] constexpr auto inline make_error_condition(vfs_errc error) noexcept -> kstd::error_condition + { + return {static_cast(error), vfs_category()}; + } + +} // namespace kernel::filesystem + +namespace kstd +{ + template<> + struct is_error_code_enum : std::true_type + { + }; + + template<> + struct is_error_condition_enum : std::true_type + { + }; +} // namespace kstd + +#endif diff --git a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp index c666ef43..a04fbaa5 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp @@ -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(dentry); + REQUIRE(dentry); + auto ofd = kstd::make_shared(dentry.value()); THEN("the file can be read and the offset is updated") { diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index f6c64f0f..a5c1593d 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -12,10 +13,12 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -54,7 +57,8 @@ namespace kernel::filesystem 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())) @@ -78,13 +82,15 @@ namespace kernel::filesystem return *active_vfs; } - auto vfs::open(std::string_view path) -> kstd::shared_ptr + auto vfs::open(std::string_view path) -> std::expected, kstd::error_code> { - auto [dentry, mount] = resolve_path_internal(path); - if (!dentry || !mount) + auto resolved_path = resolve_path_internal(path); + if (!resolved_path) { - return nullptr; + return std::unexpected{resolved_path.error()}; } + + auto [dentry, mount] = resolved_path.value(); mount->increment_ref_count(); return dentry; } @@ -106,10 +112,10 @@ namespace kernel::filesystem return operation_result::invalid_path; } - auto [mount_point_dentry, mount_context] = resolve_path_internal(target); + auto [mount_point_dentry, mount_context] = resolve_path_internal(target).value_or(std::pair{nullptr, nullptr}); if (mount_point_dentry && mount_context) { - auto [source_dentry, source_mount_context] = resolve_path_internal(source); + auto [source_dentry, source_mount_context] = resolve_path_internal(source).value_or(std::pair{nullptr, nullptr}); if (source_dentry && source_mount_context) { if (auto fs = kernel::filesystem::filesystem::probe_and_mount(source_dentry->get_inode())) @@ -156,7 +162,7 @@ namespace kernel::filesystem auto vfs::graft_persistent_device_fs(kstd::shared_ptr 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"); @@ -171,11 +177,11 @@ namespace kernel::filesystem } auto vfs::resolve_path_internal(std::string_view path) const - -> std::pair, kstd::shared_ptr> + -> std::expected, kstd::shared_ptr>, kstd::error_code> { if (!path::is_valid_absolute_path(path)) { - return {nullptr, nullptr}; + return std::unexpected{make_error_code(vfs_errc::invalid_path)}; } auto current_mount = m_mount_table.find_mount("/"); @@ -231,7 +237,7 @@ namespace kernel::filesystem auto found_inode = current_fs->lookup(current_dentry->get_inode(), part); if (!found_inode) { - return {nullptr, nullptr}; + return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; } next_dentry = kstd::make_shared(current_dentry, found_inode, part); @@ -252,7 +258,7 @@ namespace kernel::filesystem { if (symlink_counter++ > constants::symloop_max) { - return {nullptr, nullptr}; + return std::unexpected{make_error_code(kstd::errc::too_many_symbolic_link_levels)}; } kstd::vector buffer(constants::symlink_max_path_length); @@ -275,17 +281,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 { - return resolve_path_internal(path).first; + return resolve_path_internal(path).transform([](auto result) { return result.first; }).value_or(nullptr); } auto vfs::find_mount(std::string_view path) const -> kstd::shared_ptr { - return resolve_path_internal(path).second; + return resolve_path_internal(path).transform([](auto result) { return result.second; }).value_or(nullptr); } } // namespace kernel::filesystem diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp index bb1167fb..ef26aa84 100644 --- a/kernel/kernel/filesystem/vfs.hpp +++ b/kernel/kernel/filesystem/vfs.hpp @@ -8,7 +8,9 @@ #include #include +#include +#include #include #include @@ -58,9 +60,9 @@ 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; + auto open(std::string_view path) -> std::expected, kstd::error_code>; /** @brief Close a file by its associated @p path. @@ -96,7 +98,7 @@ 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>; + -> std::expected, kstd::shared_ptr>, kstd::error_code>; [[nodiscard]] auto resolve_path(std::string_view path) const -> kstd::shared_ptr; [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr; diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index 849300ac..c5130ef4 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -105,8 +105,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); - REQUIRE(mounted_monkey_1 != nullptr); - 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()) == + kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); @@ -125,11 +126,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS 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()) == + kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_fish1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); REQUIRE(vfs.unmount("/information/monkey_house/infrastructure") == @@ -142,11 +144,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.do_mount("/dev/ram16", "/information") == kernel::filesystem::vfs::operation_result::success); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); - REQUIRE(mounted_monkey_1 != nullptr); + REQUIRE(mounted_monkey_1); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); - REQUIRE(vfs.close(mounted_monkey_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path()) == + kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); } @@ -160,10 +163,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS 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()) == kernel::filesystem::vfs::operation_result::success); + 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") @@ -172,9 +175,10 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.do_mount("/dev/ram32", "/information") == kernel::filesystem::vfs::operation_result::success); auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); - REQUIRE(mounted_tickets != nullptr); + REQUIRE(mounted_tickets); - REQUIRE(vfs.close(mounted_tickets->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(mounted_tickets.value()->absolute_path()) == + kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); mounted_tickets = vfs.open("/information/entrance/tickets.txt"); @@ -197,7 +201,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS 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()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); @@ -218,7 +222,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS 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()) == kernel::filesystem::vfs::operation_result::success); auto dev_ram_16 = vfs.open("/dev/ram16"); REQUIRE(dev_ram_16 == nullptr); @@ -236,7 +240,7 @@ 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()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/dev") == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/") == kernel::filesystem::vfs::operation_result::success); @@ -352,14 +356,14 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto dentry = vfs.open("/information/sheep_1.txt"); REQUIRE(dentry != nullptr); - auto sheep_1_ofd = kstd::make_shared(dentry); + auto sheep_1_ofd = kstd::make_shared(dentry.value()); kstd::vector buffer(7); auto bytes_read = sheep_1_ofd->read(buffer.data(), buffer.size()); std::string_view buffer_as_str{reinterpret_cast(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()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); @@ -379,8 +383,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(sheep_1 != nullptr); REQUIRE(goat_1 != nullptr); - auto sheep_1_ofd = kstd::make_shared(sheep_1); - auto goat_1_ofd = kstd::make_shared(goat_1); + auto sheep_1_ofd = kstd::make_shared(sheep_1.value()); + auto goat_1_ofd = kstd::make_shared(goat_1.value()); kstd::vector sheep_buffer(7); auto bytes_read = sheep_1_ofd->read(sheep_buffer.data(), sheep_buffer.size()); @@ -392,8 +396,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS buffer_as_str = std::string_view{reinterpret_cast(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()) == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.close(goat_1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::unmount_failed); @@ -404,7 +408,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS 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()) == + kernel::filesystem::vfs::operation_result::success); REQUIRE(vfs.unmount("/information") == kernel::filesystem::vfs::operation_result::success); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp index 88f76f88..76c05204 100644 --- a/kernel/kernel/main.cpp +++ b/kernel/kernel/main.cpp @@ -28,18 +28,18 @@ 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 buffer_1{10}; - auto bytes_read = kapi::filesystem::read(fd_1, buffer_1.data(), buffer_1.size()); + auto bytes_read = kapi::filesystem::read(fd_1.value(), buffer_1.data(), buffer_1.size()); auto buffer_as_str = std::string_view{reinterpret_cast(buffer_1.data()), static_cast(bytes_read)}; kstd::println("--> read {} bytes from /entrance/tickets.txt: {}", bytes_read, buffer_as_str); kstd::println(""); @@ -67,9 +67,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 +78,16 @@ auto run_demo() -> void // 6) read from the new file kstd::vector 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(buffer_2.data()), static_cast(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 +96,13 @@ auto run_demo() -> void // 8) read from the device file kstd::vector 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 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 -- cgit v1.2.3 From 3dc0df78f96dae38a54208d78e14f977f085b9bb Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sun, 12 Jul 2026 21:37:50 +0200 Subject: kapi: enforce stricter error handling --- kernel/kapi/filesystem.cpp | 58 +++---- kernel/kapi/filesystem.tests.cpp | 72 ++++---- kernel/kernel/filesystem/open_file_table.cpp | 20 ++- kernel/kernel/filesystem/open_file_table.hpp | 9 +- kernel/kernel/filesystem/open_file_table.tests.cpp | 21 +-- kernel/kernel/filesystem/vfs.cpp | 40 ++--- kernel/kernel/filesystem/vfs.hpp | 35 ++-- kernel/kernel/filesystem/vfs.tests.cpp | 185 ++++++++++----------- kernel/kernel/main.cpp | 15 +- 9 files changed, 214 insertions(+), 241 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 24a3adf3..f84949da 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -14,62 +13,45 @@ 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 { - if (kernel::filesystem::vfs::get().do_mount(source, target) == kernel::filesystem::vfs::operation_result::success) - { - return 0; - } - return -1; + return kernel::filesystem::vfs::get().do_mount(source, target); } - auto umount(std::string_view target) -> kstd::ssize_t + auto umount(std::string_view target) -> std::expected { - 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) -> std::expected { - return kernel::filesystem::vfs::get().open(path).transform([](auto dentry) { + return kernel::filesystem::vfs::get().open(path).and_then([](auto dentry) { auto open_file_descriptor = kstd::make_shared(dentry); return kernel::filesystem::open_file_table::get().add_file(open_file_descriptor); }); } - auto close(size_t file_descriptor) -> kstd::ssize_t + auto close(size_t file_descriptor) -> std::expected { - 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); }) + .transform([](auto) { return; }); } - 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 { - 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).transform([=](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 { - 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).transform([=](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 37d0c20d..d1e01db6 100644 --- a/kernel/kapi/filesystem.tests.cpp +++ b/kernel/kapi/filesystem.tests.cpp @@ -2,6 +2,8 @@ #include +#include + #include #include @@ -29,12 +31,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap auto buffer = std::vector(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(buffer.data()), static_cast(bytes_read)}; + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(*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") @@ -43,12 +45,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap auto buffer = std::vector(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(buffer.data()), static_cast(bytes_read)}; + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(*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") @@ -57,57 +59,57 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap auto buffer = std::vector(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(buffer.data()), static_cast(bytes_read)}; + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(*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").value(); auto buffer = std::vector(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(buffer.data()), static_cast(bytes_read)}; + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(*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").value(); auto buffer = std::vector(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(buffer.data()), static_cast(bytes_read)}; + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), static_cast(*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").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") @@ -116,9 +118,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap auto buffer = std::vector(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") @@ -127,28 +129,28 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap auto buffer = std::vector(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").value(); auto read_buffer = std::vector(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") @@ -159,15 +161,15 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap 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").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") @@ -175,7 +177,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap std::vector 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") @@ -183,7 +185,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap std::vector 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/kernel/filesystem/open_file_table.cpp b/kernel/kernel/filesystem/open_file_table.cpp index 38bd7a43..df5717a4 100644 --- a/kernel/kernel/filesystem/open_file_table.cpp +++ b/kernel/kernel/filesystem/open_file_table.cpp @@ -5,10 +5,11 @@ #include #include -#include +#include #include #include +#include #include namespace @@ -38,11 +39,12 @@ namespace kernel::filesystem return *global_open_file_table; } - auto open_file_table::add_file(kstd::shared_ptr const & file_descriptor) -> kstd::ssize_t + auto open_file_table::add_file(kstd::shared_ptr const & file_descriptor) + -> std::expected { if (!file_descriptor) { - return -1; + return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; } auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; }); @@ -56,21 +58,21 @@ namespace kernel::filesystem return m_open_files.size() - 1; } - auto open_file_table::file(size_t fd) const -> kstd::shared_ptr + auto open_file_table::file(size_t fd) const -> std::expected, kstd::error_code> { - if (fd >= m_open_files.size()) + if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr) { - return nullptr; + return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; } return 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) -> std::expected { - if (fd >= m_open_files.size()) + if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr) { - return -1; + return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; } m_open_files.at(fd) = nullptr; diff --git a/kernel/kernel/filesystem/open_file_table.hpp b/kernel/kernel/filesystem/open_file_table.hpp index a5e6b496..efdaf578 100644 --- a/kernel/kernel/filesystem/open_file_table.hpp +++ b/kernel/kernel/filesystem/open_file_table.hpp @@ -4,10 +4,11 @@ #include #include -#include +#include #include #include +#include namespace kernel::filesystem { @@ -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 const & fd) -> kstd::ssize_t; + auto add_file(kstd::shared_ptr const & fd) -> std::expected; /** @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; + [[nodiscard]] auto file(size_t fd) const -> std::expected, kstd::error_code>; /** @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) -> std::expected; 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 ffb4a650..78afaa6d 100644 --- a/kernel/kernel/filesystem/open_file_table.tests.cpp +++ b/kernel/kernel/filesystem/open_file_table.tests.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -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() == make_error_condition(kstd::errc::invalid_argument)); } - 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() == make_error_condition(kstd::errc::invalid_argument)); } } } @@ -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() == make_error_condition(kstd::errc::invalid_argument)); } } 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/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index a5c1593d..55c83ca9 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -65,7 +65,7 @@ namespace kernel::filesystem { 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); } } @@ -95,21 +95,21 @@ namespace kernel::filesystem return dentry; } - auto vfs::close(std::string_view path) -> operation_result + auto vfs::close(std::string_view path) -> std::expected { if (auto mount = find_mount(path)) { - mount->decrement_ref_count(); - return operation_result::success; + mount.value()->decrement_ref_count(); + return {}; } - return operation_result::invalid_path; + return std::unexpected{make_error_code(vfs_errc::invalid_path)}; } - auto vfs::do_mount(std::string_view source, std::string_view target) -> operation_result + auto vfs::do_mount(std::string_view source, std::string_view target) -> std::expected { if (!path::is_valid_path(source) || !path::is_valid_path(target)) { - return operation_result::invalid_path; + return std::unexpected{make_error_code(vfs_errc::invalid_path)}; } auto [mount_point_dentry, mount_context] = resolve_path_internal(target).value_or(std::pair{nullptr, nullptr}); @@ -121,33 +121,33 @@ namespace kernel::filesystem 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 {}; } - return operation_result::invalid_filesystem; + return std::unexpected{make_error_code(vfs_errc::invalid_filesystem)}; } - return operation_result::non_existent_path; + return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; } - return operation_result::mount_point_not_found; + return std::unexpected{make_error_code(vfs_errc::mount_point_not_found)}; } - auto vfs::unmount(std::string_view path) -> operation_result + auto vfs::unmount(std::string_view path) -> std::expected { if (!path::is_valid_path(path)) { - return operation_result::invalid_path; + return std::unexpected{make_error_code(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 {}; } else if (remove_result == mount_table::operation_result::mount_not_found) { - return operation_result::mount_point_not_found; + return std::unexpected{make_error_code(vfs_errc::mount_point_not_found)}; } - return operation_result::unmount_failed; + return std::unexpected{make_error_code(vfs_errc::unmount_failed)}; } auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, @@ -284,14 +284,14 @@ namespace kernel::filesystem return std::pair{current_dentry, current_mount}; } - auto vfs::resolve_path(std::string_view path) const -> kstd::shared_ptr + auto vfs::resolve_path(std::string_view path) const -> std::expected, kstd::error_code> { - return resolve_path_internal(path).transform([](auto result) { return result.first; }).value_or(nullptr); + return resolve_path_internal(path).transform([](auto result) { return result.first; }); } - auto vfs::find_mount(std::string_view path) const -> kstd::shared_ptr + auto vfs::find_mount(std::string_view path) const -> std::expected, kstd::error_code> { - return resolve_path_internal(path).transform([](auto result) { return result.second; }).value_or(nullptr); + 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 ef26aa84..3e86eae5 100644 --- a/kernel/kernel/filesystem/vfs.hpp +++ b/kernel/kernel/filesystem/vfs.hpp @@ -19,24 +19,11 @@ 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 - }; - vfs(); /** @@ -67,24 +54,24 @@ namespace kernel::filesystem /** @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) -> std::expected; /** @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 do_mount(std::string_view source, std::string_view target) -> std::expected; /** @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) -> std::expected; private: /** @@ -99,8 +86,12 @@ namespace kernel::filesystem */ [[nodiscard]] auto resolve_path_internal(std::string_view path) const -> std::expected, kstd::shared_ptr>, kstd::error_code>; - [[nodiscard]] auto resolve_path(std::string_view path) const -> kstd::shared_ptr; - [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr; + + [[nodiscard]] auto resolve_path(std::string_view path) const + -> std::expected, kstd::error_code>; + + [[nodiscard]] auto find_mount(std::string_view path) const + -> std::expected, kstd::error_code>; auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs, diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index c5130ef4..59589633 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -1,9 +1,11 @@ #include +#include #include #include #include +#include #include #include @@ -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() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto dev = vfs.open("/dev/ram0"); REQUIRE(dev != nullptr); @@ -102,16 +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.do_mount("/dev/ram16", "/information")); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1); - REQUIRE(vfs.close(mounted_monkey_1.value()->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")); auto unmounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); - REQUIRE(unmounted_monkey_1 == nullptr); + REQUIRE(unmounted_monkey_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); @@ -119,9 +120,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("third image can be mounted in a mounted file system, unmount only if no child mount exists") { - REQUIRE(vfs.do_mount("/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.do_mount("/dev/ram16", "/information")); + REQUIRE(vfs.do_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"); @@ -129,34 +129,31 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(mounted_monkey_1); REQUIRE(mounted_fish1); - REQUIRE(vfs.close(mounted_monkey_1.value()->absolute_path()) == - kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(mounted_fish1.value()->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.do_mount("/dev/ram16", "/information")); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); 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.value()->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); } @@ -165,27 +162,26 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1); - REQUIRE(vfs.close(info_1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); + 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.do_mount("/dev/ram16", "/information")); + REQUIRE(vfs.do_mount("/dev/ram32", "/information")); auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets); - REQUIRE(vfs.close(mounted_tickets.value()->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() == make_error_condition(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") @@ -193,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.do_mount("/dev/ram16", "/")); info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 == nullptr); + REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); - REQUIRE(vfs.close(water.value()->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); @@ -214,22 +210,23 @@ 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.do_mount("/dev/ram16", "/")); info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 == nullptr); + REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); - REQUIRE(vfs.close(water.value()->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() == make_error_condition(kstd::errc::no_such_file_or_directory)); - REQUIRE(vfs.do_mount("/dev/ram32", "/") == kernel::filesystem::vfs::operation_result::non_existent_path); + REQUIRE(vfs.do_mount("/dev/ram32", "/").error() == + make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); - 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); @@ -240,58 +237,59 @@ 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.value()->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() == make_error_condition(kstd::errc::no_such_file_or_directory)); - REQUIRE(vfs.do_mount("/dev/ram0", "/") == kernel::filesystem::vfs::operation_result::success); + REQUIRE(vfs.do_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() == make_error_condition(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.do_mount("/closed.txt", "/information").error() == + make_error_code(kernel::filesystem::vfs_errc::invalid_filesystem)); } 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.do_mount("/dev/ram16", "").error() == make_error_code(kernel::filesystem::vfs_errc::invalid_path)); + REQUIRE(vfs.do_mount("/dev/ram16", "information").error() == + make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); } 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.do_mount("/dev/nonexistent", "/information").error() == + make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); } 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.do_mount("/dev/ram16", "/information/nonexistent").error() == + make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); } 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() == make_error_code(kernel::filesystem::vfs_errc::invalid_path)); + REQUIRE(vfs.unmount("information").error() == + make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); } 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() == + make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); } THEN("a file can be access if . in the path") @@ -311,7 +309,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.do_mount("/dev/ram16", "/information")); auto img = vfs.open("/information/monkey_house/caretaker/../../../../../../archiv/2024.img"); REQUIRE(img != nullptr); @@ -325,9 +323,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.do_mount("/dev/ram16", "/information")); + REQUIRE(vfs.do_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); @@ -349,10 +346,10 @@ 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.do_mount("/archiv/2024.img", "/information")); auto info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1 == nullptr); + REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); auto dentry = vfs.open("/information/sheep_1.txt"); REQUIRE(dentry != nullptr); @@ -363,20 +360,19 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); - REQUIRE(vfs.close(dentry.value()->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() == make_error_condition(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.do_mount("/archiv/2024.img", "/information")); + REQUIRE(vfs.do_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"); @@ -396,24 +392,23 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), bytes_read}; REQUIRE(buffer_as_str == "goat_1"); - REQUIRE(vfs.close(sheep_1.value()->absolute_path()) == kernel::filesystem::vfs::operation_result::success); - REQUIRE(vfs.close(goat_1.value()->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() == make_error_code(kernel::filesystem::vfs_errc::unmount_failed)); - 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() == make_error_condition(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.value()->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() == make_error_condition(kstd::errc::no_such_file_or_directory)); } } @@ -428,23 +423,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.do_mount("/dev/ram16", "/entrance")); + REQUIRE(vfs.do_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() == make_error_code(kernel::filesystem::vfs_errc::unmount_failed)); + 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.do_mount("/dev/ram16", "/entrance")); + REQUIRE(vfs.do_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")); } } @@ -492,21 +485,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() == make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); } 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() == make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); } 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() == make_error_code(kstd::errc::too_many_symbolic_link_levels)); } } @@ -516,7 +509,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.do_mount("/archiv/2024.img", "/information")); THEN("file can be opened through symbolic link pointing to the parent filesystem") { @@ -533,7 +526,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.do_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 76c05204..749040ce 100644 --- a/kernel/kernel/main.cpp +++ b/kernel/kernel/main.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -39,22 +40,22 @@ auto run_demo() -> void // 2) read from the file kstd::vector buffer_1{10}; - auto bytes_read = kapi::filesystem::read(fd_1.value(), buffer_1.data(), buffer_1.size()); - auto buffer_as_str = std::string_view{reinterpret_cast(buffer_1.data()), static_cast(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(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() == make_error_condition(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"); } @@ -78,7 +79,7 @@ auto run_demo() -> void // 6) read from the new file kstd::vector buffer_2{10}; - bytes_read = kapi::filesystem::read(fd_2.value(), 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(buffer_2.data()), static_cast(bytes_read)}; kstd::println("--> read {} bytes from /entrance/information/info_1.txt: {} ", bytes_read, buffer_as_str); @@ -96,13 +97,13 @@ auto run_demo() -> void // 8) read from the device file kstd::vector buffer_3{2}; - bytes_read = kapi::filesystem::read(fd_3.value(), 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 write_buffer{default_buffer_value, default_buffer_value}; - auto bytes_written = kapi::filesystem::write(fd_3.value(), 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 -- cgit v1.2.3 From 48b95e0b46e32f35ea6f16f41ab99286856292bf Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 12:00:39 +0200 Subject: kapi: extend panic formatting --- kernel/kapi/system.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'kernel') diff --git a/kernel/kapi/system.cpp b/kernel/kapi/system.cpp index 86c99515..23dadd3a 100644 --- a/kernel/kapi/system.cpp +++ b/kernel/kapi/system.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -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.category().name(), error.message(), location.file_name(), location.line()); + cpu::halt(); + } + } // namespace kapi::system -- cgit v1.2.3 From 34ffa4de405d053ef4b53d58e1437f2e82d152b1 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 12:18:08 +0200 Subject: kstd: make error_code formattable --- kernel/kapi/system.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/system.cpp b/kernel/kapi/system.cpp index 23dadd3a..629e5990 100644 --- a/kernel/kapi/system.cpp +++ b/kernel/kapi/system.cpp @@ -22,8 +22,8 @@ namespace kapi::system [[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.category().name(), error.message(), location.file_name(), location.line()); + kstd::println(kstd::print_sink::stderr, "[PANIC] in {} : {} ({}) @ {}:{}", location.function_name(), message, error, + location.file_name(), location.line()); cpu::halt(); } -- cgit v1.2.3 From 74e471800380573af6d63b2ad1ba95cfecbce246 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 13:50:11 +0200 Subject: kernel: initial fs driver system_error integration --- kernel/kernel/filesystem/devfs/filesystem.cpp | 20 +++-- kernel/kernel/filesystem/devfs/filesystem.hpp | 7 +- .../kernel/filesystem/devfs/filesystem.tests.cpp | 36 ++++---- kernel/kernel/filesystem/ext2/error.hpp | 96 ++++++++++++++++++++++ kernel/kernel/filesystem/ext2/filesystem.cpp | 50 ++++++----- kernel/kernel/filesystem/ext2/filesystem.hpp | 17 ++-- kernel/kernel/filesystem/ext2/filesystem.tests.cpp | 34 ++++---- kernel/kernel/filesystem/ext2/inode.cpp | 4 +- kernel/kernel/filesystem/ext2/inode.tests.cpp | 26 +++--- kernel/kernel/filesystem/filesystem.cpp | 13 +-- kernel/kernel/filesystem/filesystem.hpp | 24 ++---- kernel/kernel/filesystem/rootfs/filesystem.cpp | 10 ++- kernel/kernel/filesystem/rootfs/filesystem.hpp | 7 +- .../kernel/filesystem/rootfs/filesystem.tests.cpp | 14 ++-- kernel/kernel/filesystem/vfs.cpp | 16 ++-- .../kernel/test_support/filesystem/filesystem.cpp | 4 +- .../kernel/test_support/filesystem/filesystem.hpp | 4 +- 17 files changed, 258 insertions(+), 124 deletions(-) create mode 100644 kernel/kernel/filesystem/ext2/error.hpp (limited to 'kernel') diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp index 3b1da25c..226102ba 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.cpp @@ -4,14 +4,17 @@ #include #include #include +#include #include #include #include #include +#include #include +#include #include namespace kernel::filesystem::devfs @@ -37,25 +40,25 @@ namespace kernel::filesystem::devfs [[gnu::used]] constexpr auto registration = type_registration{}; - auto filesystem::mount(kstd::shared_ptr const &) -> operation_result + auto filesystem::mount(kstd::shared_ptr const &) -> std::expected { m_root_inode = kstd::make_shared(); build_device_inode_table(); - return operation_result::success; + return {}; } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const - -> kstd::shared_ptr + -> std::expected, kstd::error_code> { if (!parent || !parent->is_directory()) { - return nullptr; + return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; } if (parent.get() != m_root_inode.get()) { - return nullptr; + return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; } auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) { @@ -65,7 +68,12 @@ namespace kernel::filesystem::devfs } return false; }); - return (it != m_inodes.end()) ? *it : nullptr; + if (it != m_inodes.end()) + { + return *it; + } + + return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; } auto filesystem::build_device_inode_table() -> void diff --git a/kernel/kernel/filesystem/devfs/filesystem.hpp b/kernel/kernel/filesystem/devfs/filesystem.hpp index 083d248c..e96790b8 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/kernel/filesystem/devfs/filesystem.hpp @@ -6,8 +6,10 @@ #include #include +#include #include +#include #include namespace kernel::filesystem::devfs @@ -25,7 +27,8 @@ 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 const & backing_inode) -> operation_result override; + auto mount(kstd::shared_ptr const & backing_inode) + -> std::expected override; /** @brief Looks up an inode by @p name within a @p parent directory. @@ -34,7 +37,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 const & parent, std::string_view name) const - -> kstd::shared_ptr override; + -> std::expected, kstd::error_code> 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/ext2/error.hpp b/kernel/kernel/filesystem/ext2/error.hpp new file mode 100644 index 00000000..e42b714b --- /dev/null +++ b/kernel/kernel/filesystem/ext2/error.hpp @@ -0,0 +1,96 @@ +#ifndef TEACHOS_KERNEL_FILESYSTEM_EXT2_ERROR_HPP +#define TEACHOS_KERNEL_FILESYSTEM_EXT2_ERROR_HPP + +#include + +#include + +#include +#include + +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, + }; + + 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(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 index out of bounds"; + default: + return "unknown ext2 error"; + }; + } + + [[nodiscard]] constexpr auto equivalent(int code, kstd::error_condition const & condition) const noexcept + -> bool override + { + switch (static_cast(code)) + { + case ext2_errc::invalid_magic_number: + case ext2_errc::invalid_root_inode: + case ext2_errc::invalid_block_group_index: + case ext2_errc::invalid_block_index: + case ext2_errc::invalid_block_number: + if (condition.category() == kernel::filesystem::vfs_category()) + { + return condition.value() == static_cast(kernel::filesystem::vfs_errc::invalid_filesystem); + } + else if (condition.category() == kstd::generic_category()) + { + return condition.value() == static_cast(kstd::errc::io_error); + } + } + + 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(error), ext2_category()}; + } + +} // namespace kernel::filesystem::ext2 + +namespace kstd +{ + template<> + struct is_error_code_enum : std::true_type + { + }; +} // namespace kstd + +#endif diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 82c6441d..fd77a0a2 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -1,6 +1,8 @@ #include +#include #include +#include #include #include #include @@ -9,13 +11,15 @@ #include #include -#include +#include #include #include #include #include +#include #include +#include namespace kernel::filesystem::ext2 { @@ -41,15 +45,16 @@ namespace kernel::filesystem::ext2 [[gnu::used]] constexpr auto registration = type_registration{}; - auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> operation_result + auto filesystem::mount(kstd::shared_ptr const & backing_inode) + -> std::expected { - 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 (m_superblock.magic != constants::magic_number) { - return operation_result::invalid_magic_number; + return std::unexpected{make_error_code(ext2_errc::invalid_magic_number)}; } auto const blocks_per_group = m_superblock.blocks_per_group; @@ -60,36 +65,41 @@ namespace kernel::filesystem::ext2 m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset(), num_block_groups * sizeof(block_group_descriptor)); - m_root_inode = read_inode(constants::root_inode_number); + 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 std::unexpected{make_error_code(ext2_errc::invalid_root_inode)}; } - return operation_result::success; + + return {}; } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const - -> kstd::shared_ptr + -> std::expected, kstd::error_code> { if (!parent || !parent->is_directory()) { - return nullptr; + return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; } auto * ext2_parent = static_cast(parent.get()); - if (!ext2_parent) - { - return nullptr; - } - auto const & inode_data = ext2_parent->data(); kstd::vector 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(); + + if (!global_block_number) + { + return std::unexpected{make_error_code(ext2_errc::invalid_block_number)}; + } + + auto const block_offset = global_block_number.value() * block_size(); m_backing_inode->read(buffer.data(), block_offset, block_size()); auto const * entry = reinterpret_cast(buffer.data()); @@ -108,10 +118,10 @@ namespace kernel::filesystem::ext2 } } - return nullptr; + return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; } - auto filesystem::read_inode(uint32_t inode_number) const -> kstd::shared_ptr + auto filesystem::read_inode(uint32_t inode_number) const -> std::expected, kstd::error_code> { auto const inodes_per_group = m_superblock.inodes_per_group; auto const block_group_index = (inode_number - 1) / inodes_per_group; @@ -119,7 +129,7 @@ namespace kernel::filesystem::ext2 if (block_group_index >= m_block_group_descriptors.size()) { - return nullptr; + return std::unexpected{make_error_code(ext2_errc::invalid_block_group_index)}; } auto const & block_group_descriptor = m_block_group_descriptors.at(block_group_index); @@ -143,7 +153,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 { if (inode_block_index < constants::direct_block_count) { @@ -186,7 +196,7 @@ namespace kernel::filesystem::ext2 return block_number; } - return -1; + return std::unexpected{make_error_code(ext2_errc::invalid_block_index)}; } auto filesystem::read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp index fc2ba7df..da7ae64e 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/kernel/filesystem/ext2/filesystem.hpp @@ -8,12 +8,13 @@ #include #include -#include +#include #include #include #include #include +#include #include namespace kernel::filesystem::ext2 @@ -47,14 +48,15 @@ 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 const & backing_inode) -> operation_result override; + auto mount(kstd::shared_ptr const & backing_inode) + -> std::expected override; /** @brief Looks up an inode by @p name within a @p parent directory. @@ -63,7 +65,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 const & parent, std::string_view name) const - -> kstd::shared_ptr override; + -> std::expected, kstd::error_code> override; /** @brief Gets the size of a block in the filesystem. @@ -81,10 +83,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; + -> std::expected; private: struct indirect_level @@ -95,7 +97,8 @@ namespace kernel::filesystem::ext2 [[nodiscard]] auto indirect_levels() const -> std::array; - [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr; + [[nodiscard]] auto read_inode(uint32_t inode_number) const + -> std::expected, kstd::error_code>; [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t; [[nodiscard]] auto inode_size() const -> uint16_t; diff --git a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp index ed3ac1ac..9a677981 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -33,7 +34,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, auto dev_inode = kstd::make_shared(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,8 @@ 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() == + make_error_code(kernel::filesystem::ext2::ext2_errc::invalid_magic_number)); } } } @@ -100,7 +102,7 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys auto dev_inode = kstd::make_shared(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 +132,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 11f55cb6..23344a7b 100644 --- a/kernel/kernel/filesystem/ext2/inode.cpp +++ b/kernel/kernel/filesystem/ext2/inode.cpp @@ -43,7 +43,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,7 +56,7 @@ 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(buffer) + bytes_read, read_offset, diff --git a/kernel/kernel/filesystem/ext2/inode.tests.cpp b/kernel/kernel/filesystem/ext2/inode.tests.cpp index aa21f6ed..325ba956 100644 --- a/kernel/kernel/filesystem/ext2/inode.tests.cpp +++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp @@ -97,18 +97,18 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in auto dev_inode = kstd::make_shared(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(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); @@ -119,7 +119,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in THEN("reading with an offset returns the expected byte") { auto buffer = kstd::vector(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(buffer[0]) == '1'); @@ -139,7 +139,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste auto dev_inode = kstd::make_shared(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; @@ -176,7 +176,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste auto dev_inode = kstd::make_shared(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; @@ -221,7 +221,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste auto dev_inode = kstd::make_shared(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 +252,7 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") auto dev_inode = kstd::make_shared(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; @@ -313,7 +313,7 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev auto dev_inode = kstd::make_shared(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 +349,7 @@ SCENARIO("Ext2 inode get_size() correctly returns size depending on revision lev auto dev_inode = kstd::make_shared(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; diff --git a/kernel/kernel/filesystem/filesystem.cpp b/kernel/kernel/filesystem/filesystem.cpp index f0b7fd28..cb60734f 100644 --- a/kernel/kernel/filesystem/filesystem.cpp +++ b/kernel/kernel/filesystem/filesystem.cpp @@ -6,8 +6,10 @@ #include #include +#include #include +#include namespace kernel::filesystem { @@ -18,7 +20,8 @@ namespace kernel::filesystem }; } // namespace - auto filesystem::probe_and_mount(kstd::shared_ptr const & backing_inode) -> kstd::shared_ptr + auto filesystem::probe_and_mount(kstd::shared_ptr const & backing_inode) + -> std::expected, kstd::error_code> { if (!backing_inode) { @@ -28,16 +31,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 std::unexpected{make_error_code(kstd::errc::not_supported)}; } - auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> operation_result + auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> std::expected { if (!backing_inode) { @@ -45,7 +48,7 @@ namespace kernel::filesystem } m_backing_inode = backing_inode; - return operation_result::success; + return {}; } auto filesystem::root_inode() const -> kstd::shared_ptr const & diff --git a/kernel/kernel/filesystem/filesystem.hpp b/kernel/kernel/filesystem/filesystem.hpp index b818d992..f9521d1f 100644 --- a/kernel/kernel/filesystem/filesystem.hpp +++ b/kernel/kernel/filesystem/filesystem.hpp @@ -4,8 +4,10 @@ #include #include +#include #include +#include #include namespace kernel::filesystem @@ -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 const & backing_inode) -> kstd::shared_ptr; + auto static probe_and_mount(kstd::shared_ptr const & backing_inode) + -> std::expected, kstd::error_code>; /** @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 const & backing_inode) -> operation_result; + virtual auto mount(kstd::shared_ptr const & backing_inode) -> std::expected; /** @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 const & parent, std::string_view name) const - -> kstd::shared_ptr = 0; + -> std::expected, kstd::error_code> = 0; /** @brief Returns a reference to the root inode of the filesystem. diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp index 52c2cec2..06b6d5c9 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp @@ -6,7 +6,9 @@ #include #include +#include +#include #include namespace kernel::filesystem::rootfs @@ -33,15 +35,15 @@ namespace kernel::filesystem::rootfs [[gnu::used]] constexpr auto registration = type_registration{}; - auto filesystem::mount(kstd::shared_ptr const &) -> operation_result + auto filesystem::mount(kstd::shared_ptr const &) -> std::expected { m_root_inode = kstd::make_shared(); - return operation_result::success; + return {}; } auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const - -> kstd::shared_ptr + -> std::expected, kstd::error_code> { - return nullptr; + return std::unexpected{make_error_code(kstd::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 5d59486d..e05cc808 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.hpp @@ -6,8 +6,10 @@ #include #include +#include #include +#include #include namespace kernel::filesystem::rootfs @@ -25,7 +27,8 @@ 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 const & backing_inode) -> operation_result override; + auto mount(kstd::shared_ptr const & backing_inode) + -> std::expected override; /** @brief Looks up an inode by @p name within a @p parent directory. @@ -34,7 +37,7 @@ namespace kernel::filesystem::rootfs @return Always returns nullptr. */ [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const - -> kstd::shared_ptr override; + -> std::expected, kstd::error_code> override; }; } // namespace kernel::filesystem::rootfs diff --git a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp index 8f16077a..347502ca 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.tests.cpp @@ -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/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 55c83ca9..7de2b79f 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -45,7 +45,10 @@ namespace kernel::filesystem { // mount rootfs at / auto root_fs = kstd::make_shared(); - 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(nullptr, root_fs->root_inode(), "/"); auto root_mount = kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, nullptr, nullptr); @@ -53,7 +56,10 @@ namespace kernel::filesystem // mount devfs at /dev (inside rootfs, temporary, will be shadowed) auto device_fs = kstd::make_shared(); - 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 @@ -65,7 +71,7 @@ namespace kernel::filesystem { 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); } } @@ -120,7 +126,7 @@ namespace kernel::filesystem { 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); + do_mount_internal(mount_point_dentry, mount_context, *fs, source_mount_context); return {}; } return std::unexpected{make_error_code(vfs_errc::invalid_filesystem)}; @@ -240,7 +246,7 @@ namespace kernel::filesystem return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; } - next_dentry = kstd::make_shared(current_dentry, found_inode, part); + next_dentry = kstd::make_shared(current_dentry, *found_inode, part); current_dentry->add_child(next_dentry); } else if (next_dentry->has_flag(dentry::dentry_flags::is_mount_point)) diff --git a/kernel/kernel/test_support/filesystem/filesystem.cpp b/kernel/kernel/test_support/filesystem/filesystem.cpp index a4ea30bb..38cea2f1 100644 --- a/kernel/kernel/test_support/filesystem/filesystem.cpp +++ b/kernel/kernel/test_support/filesystem/filesystem.cpp @@ -4,13 +4,15 @@ #include #include +#include +#include #include namespace kernel::tests::filesystem { auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const - -> kstd::shared_ptr + -> std::expected, kstd::error_code> { return kstd::make_shared(); } diff --git a/kernel/kernel/test_support/filesystem/filesystem.hpp b/kernel/kernel/test_support/filesystem/filesystem.hpp index 5809bb5e..e6e0f416 100644 --- a/kernel/kernel/test_support/filesystem/filesystem.hpp +++ b/kernel/kernel/test_support/filesystem/filesystem.hpp @@ -5,7 +5,9 @@ #include #include +#include +#include #include namespace kernel::tests::filesystem @@ -15,7 +17,7 @@ namespace kernel::tests::filesystem filesystem() = default; [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const - -> kstd::shared_ptr override; + -> std::expected, kstd::error_code> override; }; } // namespace kernel::tests::filesystem -- cgit v1.2.3 From 44c50280e92e014c2b63380d032b23864649c744 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 14:02:45 +0200 Subject: kernel: forward path resolution error --- kernel/kernel/filesystem/vfs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 7de2b79f..56e164bd 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -243,7 +243,7 @@ namespace kernel::filesystem auto found_inode = current_fs->lookup(current_dentry->get_inode(), part); if (!found_inode) { - return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; + return std::unexpected{found_inode.error()}; } next_dentry = kstd::make_shared(current_dentry, *found_inode, part); -- cgit v1.2.3 From 29e78eb35bdd6d1a73357ec8bcf9f45645e33637 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 14:17:50 +0200 Subject: kernel/vfs: simplify do_mount --- kernel/kernel/filesystem/vfs.cpp | 34 ++++++++++++++++++++-------------- kernel/kernel/filesystem/vfs.tests.cpp | 7 +++---- 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 56e164bd..45424ee2 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -118,22 +118,28 @@ namespace kernel::filesystem return std::unexpected{make_error_code(vfs_errc::invalid_path)}; } - auto [mount_point_dentry, mount_context] = resolve_path_internal(target).value_or(std::pair{nullptr, nullptr}); - 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).value_or(std::pair{nullptr, nullptr}); - 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 {}; - } - return std::unexpected{make_error_code(vfs_errc::invalid_filesystem)}; - } - return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; + return std::unexpected{resolved_target.error()}; } - return std::unexpected{make_error_code(vfs_errc::mount_point_not_found)}; + auto [mount_point_dentry, mount_context] = *resolved_target; + + auto resolved_source = resolve_path_internal(source); + if (!resolved_source) + { + return std::unexpected{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 std::unexpected{fs.error()}; + } + + do_mount_internal(mount_point_dentry, mount_context, *fs, source_mount_context); + return {}; } auto vfs::unmount(std::string_view path) -> std::expected diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index 59589633..e4f042e7 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -256,15 +256,14 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("mount with null file system fails") { - REQUIRE(vfs.do_mount("/closed.txt", "/information").error() == - make_error_code(kernel::filesystem::vfs_errc::invalid_filesystem)); + REQUIRE(vfs.do_mount("/closed.txt", "/information").error() == make_error_condition(kstd::errc::not_supported)); } THEN("mount with invalid path fails") { REQUIRE(vfs.do_mount("/dev/ram16", "").error() == make_error_code(kernel::filesystem::vfs_errc::invalid_path)); REQUIRE(vfs.do_mount("/dev/ram16", "information").error() == - make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); + make_error_code(kernel::filesystem::vfs_errc::invalid_path)); } THEN("mount with non-existent source path fails") @@ -276,7 +275,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("mount with non-existent mount point fails") { REQUIRE(vfs.do_mount("/dev/ram16", "/information/nonexistent").error() == - make_error_code(kernel::filesystem::vfs_errc::mount_point_not_found)); + make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); } THEN("unmount with invalid path fails") -- cgit v1.2.3 From 9576497d8b3f525754e12b9a9ad7342fcf5da7ef Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 14:20:23 +0200 Subject: kernel/ext2: fix error message --- kernel/kernel/filesystem/ext2/error.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/ext2/error.hpp b/kernel/kernel/filesystem/ext2/error.hpp index e42b714b..aed33ece 100644 --- a/kernel/kernel/filesystem/ext2/error.hpp +++ b/kernel/kernel/filesystem/ext2/error.hpp @@ -42,7 +42,7 @@ namespace kernel::filesystem::ext2 case ext2_errc::invalid_block_index: return "block index out of bounds"; case ext2_errc::invalid_block_number: - return "block index out of bounds"; + return "block number out of bounds"; default: return "unknown ext2 error"; }; -- cgit v1.2.3 From b105039ed6a0be0ba3da1827e711c649edef6d8e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 14:41:46 +0200 Subject: kernel: clean up error API --- kernel/kernel/filesystem/devfs/filesystem.cpp | 7 +-- kernel/kernel/filesystem/error.hpp | 19 +++++++ kernel/kernel/filesystem/ext2/filesystem.cpp | 14 +++--- kernel/kernel/filesystem/ext2/filesystem.tests.cpp | 3 +- kernel/kernel/filesystem/filesystem.cpp | 3 +- kernel/kernel/filesystem/open_file_table.cpp | 7 +-- kernel/kernel/filesystem/open_file_table.tests.cpp | 6 +-- kernel/kernel/filesystem/rootfs/filesystem.cpp | 3 +- kernel/kernel/filesystem/vfs.cpp | 14 +++--- kernel/kernel/filesystem/vfs.tests.cpp | 58 ++++++++++------------ kernel/kernel/main.cpp | 2 +- 11 files changed, 76 insertions(+), 60 deletions(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp index 226102ba..8af12131 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.cpp @@ -53,12 +53,12 @@ namespace kernel::filesystem::devfs { if (!parent || !parent->is_directory()) { - return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; + return std::unexpected{vfs_errc::invalid_inode}; } if (parent.get() != m_root_inode.get()) { - return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; + return std::unexpected{vfs_errc::invalid_inode}; } auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) { @@ -68,12 +68,13 @@ namespace kernel::filesystem::devfs } return false; }); + if (it != m_inodes.end()) { return *it; } - return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; + return std::unexpected{vfs_errc::non_existent_path}; } auto filesystem::build_device_inode_table() -> void diff --git a/kernel/kernel/filesystem/error.hpp b/kernel/kernel/filesystem/error.hpp index 267e5b7e..041b7b98 100644 --- a/kernel/kernel/filesystem/error.hpp +++ b/kernel/kernel/filesystem/error.hpp @@ -18,6 +18,10 @@ namespace kernel::filesystem has_child_mounts, invalid_filesystem, unmount_failed, + symbolic_link_loop, + unsupported_filesystem, + invalid_file_descriptor, + invalid_inode, }; namespace detail @@ -47,6 +51,14 @@ namespace kernel::filesystem return "invalid filesystem"; case vfs_errc::unmount_failed: return "unmount failed"; + case vfs_errc::symbolic_link_loop: + 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"; default: return "unknown VFS error"; } @@ -58,6 +70,7 @@ namespace kernel::filesystem { 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::non_existent_path: case vfs_errc::mount_point_not_found: @@ -66,6 +79,12 @@ namespace kernel::filesystem 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::symbolic_link_loop: + 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); default: return kstd::error_condition{value, *this}; } diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index fd77a0a2..55da8976 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -54,7 +54,7 @@ namespace kernel::filesystem::ext2 if (m_superblock.magic != constants::magic_number) { - return std::unexpected{make_error_code(ext2_errc::invalid_magic_number)}; + return std::unexpected{ext2_errc::invalid_magic_number}; } auto const blocks_per_group = m_superblock.blocks_per_group; @@ -72,7 +72,7 @@ namespace kernel::filesystem::ext2 if (!m_root_inode || !m_root_inode->is_directory()) { - return std::unexpected{make_error_code(ext2_errc::invalid_root_inode)}; + return std::unexpected{ext2_errc::invalid_root_inode}; } return {}; @@ -83,7 +83,7 @@ namespace kernel::filesystem::ext2 { if (!parent || !parent->is_directory()) { - return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; + return std::unexpected{vfs_errc::invalid_inode}; } auto * ext2_parent = static_cast(parent.get()); @@ -96,7 +96,7 @@ namespace kernel::filesystem::ext2 if (!global_block_number) { - return std::unexpected{make_error_code(ext2_errc::invalid_block_number)}; + return std::unexpected{ext2_errc::invalid_block_number}; } auto const block_offset = global_block_number.value() * block_size(); @@ -118,7 +118,7 @@ namespace kernel::filesystem::ext2 } } - return std::unexpected{make_error_code(vfs_errc::non_existent_path)}; + return std::unexpected{vfs_errc::non_existent_path}; } auto filesystem::read_inode(uint32_t inode_number) const -> std::expected, kstd::error_code> @@ -129,7 +129,7 @@ namespace kernel::filesystem::ext2 if (block_group_index >= m_block_group_descriptors.size()) { - return std::unexpected{make_error_code(ext2_errc::invalid_block_group_index)}; + return std::unexpected{ext2_errc::invalid_block_group_index}; } auto const & block_group_descriptor = m_block_group_descriptors.at(block_group_index); @@ -196,7 +196,7 @@ namespace kernel::filesystem::ext2 return block_number; } - return std::unexpected{make_error_code(ext2_errc::invalid_block_index)}; + return std::unexpected{ext2_errc::invalid_block_index}; } auto filesystem::read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t diff --git a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp index 9a677981..1702526e 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp @@ -82,8 +82,7 @@ SCENARIO("Ext2 filesystem rejects invalid magic", "[filesystem][ext2][filesystem THEN("mount fails with invalid_magic_number") { - REQUIRE(fs.mount(dev_inode).error() == - make_error_code(kernel::filesystem::ext2::ext2_errc::invalid_magic_number)); + REQUIRE(fs.mount(dev_inode).error() == kernel::filesystem::ext2::ext2_errc::invalid_magic_number); } } } diff --git a/kernel/kernel/filesystem/filesystem.cpp b/kernel/kernel/filesystem/filesystem.cpp index cb60734f..1d15d410 100644 --- a/kernel/kernel/filesystem/filesystem.cpp +++ b/kernel/kernel/filesystem/filesystem.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -37,7 +38,7 @@ namespace kernel::filesystem } } - return std::unexpected{make_error_code(kstd::errc::not_supported)}; + return std::unexpected{vfs_errc::unsupported_filesystem}; } auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> std::expected diff --git a/kernel/kernel/filesystem/open_file_table.cpp b/kernel/kernel/filesystem/open_file_table.cpp index df5717a4..1109249a 100644 --- a/kernel/kernel/filesystem/open_file_table.cpp +++ b/kernel/kernel/filesystem/open_file_table.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -44,7 +45,7 @@ namespace kernel::filesystem { if (!file_descriptor) { - return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; + return std::unexpected{vfs_errc::invalid_file_descriptor}; } auto it = std::ranges::find_if(m_open_files, [](auto const & open_file) { return open_file == nullptr; }); @@ -62,7 +63,7 @@ namespace kernel::filesystem { if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr) { - return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; + return std::unexpected{vfs_errc::invalid_file_descriptor}; } return m_open_files.at(fd); @@ -72,7 +73,7 @@ namespace kernel::filesystem { if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr) { - return std::unexpected{make_error_code(kstd::errc::invalid_argument)}; + return std::unexpected{vfs_errc::invalid_file_descriptor}; } m_open_files.at(fd) = nullptr; diff --git a/kernel/kernel/filesystem/open_file_table.tests.cpp b/kernel/kernel/filesystem/open_file_table.tests.cpp index 78afaa6d..69188528 100644 --- a/kernel/kernel/filesystem/open_file_table.tests.cpp +++ b/kernel/kernel/filesystem/open_file_table.tests.cpp @@ -50,13 +50,13 @@ SCENARIO("Open file table add/get file", "[filesystem][open_file_table]") THEN("adding a null file descriptor returns an error") { auto fd = table.add_file(nullptr); - REQUIRE(fd.error() == make_error_condition(kstd::errc::invalid_argument)); + REQUIRE(fd.error() == kstd::errc::bad_file_descriptor); } THEN("retrieving a file descriptor with an out-of-bounds file descriptor returns an error") { auto retrieved_descriptor = table.file(1000); - REQUIRE(retrieved_descriptor.error() == make_error_condition(kstd::errc::invalid_argument)); + REQUIRE(retrieved_descriptor.error() == kstd::errc::bad_file_descriptor); } } } @@ -78,7 +78,7 @@ SCENARIO("Open file table remove file", "[filesystem][open_file_table]") THEN("the file descriptor can no longer be retrieved using the file descriptor") { auto retrieved_descriptor = table.file(*fd); - REQUIRE(retrieved_descriptor.error() == make_error_condition(kstd::errc::invalid_argument)); + REQUIRE(retrieved_descriptor.error() == kstd::errc::bad_file_descriptor); } } diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp index 06b6d5c9..4efacb6b 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -44,6 +45,6 @@ namespace kernel::filesystem::rootfs auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const -> std::expected, kstd::error_code> { - return std::unexpected{make_error_code(kstd::errc::no_such_file_or_directory)}; + return std::unexpected{vfs_errc::non_existent_path}; } } // namespace kernel::filesystem::rootfs diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 45424ee2..5ffc3468 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -108,14 +108,14 @@ namespace kernel::filesystem mount.value()->decrement_ref_count(); return {}; } - return std::unexpected{make_error_code(vfs_errc::invalid_path)}; + return std::unexpected{vfs_errc::invalid_path}; } auto vfs::do_mount(std::string_view source, std::string_view target) -> std::expected { if (!path::is_valid_path(source) || !path::is_valid_path(target)) { - return std::unexpected{make_error_code(vfs_errc::invalid_path)}; + return std::unexpected{vfs_errc::invalid_path}; } auto resolved_target = resolve_path_internal(target); @@ -146,7 +146,7 @@ namespace kernel::filesystem { if (!path::is_valid_path(path)) { - return std::unexpected{make_error_code(vfs_errc::invalid_path)}; + return std::unexpected{vfs_errc::invalid_path}; } auto remove_result = m_mount_table.remove_mount(path); @@ -156,10 +156,10 @@ namespace kernel::filesystem } else if (remove_result == mount_table::operation_result::mount_not_found) { - return std::unexpected{make_error_code(vfs_errc::mount_point_not_found)}; + return std::unexpected{vfs_errc::mount_point_not_found}; } - return std::unexpected{make_error_code(vfs_errc::unmount_failed)}; + return std::unexpected{vfs_errc::unmount_failed}; } auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, @@ -193,7 +193,7 @@ namespace kernel::filesystem { if (!path::is_valid_absolute_path(path)) { - return std::unexpected{make_error_code(vfs_errc::invalid_path)}; + return std::unexpected{vfs_errc::invalid_path}; } auto current_mount = m_mount_table.find_mount("/"); @@ -270,7 +270,7 @@ namespace kernel::filesystem { if (symlink_counter++ > constants::symloop_max) { - return std::unexpected{make_error_code(kstd::errc::too_many_symbolic_link_levels)}; + return std::unexpected{vfs_errc::symbolic_link_loop}; } kstd::vector buffer(constants::symlink_max_path_length); diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index e4f042e7..7ec70d9c 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -75,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.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + REQUIRE(image_1.error() == kstd::errc::no_such_file_or_directory); auto dev = vfs.open("/dev/ram0"); REQUIRE(dev != nullptr); @@ -112,7 +112,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/information")); auto unmounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); - REQUIRE(unmounted_monkey_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + 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); @@ -178,7 +178,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/information")); mounted_tickets = vfs.open("/information/entrance/tickets.txt"); - REQUIRE(mounted_tickets.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + 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); @@ -192,7 +192,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.do_mount("/dev/ram16", "/")); info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); @@ -213,7 +213,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.do_mount("/dev/ram16", "/")); info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); auto water = vfs.open("/monkey_house/infrastructure/water.txt"); REQUIRE(water != nullptr); @@ -221,10 +221,9 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.close(water.value()->absolute_path())); auto dev_ram_16 = vfs.open("/dev/ram16"); - REQUIRE(dev_ram_16.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + REQUIRE(dev_ram_16.error() == kstd::errc::no_such_file_or_directory); - REQUIRE(vfs.do_mount("/dev/ram32", "/").error() == - make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); + REQUIRE(vfs.do_mount("/dev/ram32", "/").error() == kstd::errc::no_such_file_or_directory); REQUIRE(vfs.unmount("/")); @@ -243,7 +242,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/")); info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); REQUIRE(vfs.do_mount("/dev/ram0", "/")); @@ -251,44 +250,39 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(info_1 != nullptr); auto dev_ram_0 = vfs.open("/dev/ram0"); - REQUIRE(dev_ram_0.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + 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").error() == make_error_condition(kstd::errc::not_supported)); + REQUIRE(vfs.do_mount("/closed.txt", "/information").error() == kstd::errc::not_supported); } THEN("mount with invalid path fails") { - REQUIRE(vfs.do_mount("/dev/ram16", "").error() == make_error_code(kernel::filesystem::vfs_errc::invalid_path)); - REQUIRE(vfs.do_mount("/dev/ram16", "information").error() == - make_error_code(kernel::filesystem::vfs_errc::invalid_path)); + REQUIRE(vfs.do_mount("/dev/ram16", "").error() == kstd::errc::invalid_argument); + REQUIRE(vfs.do_mount("/dev/ram16", "information").error() == kstd::errc::invalid_argument); } THEN("mount with non-existent source path fails") { - REQUIRE(vfs.do_mount("/dev/nonexistent", "/information").error() == - make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); + REQUIRE(vfs.do_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").error() == - make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); + REQUIRE(vfs.do_mount("/dev/ram16", "/information/nonexistent").error() == kstd::errc::no_such_file_or_directory); } THEN("unmount with invalid path fails") { - REQUIRE(vfs.unmount("").error() == make_error_code(kernel::filesystem::vfs_errc::invalid_path)); - REQUIRE(vfs.unmount("information").error() == - make_error_code(kernel::filesystem::vfs_errc::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").error() == - make_error_code(kernel::filesystem::vfs_errc::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") @@ -348,7 +342,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.do_mount("/archiv/2024.img", "/information")); auto info_1 = vfs.open("/information/info_1.txt"); - REQUIRE(info_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); auto dentry = vfs.open("/information/sheep_1.txt"); REQUIRE(dentry != nullptr); @@ -363,7 +357,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/information")); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); - REQUIRE(unmounted_sheep_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + 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 " @@ -394,11 +388,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.close(sheep_1.value()->absolute_path())); REQUIRE(vfs.close(goat_1.value()->absolute_path())); - REQUIRE(vfs.unmount("/information").error() == make_error_code(kernel::filesystem::vfs_errc::unmount_failed)); + REQUIRE(vfs.unmount("/information").error() == kstd::errc::device_or_resource_busy); REQUIRE(vfs.unmount("/information/stable")); auto unmounted_goat_1 = vfs.open("/information/stable/petting_zoo/goat_1.txt"); - REQUIRE(unmounted_goat_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + 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); @@ -407,7 +401,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.unmount("/information")); auto unmounted_sheep_1 = vfs.open("/information/sheep_1.txt"); - REQUIRE(unmounted_sheep_1.error() == make_error_condition(kstd::errc::no_such_file_or_directory)); + REQUIRE(unmounted_sheep_1.error() == kstd::errc::no_such_file_or_directory); } } @@ -425,7 +419,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(vfs.do_mount("/dev/ram16", "/entrance")); REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/enclosures")); - REQUIRE(vfs.unmount("/entrance").error() == make_error_code(kernel::filesystem::vfs_errc::unmount_failed)); + REQUIRE(vfs.unmount("/entrance").error() == kstd::errc::device_or_resource_busy); REQUIRE(vfs.unmount("/enclosures")); REQUIRE(vfs.unmount("/entrance")); } @@ -484,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.error() == make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); + 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.error() == make_error_code(kernel::filesystem::vfs_errc::non_existent_path)); + 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.error() == make_error_code(kstd::errc::too_many_symbolic_link_levels)); + REQUIRE(circular_symlink.error() == kstd::errc::too_many_symbolic_link_levels); } } diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp index 749040ce..28429b84 100644 --- a/kernel/kernel/main.cpp +++ b/kernel/kernel/main.cpp @@ -48,7 +48,7 @@ auto run_demo() -> void // 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 && fd_before_mount.error() == make_error_condition(kstd::errc::no_such_file_or_directory)) + 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"); } -- cgit v1.2.3 From b7edb751d4224161361ccb80ad8e747cd294b166 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 22:21:41 +0200 Subject: kernel/ext2: improve error mapping --- kernel/kernel/filesystem/ext2/error.hpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/ext2/error.hpp b/kernel/kernel/filesystem/ext2/error.hpp index aed33ece..885f82e6 100644 --- a/kernel/kernel/filesystem/ext2/error.hpp +++ b/kernel/kernel/filesystem/ext2/error.hpp @@ -55,19 +55,24 @@ namespace kernel::filesystem::ext2 { case ext2_errc::invalid_magic_number: case ext2_errc::invalid_root_inode: - case ext2_errc::invalid_block_group_index: - case ext2_errc::invalid_block_index: - case ext2_errc::invalid_block_number: if (condition.category() == kernel::filesystem::vfs_category()) { return condition.value() == static_cast(kernel::filesystem::vfs_errc::invalid_filesystem); } else if (condition.category() == kstd::generic_category()) + { + return condition.value() == static_cast(kstd::errc::invalid_argument); + } + break; + case ext2_errc::invalid_block_group_index: + case ext2_errc::invalid_block_index: + case ext2_errc::invalid_block_number: + if (condition.category() == kstd::generic_category()) { return condition.value() == static_cast(kstd::errc::io_error); } + break; } - return kstd::error_category::equivalent(code, condition); } } constexpr inline ext2_category_instance{}; -- cgit v1.2.3 From 2b027860ed1e75187d9c3b5ddd98957da7bd6e15 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 22:27:18 +0200 Subject: kernel/fs: clean up file system error names --- kernel/kernel/filesystem/devfs/filesystem.cpp | 2 +- kernel/kernel/filesystem/error.hpp | 20 +++++++++++++------- kernel/kernel/filesystem/ext2/filesystem.cpp | 2 +- kernel/kernel/filesystem/rootfs/filesystem.cpp | 2 +- kernel/kernel/filesystem/vfs.cpp | 2 +- 5 files changed, 17 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp index 8af12131..59a1ae9c 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.cpp @@ -74,7 +74,7 @@ namespace kernel::filesystem::devfs return *it; } - return std::unexpected{vfs_errc::non_existent_path}; + return std::unexpected{vfs_errc::no_such_file_or_directory}; } auto filesystem::build_device_inode_table() -> void diff --git a/kernel/kernel/filesystem/error.hpp b/kernel/kernel/filesystem/error.hpp index 041b7b98..678d95c5 100644 --- a/kernel/kernel/filesystem/error.hpp +++ b/kernel/kernel/filesystem/error.hpp @@ -12,16 +12,18 @@ namespace kernel::filesystem enum struct vfs_errc : int { invalid_path = 1, - non_existent_path, + no_such_file_or_directory, mount_point_not_found, mount_busy, has_child_mounts, invalid_filesystem, unmount_failed, - symbolic_link_loop, + too_many_symbolic_link_levels, unsupported_filesystem, invalid_file_descriptor, invalid_inode, + not_a_directory, + is_a_directory, }; namespace detail @@ -39,8 +41,8 @@ namespace kernel::filesystem { case vfs_errc::invalid_path: return "invalid path"; - case vfs_errc::non_existent_path: - return "path does not exist"; + 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: @@ -51,7 +53,7 @@ namespace kernel::filesystem return "invalid filesystem"; case vfs_errc::unmount_failed: return "unmount failed"; - case vfs_errc::symbolic_link_loop: + case vfs_errc::too_many_symbolic_link_levels: return "too many symbolic link levels"; case vfs_errc::unsupported_filesystem: return "unsupported filesystem"; @@ -59,6 +61,10 @@ namespace kernel::filesystem 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"; } @@ -72,14 +78,14 @@ namespace kernel::filesystem case vfs_errc::invalid_filesystem: case vfs_errc::invalid_inode: return make_error_condition(kstd::errc::invalid_argument); - case vfs_errc::non_existent_path: + 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::symbolic_link_loop: + 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); diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 55da8976..78a8aead 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -118,7 +118,7 @@ namespace kernel::filesystem::ext2 } } - return std::unexpected{vfs_errc::non_existent_path}; + return std::unexpected{vfs_errc::no_such_file_or_directory}; } auto filesystem::read_inode(uint32_t inode_number) const -> std::expected, kstd::error_code> diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp index 4efacb6b..ea2ceedf 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp @@ -45,6 +45,6 @@ namespace kernel::filesystem::rootfs auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const -> std::expected, kstd::error_code> { - return std::unexpected{vfs_errc::non_existent_path}; + return std::unexpected{vfs_errc::no_such_file_or_directory}; } } // namespace kernel::filesystem::rootfs diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 5ffc3468..aa462eae 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -270,7 +270,7 @@ namespace kernel::filesystem { if (symlink_counter++ > constants::symloop_max) { - return std::unexpected{vfs_errc::symbolic_link_loop}; + return std::unexpected{vfs_errc::too_many_symbolic_link_levels}; } kstd::vector buffer(constants::symlink_max_path_length); -- cgit v1.2.3 From ea6793ca34a77b1b5ed3a590c8aa235ac0d42ee7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 22:31:34 +0200 Subject: kernel/vfs: add missing error mappings --- kernel/kernel/filesystem/error.hpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/error.hpp b/kernel/kernel/filesystem/error.hpp index 678d95c5..56f56ce4 100644 --- a/kernel/kernel/filesystem/error.hpp +++ b/kernel/kernel/filesystem/error.hpp @@ -91,6 +91,10 @@ namespace kernel::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}; } -- cgit v1.2.3 From 12dbc8892027feceec2576c2e5dd03b30a1da2da Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 22:31:52 +0200 Subject: kernel/vfs: add early check --- kernel/kernel/filesystem/vfs.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index aa462eae..e0e79094 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -215,6 +215,11 @@ namespace kernel::filesystem auto part = path_parts_vector.back(); path_parts_vector.pop_back(); + if (!current_dentry->get_inode()->is_directory()) + { + return std::unexpected{vfs_errc::not_a_directory}; + } + if (part == ".") { continue; -- cgit v1.2.3 From 21a5d0ae7afa0345936fb5124518c679efe3df2a Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 22:35:22 +0200 Subject: kernel/fs: separate out checks --- kernel/kernel/filesystem/devfs/filesystem.cpp | 7 ++++++- kernel/kernel/filesystem/ext2/filesystem.cpp | 7 ++++++- kernel/kernel/filesystem/vfs.cpp | 8 ++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp index 59a1ae9c..d91ee1e4 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.cpp @@ -51,11 +51,16 @@ namespace kernel::filesystem::devfs auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const -> std::expected, kstd::error_code> { - if (!parent || !parent->is_directory()) + if (!parent) { return std::unexpected{vfs_errc::invalid_inode}; } + if (!parent->is_directory()) + { + return std::unexpected{vfs_errc::not_a_directory}; + } + if (parent.get() != m_root_inode.get()) { return std::unexpected{vfs_errc::invalid_inode}; diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 78a8aead..7aa2bd2d 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -81,11 +81,16 @@ namespace kernel::filesystem::ext2 auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const -> std::expected, kstd::error_code> { - if (!parent || !parent->is_directory()) + if (!parent) { return std::unexpected{vfs_errc::invalid_inode}; } + if (!parent->is_directory()) + { + return std::unexpected{vfs_errc::not_a_directory}; + } + auto * ext2_parent = static_cast(parent.get()); auto const & inode_data = ext2_parent->data(); kstd::vector buffer(block_size()); diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index e0e79094..31b9e4d0 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -158,6 +158,14 @@ namespace kernel::filesystem { return std::unexpected{vfs_errc::mount_point_not_found}; } + else if (remove_result == mount_table::operation_result::cannot_be_unmounted) + { + return std::unexpected{vfs_errc::mount_busy}; + } + else if (remove_result == mount_table::operation_result::has_child_mounts) + { + return std::unexpected{vfs_errc::has_child_mounts}; + } return std::unexpected{vfs_errc::unmount_failed}; } -- cgit v1.2.3 From 4cdbf7811ed69feac2b5561841bdfad5f5068f5e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 13 Jul 2026 22:40:43 +0200 Subject: kernel/ext2: forward block number error --- kernel/kernel/filesystem/ext2/filesystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 7aa2bd2d..5b0e0907 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -101,7 +101,7 @@ namespace kernel::filesystem::ext2 if (!global_block_number) { - return std::unexpected{ext2_errc::invalid_block_number}; + return std::unexpected{global_block_number.error()}; } auto const block_offset = global_block_number.value() * block_size(); -- cgit v1.2.3 From 6dd7107c4e2aeb65eb1e04d260bd9effd179993a Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 14 Jul 2026 14:46:32 +0200 Subject: kernel/vfs: rename do_mount to mount --- kernel/kapi/filesystem.cpp | 2 +- kernel/kernel/filesystem/vfs.cpp | 15 +++++----- kernel/kernel/filesystem/vfs.hpp | 10 +++---- kernel/kernel/filesystem/vfs.tests.cpp | 54 +++++++++++++++++----------------- 4 files changed, 41 insertions(+), 40 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index f84949da..a7c8e403 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -15,7 +15,7 @@ namespace kapi::filesystem { auto mount(std::string_view source, std::string_view target) -> std::expected { - return kernel::filesystem::vfs::get().do_mount(source, target); + return kernel::filesystem::vfs::get().mount(source, target); } auto umount(std::string_view target) -> std::expected diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 31b9e4d0..c38e19d7 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -51,7 +51,7 @@ namespace kernel::filesystem } auto root_fs_root_dentry = kstd::make_shared(nullptr, root_fs->root_inode(), "/"); - auto root_mount = kstd::make_shared(nullptr, root_fs_root_dentry, root_fs, nullptr, nullptr); + auto root_mount = kstd::make_shared(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) @@ -111,7 +111,7 @@ namespace kernel::filesystem return std::unexpected{vfs_errc::invalid_path}; } - auto vfs::do_mount(std::string_view source, std::string_view target) -> std::expected + auto vfs::mount(std::string_view source, std::string_view target) -> std::expected { if (!path::is_valid_path(source) || !path::is_valid_path(target)) { @@ -171,12 +171,13 @@ namespace kernel::filesystem } auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, - kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs, - kstd::shared_ptr const & source_mount) -> void + kstd::shared_ptr const & parent_mount, + kstd::shared_ptr const & fs, + kstd::shared_ptr const & source_mount) -> void { auto new_fs_root = kstd::make_shared(mount_point_dentry->parent(), fs->root_inode(), mount_point_dentry->name()); - auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount, source_mount); + auto new_mount = kstd::make_shared(mount_point_dentry, new_fs_root, fs, parent_mount, source_mount); m_mount_table.add_mount(new_mount); } @@ -197,7 +198,7 @@ namespace kernel::filesystem } auto vfs::resolve_path_internal(std::string_view path) const - -> std::expected, kstd::shared_ptr>, kstd::error_code> + -> std::expected, kstd::shared_ptr>, kstd::error_code> { if (!path::is_valid_absolute_path(path)) { @@ -314,7 +315,7 @@ namespace kernel::filesystem return resolve_path_internal(path).transform([](auto result) { return result.first; }); } - auto vfs::find_mount(std::string_view path) const -> std::expected, kstd::error_code> + auto vfs::find_mount(std::string_view path) const -> std::expected, kstd::error_code> { return resolve_path_internal(path).transform([](auto result) { return result.second; }); } diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp index 3e86eae5..f3f94e81 100644 --- a/kernel/kernel/filesystem/vfs.hpp +++ b/kernel/kernel/filesystem/vfs.hpp @@ -64,7 +64,7 @@ namespace kernel::filesystem @param target The path where the filesystem should be mounted. @return Nothing on success or an error code on failure. */ - auto do_mount(std::string_view source, std::string_view target) -> std::expected; + auto mount(std::string_view source, std::string_view target) -> std::expected; /** @brief Unmount the filesystem mounted at the specified @p path. @@ -85,17 +85,17 @@ namespace kernel::filesystem * - find_mount() for the mount context only. */ [[nodiscard]] auto resolve_path_internal(std::string_view path) const - -> std::expected, kstd::shared_ptr>, kstd::error_code>; + -> std::expected, kstd::shared_ptr>, kstd::error_code>; [[nodiscard]] auto resolve_path(std::string_view path) const -> std::expected, kstd::error_code>; [[nodiscard]] auto find_mount(std::string_view path) const - -> std::expected, kstd::error_code>; + -> std::expected, kstd::error_code>; auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, - kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs, - kstd::shared_ptr const & source_mount = nullptr) -> void; + kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs, + kstd::shared_ptr const & source_mount = nullptr) -> void; auto graft_persistent_device_fs(kstd::shared_ptr const & device_fs) -> void; diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index 7ec70d9c..8ef24a15 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -104,7 +104,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("second image can be mounted, data retrieved and unmounted again") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information")); + REQUIRE(vfs.mount("/dev/ram16", "/information")); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1); @@ -120,8 +120,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("third image can be mounted in a mounted file system, unmount only if no child mount exists") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information")); - REQUIRE(vfs.do_mount("/dev/ram32", "/information/monkey_house/infrastructure")); + 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"); @@ -139,7 +139,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("image can be mounted, unmount only if no files are open") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information")); + REQUIRE(vfs.mount("/dev/ram16", "/information")); auto mounted_monkey_1 = vfs.open("/information/monkey_house/monkey_1.txt"); REQUIRE(mounted_monkey_1); @@ -168,8 +168,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("images can be stacked mounted and correct file system is unmounted again") { - REQUIRE(vfs.do_mount("/dev/ram16", "/information")); - REQUIRE(vfs.do_mount("/dev/ram32", "/information")); + REQUIRE(vfs.mount("/dev/ram16", "/information")); + REQUIRE(vfs.mount("/dev/ram32", "/information")); auto mounted_tickets = vfs.open("/information/entrance/tickets.txt"); REQUIRE(mounted_tickets); @@ -189,7 +189,7 @@ 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", "/")); + REQUIRE(vfs.mount("/dev/ram16", "/")); info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); @@ -210,7 +210,7 @@ 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", "/")); + REQUIRE(vfs.mount("/dev/ram16", "/")); info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); @@ -223,7 +223,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto dev_ram_16 = vfs.open("/dev/ram16"); REQUIRE(dev_ram_16.error() == kstd::errc::no_such_file_or_directory); - REQUIRE(vfs.do_mount("/dev/ram32", "/").error() == kstd::errc::no_such_file_or_directory); + REQUIRE(vfs.mount("/dev/ram32", "/").error() == kstd::errc::no_such_file_or_directory); REQUIRE(vfs.unmount("/")); @@ -244,7 +244,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); - REQUIRE(vfs.do_mount("/dev/ram0", "/")); + REQUIRE(vfs.mount("/dev/ram0", "/")); info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1 != nullptr); @@ -255,23 +255,23 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("mount with null file system fails") { - REQUIRE(vfs.do_mount("/closed.txt", "/information").error() == kstd::errc::not_supported); + REQUIRE(vfs.mount("/closed.txt", "/information").error() == kstd::errc::not_supported); } THEN("mount with invalid path fails") { - REQUIRE(vfs.do_mount("/dev/ram16", "").error() == kstd::errc::invalid_argument); - REQUIRE(vfs.do_mount("/dev/ram16", "information").error() == kstd::errc::invalid_argument); + 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").error() == kstd::errc::no_such_file_or_directory); + 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").error() == kstd::errc::no_such_file_or_directory); + REQUIRE(vfs.mount("/dev/ram16", "/information/nonexistent").error() == kstd::errc::no_such_file_or_directory); } THEN("unmount with invalid path fails") @@ -302,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")); + REQUIRE(vfs.mount("/dev/ram16", "/information")); auto img = vfs.open("/information/monkey_house/caretaker/../../../../../../archiv/2024.img"); REQUIRE(img != nullptr); @@ -316,8 +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")); - REQUIRE(vfs.do_mount("/archiv/2024.img", "/information/monkey_house/infrastructure")); + 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); @@ -339,7 +339,7 @@ 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")); + REQUIRE(vfs.mount("/archiv/2024.img", "/information")); auto info_1 = vfs.open("/information/info_1.txt"); REQUIRE(info_1.error() == kstd::errc::no_such_file_or_directory); @@ -364,8 +364,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS "mounted, files can be read and unmounted again") { auto & vfs = kernel::filesystem::vfs::get(); - REQUIRE(vfs.do_mount("/archiv/2024.img", "/information")); - REQUIRE(vfs.do_mount("/archiv/2025.img", "/information/stable")); + 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"); @@ -416,8 +416,8 @@ 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")); - REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/enclosures")); + REQUIRE(vfs.mount("/dev/ram16", "/entrance")); + REQUIRE(vfs.mount("/entrance/archiv/2024.img", "/enclosures")); REQUIRE(vfs.unmount("/entrance").error() == kstd::errc::device_or_resource_busy); REQUIRE(vfs.unmount("/enclosures")); @@ -426,8 +426,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS THEN("can mount filesystem onto the directory that contains it") { - REQUIRE(vfs.do_mount("/dev/ram16", "/entrance")); - REQUIRE(vfs.do_mount("/entrance/archiv/2024.img", "/entrance")); + REQUIRE(vfs.mount("/dev/ram16", "/entrance")); + REQUIRE(vfs.mount("/entrance/archiv/2024.img", "/entrance")); REQUIRE(vfs.unmount("/entrance")); REQUIRE(vfs.unmount("/entrance")); @@ -502,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(); - REQUIRE(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") { @@ -519,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(); - REQUIRE(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") -- cgit v1.2.3 From 5d98c13c0a1aa1e5415dbe820d7b537477b79c18 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 14 Jul 2026 14:54:39 +0200 Subject: kernel/vfs: extract type aliases --- kernel/kernel/filesystem/vfs.cpp | 14 ++++++-------- kernel/kernel/filesystem/vfs.hpp | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 17 deletions(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index c38e19d7..40f2c3aa 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -88,7 +88,7 @@ namespace kernel::filesystem return *active_vfs; } - auto vfs::open(std::string_view path) -> std::expected, kstd::error_code> + auto vfs::open(std::string_view path) -> std::expected { auto resolved_path = resolve_path_internal(path); if (!resolved_path) @@ -170,10 +170,8 @@ namespace kernel::filesystem return std::unexpected{vfs_errc::unmount_failed}; } - auto vfs::do_mount_internal(kstd::shared_ptr const & mount_point_dentry, - kstd::shared_ptr const & parent_mount, - kstd::shared_ptr const & fs, - kstd::shared_ptr 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(mount_point_dentry->parent(), fs->root_inode(), mount_point_dentry->name()); @@ -198,7 +196,7 @@ namespace kernel::filesystem } auto vfs::resolve_path_internal(std::string_view path) const - -> std::expected, kstd::shared_ptr>, kstd::error_code> + -> std::expected, kstd::error_code> { if (!path::is_valid_absolute_path(path)) { @@ -310,12 +308,12 @@ namespace kernel::filesystem return std::pair{current_dentry, current_mount}; } - auto vfs::resolve_path(std::string_view path) const -> std::expected, kstd::error_code> + auto vfs::resolve_path(std::string_view path) const -> std::expected { return resolve_path_internal(path).transform([](auto result) { return result.first; }); } - auto vfs::find_mount(std::string_view path) const -> std::expected, kstd::error_code> + auto vfs::find_mount(std::string_view path) const -> std::expected { return resolve_path_internal(path).transform([](auto result) { return result.second; }); } diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp index f3f94e81..2645fe14 100644 --- a/kernel/kernel/filesystem/vfs.hpp +++ b/kernel/kernel/filesystem/vfs.hpp @@ -24,6 +24,10 @@ namespace kernel::filesystem */ struct vfs { + using dentry_ptr = kstd::shared_ptr; + using mount_ptr = kstd::shared_ptr; + using fs_ptr = kstd::shared_ptr; + vfs(); /** @@ -49,7 +53,7 @@ namespace kernel::filesystem @param path The path to the file to open. @return A shared pointer to the dentry on success or an error code on failure. */ - auto open(std::string_view path) -> std::expected, kstd::error_code>; + auto open(std::string_view path) -> std::expected; /** @brief Close a file by its associated @p path. @@ -85,17 +89,14 @@ namespace kernel::filesystem * - find_mount() for the mount context only. */ [[nodiscard]] auto resolve_path_internal(std::string_view path) const - -> std::expected, kstd::shared_ptr>, kstd::error_code>; + -> std::expected, kstd::error_code>; - [[nodiscard]] auto resolve_path(std::string_view path) const - -> std::expected, kstd::error_code>; + [[nodiscard]] auto resolve_path(std::string_view path) const -> std::expected; - [[nodiscard]] auto find_mount(std::string_view path) const - -> std::expected, kstd::error_code>; + [[nodiscard]] auto find_mount(std::string_view path) const -> std::expected; - auto do_mount_internal(kstd::shared_ptr const & mount_point_dentry, - kstd::shared_ptr const & parent_mount, kstd::shared_ptr const & fs, - kstd::shared_ptr 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 const & device_fs) -> void; -- cgit v1.2.3 From af017fa7983e6730b2f8fb6acee221dd39c02b7a Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 14 Jul 2026 15:27:49 +0200 Subject: kstd: extract result helper alias --- kernel/kernel/filesystem/devfs/filesystem.cpp | 16 ++++---- kernel/kernel/filesystem/devfs/filesystem.hpp | 7 ++-- kernel/kernel/filesystem/ext2/filesystem.cpp | 24 ++++++------ kernel/kernel/filesystem/ext2/filesystem.hpp | 12 +++--- kernel/kernel/filesystem/filesystem.cpp | 10 ++--- kernel/kernel/filesystem/filesystem.hpp | 8 ++-- kernel/kernel/filesystem/open_file_table.cpp | 18 ++++----- kernel/kernel/filesystem/open_file_table.hpp | 8 ++-- kernel/kernel/filesystem/rootfs/filesystem.cpp | 10 ++--- kernel/kernel/filesystem/rootfs/filesystem.hpp | 7 ++-- kernel/kernel/filesystem/vfs.cpp | 52 +++++++++++++------------- kernel/kernel/filesystem/vfs.hpp | 16 ++++---- 12 files changed, 92 insertions(+), 96 deletions(-) (limited to 'kernel') diff --git a/kernel/kernel/filesystem/devfs/filesystem.cpp b/kernel/kernel/filesystem/devfs/filesystem.cpp index d91ee1e4..7ffcb3c4 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.cpp +++ b/kernel/kernel/filesystem/devfs/filesystem.cpp @@ -11,10 +11,10 @@ #include #include +#include #include #include -#include #include namespace kernel::filesystem::devfs @@ -40,30 +40,30 @@ namespace kernel::filesystem::devfs [[gnu::used]] constexpr auto registration = type_registration{}; - auto filesystem::mount(kstd::shared_ptr const &) -> std::expected + auto filesystem::mount(kstd::shared_ptr const &) -> kstd::result { m_root_inode = kstd::make_shared(); build_device_inode_table(); - return {}; + return kstd::success(); } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const - -> std::expected, kstd::error_code> + -> kstd::result> { if (!parent) { - return std::unexpected{vfs_errc::invalid_inode}; + return kstd::failure(vfs_errc::invalid_inode); } if (!parent->is_directory()) { - return std::unexpected{vfs_errc::not_a_directory}; + return kstd::failure(vfs_errc::not_a_directory); } if (parent.get() != m_root_inode.get()) { - return std::unexpected{vfs_errc::invalid_inode}; + return kstd::failure(vfs_errc::invalid_inode); } auto it = std::ranges::find_if(m_inodes, [&](auto const & dev_node) { @@ -79,7 +79,7 @@ namespace kernel::filesystem::devfs return *it; } - return std::unexpected{vfs_errc::no_such_file_or_directory}; + 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 e96790b8..dadeaf7d 100644 --- a/kernel/kernel/filesystem/devfs/filesystem.hpp +++ b/kernel/kernel/filesystem/devfs/filesystem.hpp @@ -6,10 +6,10 @@ #include #include +#include #include #include -#include #include namespace kernel::filesystem::devfs @@ -27,8 +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 const & backing_inode) - -> std::expected override; + auto mount(kstd::shared_ptr const & backing_inode) -> kstd::result override; /** @brief Looks up an inode by @p name within a @p parent directory. @@ -37,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 const & parent, std::string_view name) const - -> std::expected, kstd::error_code> override; + -> kstd::result> override; private: auto build_device_inode_table() -> void; diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 5b0e0907..4195ad05 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -45,8 +46,7 @@ namespace kernel::filesystem::ext2 [[gnu::used]] constexpr auto registration = type_registration{}; - auto filesystem::mount(kstd::shared_ptr const & backing_inode) - -> std::expected + auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> kstd::result { std::ignore = kernel::filesystem::filesystem::mount(backing_inode); @@ -54,7 +54,7 @@ namespace kernel::filesystem::ext2 if (m_superblock.magic != constants::magic_number) { - return std::unexpected{ext2_errc::invalid_magic_number}; + return kstd::failure(ext2_errc::invalid_magic_number); } auto const blocks_per_group = m_superblock.blocks_per_group; @@ -72,23 +72,23 @@ namespace kernel::filesystem::ext2 if (!m_root_inode || !m_root_inode->is_directory()) { - return std::unexpected{ext2_errc::invalid_root_inode}; + return kstd::failure(ext2_errc::invalid_root_inode); } return {}; } auto filesystem::lookup(kstd::shared_ptr const & parent, std::string_view name) const - -> std::expected, kstd::error_code> + -> kstd::result> { if (!parent) { - return std::unexpected{vfs_errc::invalid_inode}; + return kstd::failure(vfs_errc::invalid_inode); } if (!parent->is_directory()) { - return std::unexpected{vfs_errc::not_a_directory}; + return kstd::failure(vfs_errc::not_a_directory); } auto * ext2_parent = static_cast(parent.get()); @@ -101,7 +101,7 @@ namespace kernel::filesystem::ext2 if (!global_block_number) { - return std::unexpected{global_block_number.error()}; + return kstd::failure(global_block_number.error()); } auto const block_offset = global_block_number.value() * block_size(); @@ -123,10 +123,10 @@ namespace kernel::filesystem::ext2 } } - return std::unexpected{vfs_errc::no_such_file_or_directory}; + return kstd::failure(vfs_errc::no_such_file_or_directory); } - auto filesystem::read_inode(uint32_t inode_number) const -> std::expected, kstd::error_code> + auto filesystem::read_inode(uint32_t inode_number) const -> kstd::result> { auto const inodes_per_group = m_superblock.inodes_per_group; auto const block_group_index = (inode_number - 1) / inodes_per_group; @@ -134,7 +134,7 @@ namespace kernel::filesystem::ext2 if (block_group_index >= m_block_group_descriptors.size()) { - return std::unexpected{ext2_errc::invalid_block_group_index}; + return kstd::failure(ext2_errc::invalid_block_group_index); } auto const & block_group_descriptor = m_block_group_descriptors.at(block_group_index); @@ -201,7 +201,7 @@ namespace kernel::filesystem::ext2 return block_number; } - return std::unexpected{ext2_errc::invalid_block_index}; + 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 diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp index da7ae64e..58620596 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/kernel/filesystem/ext2/filesystem.hpp @@ -8,13 +8,13 @@ #include #include +#include #include #include #include #include #include -#include #include namespace kernel::filesystem::ext2 @@ -55,8 +55,7 @@ namespace kernel::filesystem::ext2 @param backing_inode The backing inode to mount. @return The result of the mount operation. */ - auto mount(kstd::shared_ptr const & backing_inode) - -> std::expected override; + auto mount(kstd::shared_ptr const & backing_inode) -> kstd::result override; /** @brief Looks up an inode by @p name within a @p parent directory. @@ -65,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 const & parent, std::string_view name) const - -> std::expected, kstd::error_code> override; + -> kstd::result> override; /** @brief Gets the size of a block in the filesystem. @@ -86,7 +85,7 @@ namespace kernel::filesystem::ext2 @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 - -> std::expected; + -> kstd::result; private: struct indirect_level @@ -97,8 +96,7 @@ namespace kernel::filesystem::ext2 [[nodiscard]] auto indirect_levels() const -> std::array; - [[nodiscard]] auto read_inode(uint32_t inode_number) const - -> std::expected, kstd::error_code>; + [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::result>; [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t; [[nodiscard]] auto inode_size() const -> uint16_t; diff --git a/kernel/kernel/filesystem/filesystem.cpp b/kernel/kernel/filesystem/filesystem.cpp index 1d15d410..ac0d0ebc 100644 --- a/kernel/kernel/filesystem/filesystem.cpp +++ b/kernel/kernel/filesystem/filesystem.cpp @@ -7,10 +7,10 @@ #include #include +#include #include #include -#include namespace kernel::filesystem { @@ -22,7 +22,7 @@ namespace kernel::filesystem } // namespace auto filesystem::probe_and_mount(kstd::shared_ptr const & backing_inode) - -> std::expected, kstd::error_code> + -> kstd::result> { if (!backing_inode) { @@ -38,10 +38,10 @@ namespace kernel::filesystem } } - return std::unexpected{vfs_errc::unsupported_filesystem}; + return kstd::failure(vfs_errc::unsupported_filesystem); } - auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> std::expected + auto filesystem::mount(kstd::shared_ptr const & backing_inode) -> kstd::result { if (!backing_inode) { @@ -49,7 +49,7 @@ namespace kernel::filesystem } m_backing_inode = backing_inode; - return {}; + return kstd::success(); } auto filesystem::root_inode() const -> kstd::shared_ptr const & diff --git a/kernel/kernel/filesystem/filesystem.hpp b/kernel/kernel/filesystem/filesystem.hpp index f9521d1f..1264d00d 100644 --- a/kernel/kernel/filesystem/filesystem.hpp +++ b/kernel/kernel/filesystem/filesystem.hpp @@ -4,10 +4,10 @@ #include #include +#include #include #include -#include #include namespace kernel::filesystem @@ -32,7 +32,7 @@ namespace kernel::filesystem @warning Panics if @p backing_inode is null. */ auto static probe_and_mount(kstd::shared_ptr const & backing_inode) - -> std::expected, kstd::error_code>; + -> kstd::result>; /** @brief Initializes the filesystem with the given @p backing_inode. @@ -40,7 +40,7 @@ namespace kernel::filesystem representing the block device or another inode which contains the filesystem data.) @return Nothing on success, and error otherwise. */ - virtual auto mount(kstd::shared_ptr const & backing_inode) -> std::expected; + virtual auto mount(kstd::shared_ptr const & backing_inode) -> kstd::result; /** @brief Looks up a child inode within the given @p parent inode with the specified @p name. This method must be @@ -51,7 +51,7 @@ namespace kernel::filesystem @return A pointer to the requested child inode, an error otherwise. */ [[nodiscard]] virtual auto lookup(kstd::shared_ptr const & parent, std::string_view name) const - -> std::expected, kstd::error_code> = 0; + -> kstd::result> = 0; /** @brief Returns a reference to the root inode of the filesystem. diff --git a/kernel/kernel/filesystem/open_file_table.cpp b/kernel/kernel/filesystem/open_file_table.cpp index 1109249a..f33fed2e 100644 --- a/kernel/kernel/filesystem/open_file_table.cpp +++ b/kernel/kernel/filesystem/open_file_table.cpp @@ -6,11 +6,11 @@ #include #include +#include #include #include #include -#include #include namespace @@ -41,11 +41,11 @@ namespace kernel::filesystem } auto open_file_table::add_file(kstd::shared_ptr const & file_descriptor) - -> std::expected + -> kstd::result { if (!file_descriptor) { - return std::unexpected{vfs_errc::invalid_file_descriptor}; + 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; }); @@ -59,25 +59,25 @@ namespace kernel::filesystem return m_open_files.size() - 1; } - auto open_file_table::file(size_t fd) const -> std::expected, kstd::error_code> + auto open_file_table::file(size_t fd) const -> kstd::result> { if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr) { - return std::unexpected{vfs_errc::invalid_file_descriptor}; + 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) -> std::expected + auto open_file_table::remove_file(size_t fd) -> kstd::result { if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr) { - return std::unexpected{vfs_errc::invalid_file_descriptor}; + return kstd::failure(vfs_errc::invalid_file_descriptor); } m_open_files.at(fd) = nullptr; - return 0; + return kstd::success(0); } } // namespace kernel::filesystem diff --git a/kernel/kernel/filesystem/open_file_table.hpp b/kernel/kernel/filesystem/open_file_table.hpp index efdaf578..a2c0e028 100644 --- a/kernel/kernel/filesystem/open_file_table.hpp +++ b/kernel/kernel/filesystem/open_file_table.hpp @@ -4,11 +4,11 @@ #include #include +#include #include #include #include -#include namespace kernel::filesystem { @@ -41,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 const & fd) -> std::expected; + auto add_file(kstd::shared_ptr const & fd) -> kstd::result; /** @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 -> std::expected, kstd::error_code>; + [[nodiscard]] auto file(size_t fd) const -> kstd::result>; /** @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) -> std::expected; + auto remove_file(size_t fd) -> kstd::result; private: open_file_table() = default; diff --git a/kernel/kernel/filesystem/rootfs/filesystem.cpp b/kernel/kernel/filesystem/rootfs/filesystem.cpp index ea2ceedf..fef43e28 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.cpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.cpp @@ -7,9 +7,9 @@ #include #include +#include #include -#include #include namespace kernel::filesystem::rootfs @@ -36,15 +36,15 @@ namespace kernel::filesystem::rootfs [[gnu::used]] constexpr auto registration = type_registration{}; - auto filesystem::mount(kstd::shared_ptr const &) -> std::expected + auto filesystem::mount(kstd::shared_ptr const &) -> kstd::result { m_root_inode = kstd::make_shared(); - return {}; + return kstd::success(); } auto filesystem::lookup(kstd::shared_ptr const &, std::string_view) const - -> std::expected, kstd::error_code> + -> kstd::result> { - return std::unexpected{vfs_errc::no_such_file_or_directory}; + 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 e05cc808..8507d8b8 100644 --- a/kernel/kernel/filesystem/rootfs/filesystem.hpp +++ b/kernel/kernel/filesystem/rootfs/filesystem.hpp @@ -5,11 +5,11 @@ #include #include +#include #include #include #include -#include #include namespace kernel::filesystem::rootfs @@ -27,8 +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 const & backing_inode) - -> std::expected override; + auto mount(kstd::shared_ptr const & backing_inode) -> kstd::result override; /** @brief Looks up an inode by @p name within a @p parent directory. @@ -37,7 +36,7 @@ namespace kernel::filesystem::rootfs @return Always returns nullptr. */ [[nodiscard]] auto lookup(kstd::shared_ptr const & parent, std::string_view name) const - -> std::expected, kstd::error_code> override; + -> kstd::result> override; }; } // namespace kernel::filesystem::rootfs diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 40f2c3aa..9aa8b2df 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -88,12 +89,12 @@ namespace kernel::filesystem return *active_vfs; } - auto vfs::open(std::string_view path) -> std::expected + auto vfs::open(std::string_view path) -> kstd::result { auto resolved_path = resolve_path_internal(path); if (!resolved_path) { - return std::unexpected{resolved_path.error()}; + return kstd::failure(resolved_path.error()); } auto [dentry, mount] = resolved_path.value(); @@ -101,73 +102,73 @@ namespace kernel::filesystem return dentry; } - auto vfs::close(std::string_view path) -> std::expected + auto vfs::close(std::string_view path) -> kstd::result { if (auto mount = find_mount(path)) { mount.value()->decrement_ref_count(); - return {}; + return kstd::success(); } - return std::unexpected{vfs_errc::invalid_path}; + return kstd::failure(vfs_errc::invalid_path); } - auto vfs::mount(std::string_view source, std::string_view target) -> std::expected + auto vfs::mount(std::string_view source, std::string_view target) -> kstd::result { if (!path::is_valid_path(source) || !path::is_valid_path(target)) { - return std::unexpected{vfs_errc::invalid_path}; + return kstd::failure(vfs_errc::invalid_path); } auto resolved_target = resolve_path_internal(target); if (!resolved_target) { - return std::unexpected{resolved_target.error()}; + 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 std::unexpected{resolved_source.error()}; + 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 std::unexpected{fs.error()}; + return kstd::failure(fs.error()); } do_mount_internal(mount_point_dentry, mount_context, *fs, source_mount_context); - return {}; + return kstd::success(); } - auto vfs::unmount(std::string_view path) -> std::expected + auto vfs::unmount(std::string_view path) -> kstd::result { if (!path::is_valid_path(path)) { - return std::unexpected{vfs_errc::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 {}; + return kstd::success(); } else if (remove_result == mount_table::operation_result::mount_not_found) { - return std::unexpected{vfs_errc::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 std::unexpected{vfs_errc::mount_busy}; + return kstd::failure(vfs_errc::mount_busy); } else if (remove_result == mount_table::operation_result::has_child_mounts) { - return std::unexpected{vfs_errc::has_child_mounts}; + return kstd::failure(vfs_errc::has_child_mounts); } - return std::unexpected{vfs_errc::unmount_failed}; + return kstd::failure(vfs_errc::unmount_failed); } auto vfs::do_mount_internal(dentry_ptr const & mount_point_dentry, mount_ptr const & parent_mount, fs_ptr const & fs, @@ -195,12 +196,11 @@ namespace kernel::filesystem } } - auto vfs::resolve_path_internal(std::string_view path) const - -> std::expected, kstd::error_code> + auto vfs::resolve_path_internal(std::string_view path) const -> kstd::result> { if (!path::is_valid_absolute_path(path)) { - return std::unexpected{vfs_errc::invalid_path}; + return kstd::failure(vfs_errc::invalid_path); } auto current_mount = m_mount_table.find_mount("/"); @@ -224,7 +224,7 @@ namespace kernel::filesystem if (!current_dentry->get_inode()->is_directory()) { - return std::unexpected{vfs_errc::not_a_directory}; + return kstd::failure(vfs_errc::not_a_directory); } if (part == ".") @@ -261,7 +261,7 @@ namespace kernel::filesystem auto found_inode = current_fs->lookup(current_dentry->get_inode(), part); if (!found_inode) { - return std::unexpected{found_inode.error()}; + return kstd::failure(found_inode.error()); } next_dentry = kstd::make_shared(current_dentry, *found_inode, part); @@ -282,7 +282,7 @@ namespace kernel::filesystem { if (symlink_counter++ > constants::symloop_max) { - return std::unexpected{vfs_errc::too_many_symbolic_link_levels}; + return kstd::failure(vfs_errc::too_many_symbolic_link_levels); } kstd::vector buffer(constants::symlink_max_path_length); @@ -308,12 +308,12 @@ namespace kernel::filesystem return std::pair{current_dentry, current_mount}; } - auto vfs::resolve_path(std::string_view path) const -> std::expected + auto vfs::resolve_path(std::string_view path) const -> kstd::result { return resolve_path_internal(path).transform([](auto result) { return result.first; }); } - auto vfs::find_mount(std::string_view path) const -> std::expected + auto vfs::find_mount(std::string_view path) const -> kstd::result { return resolve_path_internal(path).transform([](auto result) { return result.second; }); } diff --git a/kernel/kernel/filesystem/vfs.hpp b/kernel/kernel/filesystem/vfs.hpp index 2645fe14..9dfd3637 100644 --- a/kernel/kernel/filesystem/vfs.hpp +++ b/kernel/kernel/filesystem/vfs.hpp @@ -8,9 +8,9 @@ #include #include +#include #include -#include #include #include @@ -53,14 +53,14 @@ namespace kernel::filesystem @param path The path to the file to open. @return A shared pointer to the dentry on success or an error code on failure. */ - auto open(std::string_view path) -> std::expected; + auto open(std::string_view path) -> kstd::result; /** @brief Close a file by its associated @p path. @param path The path to the file to close. @return Nothing on success or an error code on failure. */ - auto close(std::string_view path) -> std::expected; + auto close(std::string_view path) -> kstd::result; /** @brief Mount a @p source path to a specific @p target path. @@ -68,14 +68,14 @@ namespace kernel::filesystem @param target The path where the filesystem should be mounted. @return Nothing on success or an error code on failure. */ - auto mount(std::string_view source, std::string_view target) -> std::expected; + auto mount(std::string_view source, std::string_view target) -> kstd::result; /** @brief Unmount the filesystem mounted at the specified @p path. @param path The path where the filesystem is mounted. @return Nothing on success or an error code on failure. */ - auto unmount(std::string_view path) -> std::expected; + auto unmount(std::string_view path) -> kstd::result; private: /** @@ -89,11 +89,11 @@ namespace kernel::filesystem * - find_mount() for the mount context only. */ [[nodiscard]] auto resolve_path_internal(std::string_view path) const - -> std::expected, kstd::error_code>; + -> kstd::result>; - [[nodiscard]] auto resolve_path(std::string_view path) const -> std::expected; + [[nodiscard]] auto resolve_path(std::string_view path) const -> kstd::result; - [[nodiscard]] auto find_mount(std::string_view path) const -> std::expected; + [[nodiscard]] auto find_mount(std::string_view path) const -> kstd::result; 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; -- cgit v1.2.3 From 55adee63740c489c7fe6e639d5e35d0bc46f1f8c Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 14 Jul 2026 18:39:45 +0200 Subject: kernel/vfs: expand error_code integration --- kernel/kapi/filesystem.cpp | 7 ++-- kernel/kernel/filesystem/devfs/inode.cpp | 6 ++- kernel/kernel/filesystem/devfs/inode.hpp | 6 ++- kernel/kernel/filesystem/device_inode.cpp | 5 ++- kernel/kernel/filesystem/device_inode.hpp | 7 ++-- kernel/kernel/filesystem/ext2/error.hpp | 8 ++++ kernel/kernel/filesystem/ext2/filesystem.cpp | 43 ++++++++++++++++++---- kernel/kernel/filesystem/ext2/filesystem.hpp | 2 +- kernel/kernel/filesystem/ext2/inode.cpp | 16 +++++--- kernel/kernel/filesystem/ext2/inode.hpp | 5 ++- kernel/kernel/filesystem/ext2/inode.tests.cpp | 14 ++++--- kernel/kernel/filesystem/inode.hpp | 6 ++- kernel/kernel/filesystem/open_file_descriptor.cpp | 31 ++++++++++++---- kernel/kernel/filesystem/open_file_descriptor.hpp | 5 ++- .../filesystem/open_file_descriptor.tests.cpp | 4 +- kernel/kernel/filesystem/open_file_table.cpp | 4 +- kernel/kernel/filesystem/open_file_table.hpp | 2 +- kernel/kernel/filesystem/rootfs/inode.cpp | 6 ++- kernel/kernel/filesystem/rootfs/inode.hpp | 5 ++- kernel/kernel/filesystem/vfs.cpp | 7 +++- kernel/kernel/filesystem/vfs.tests.cpp | 6 +-- kernel/kernel/main.cpp | 2 +- kernel/kernel/test_support/filesystem/inode.cpp | 6 ++- kernel/kernel/test_support/filesystem/inode.hpp | 6 ++- 24 files changed, 145 insertions(+), 64 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index a7c8e403..efde1336 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -37,20 +37,19 @@ namespace kapi::filesystem .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); }) - .transform([](auto) { return; }); + .and_then([=]() { return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); }); } auto read(size_t file_descriptor, void * buffer, size_t size) -> std::expected { - return kernel::filesystem::open_file_table::get().file(file_descriptor).transform([=](auto descriptor) { + 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) -> std::expected { - return kernel::filesystem::open_file_table::get().file(file_descriptor).transform([=](auto descriptor) { + return kernel::filesystem::open_file_table::get().file(file_descriptor).and_then([=](auto descriptor) { return descriptor->write(buffer, size); }); } 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 +#include + #include 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 { return 0; } - auto inode::write(void const *, size_t, size_t) -> size_t + auto inode::write(void const *, size_t, size_t) -> kstd::result { 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 +#include + #include 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 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 override; /** @brief Check if this inode represents a directory. diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp index 091b5499..644e3df7 100644 --- a/kernel/kernel/filesystem/device_inode.cpp +++ b/kernel/kernel/filesystem/device_inode.cpp @@ -6,6 +6,7 @@ #include #include +#include #include @@ -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 { 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 { if (m_device->is_block_device()) { diff --git a/kernel/kernel/filesystem/device_inode.hpp b/kernel/kernel/filesystem/device_inode.hpp index b461f225..5b22366a 100644 --- a/kernel/kernel/filesystem/device_inode.hpp +++ b/kernel/kernel/filesystem/device_inode.hpp @@ -6,6 +6,7 @@ #include #include +#include #include @@ -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 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 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/ext2/error.hpp b/kernel/kernel/filesystem/ext2/error.hpp index 885f82e6..79f40517 100644 --- a/kernel/kernel/filesystem/ext2/error.hpp +++ b/kernel/kernel/filesystem/ext2/error.hpp @@ -18,6 +18,8 @@ namespace kernel::filesystem::ext2 invalid_block_group_index, invalid_block_index, invalid_block_number, + failed_to_read_superblock, + failed_to_read_block_group_descriptors, }; namespace detail @@ -43,6 +45,10 @@ namespace kernel::filesystem::ext2 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"; }; @@ -67,6 +73,8 @@ namespace kernel::filesystem::ext2 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(kstd::errc::io_error); diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 4195ad05..34ee1f75 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -50,7 +50,11 @@ namespace kernel::filesystem::ext2 { 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) { @@ -62,8 +66,13 @@ namespace kernel::filesystem::ext2 m_block_group_descriptors = kstd::vector(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()); + } if (auto root_inode = read_inode(constants::root_inode_number)) { @@ -105,7 +114,10 @@ namespace kernel::filesystem::ext2 } auto const block_offset = global_block_number.value() * block_size(); - m_backing_inode->read(buffer.data(), block_offset, 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(buffer.data()); auto bytes_read = 0uz; @@ -143,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(this, new_inode_data); } @@ -186,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; @@ -204,13 +227,17 @@ namespace kernel::filesystem::ext2 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 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 58620596..5e5913bf 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.hpp +++ b/kernel/kernel/filesystem/ext2/filesystem.hpp @@ -97,7 +97,7 @@ namespace kernel::filesystem::ext2 [[nodiscard]] auto indirect_levels() const -> std::array; [[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::result>; - [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t; + [[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> kstd::result; [[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/inode.cpp b/kernel/kernel/filesystem/ext2/inode.cpp index 23344a7b..6dadbec5 100644 --- a/kernel/kernel/filesystem/ext2/inode.cpp +++ b/kernel/kernel/filesystem/ext2/inode.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -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 { auto const max_readable = this->size() - offset; auto const requested_size = std::min(size, max_readable); @@ -58,9 +59,14 @@ namespace kernel::filesystem::ext2 { 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(buffer) + bytes_read, read_offset, - bytes_to_read); + auto const read_result = m_filesystem->backing_inode()->read(static_cast(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 { 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 8b63f787..16cb04e0 100644 --- a/kernel/kernel/filesystem/ext2/inode.hpp +++ b/kernel/kernel/filesystem/ext2/inode.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -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 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 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 325ba956..496e7c4f 100644 --- a/kernel/kernel/filesystem/ext2/inode.tests.cpp +++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp @@ -20,6 +20,8 @@ #include #include +// NOLINTBEGIN(readability-magic-numbers) + SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]") { GIVEN("an ext2 filesystem") @@ -112,7 +114,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in REQUIRE(bytes_read == 6); - auto const text = std::string_view{reinterpret_cast(buffer.data()), bytes_read}; + auto const text = std::string_view{reinterpret_cast(buffer.data()), *bytes_read}; REQUIRE(text == "info_1"); } @@ -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(buffer.data()), bytes_read}; + auto const text = std::string_view{reinterpret_cast(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!"); @@ -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(buffer.data()), bytes_read}; + auto const text = std::string_view{reinterpret_cast(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"); @@ -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(buffer.data()), bytes_read}; + auto const text = std::string_view{reinterpret_cast(buffer.data()), *bytes_read}; REQUIRE(text == "Hello World!"); } } @@ -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/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 + #include 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 = 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 = 0; /** @brief Returns whether the inode is a directory. diff --git a/kernel/kernel/filesystem/open_file_descriptor.cpp b/kernel/kernel/filesystem/open_file_descriptor.cpp index bec484d7..ecf3e725 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.cpp +++ b/kernel/kernel/filesystem/open_file_descriptor.cpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -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 { - 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 { - 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 beb32ec6..f6899a31 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.hpp +++ b/kernel/kernel/filesystem/open_file_descriptor.hpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -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; /** @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; /** @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 a04fbaa5..06488ba0 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp @@ -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(buffer.data()), static_cast(bytes_read)}; + std::string_view buffer_as_str{reinterpret_cast(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(buffer.data()), bytes_read_1 + bytes_read_2}; + std::string_view buffer_as_str{reinterpret_cast(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 f33fed2e..dea504e4 100644 --- a/kernel/kernel/filesystem/open_file_table.cpp +++ b/kernel/kernel/filesystem/open_file_table.cpp @@ -69,7 +69,7 @@ namespace kernel::filesystem return kstd::success(m_open_files.at(fd)); } - auto open_file_table::remove_file(size_t fd) -> kstd::result + auto open_file_table::remove_file(size_t fd) -> kstd::result { if (fd >= m_open_files.size() || m_open_files.at(fd) == nullptr) { @@ -77,7 +77,7 @@ namespace kernel::filesystem } m_open_files.at(fd) = nullptr; - return kstd::success(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 a2c0e028..7c9a0c0c 100644 --- a/kernel/kernel/filesystem/open_file_table.hpp +++ b/kernel/kernel/filesystem/open_file_table.hpp @@ -55,7 +55,7 @@ namespace kernel::filesystem @param fd The file descriptor index to remove. @return 0 on success, or -1 on failure. */ - auto remove_file(size_t fd) -> kstd::result; + auto remove_file(size_t fd) -> kstd::result; private: open_file_table() = default; 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 +#include + #include 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 { return 0; } - auto inode::write(void const *, size_t, size_t) -> size_t + auto inode::write(void const *, size_t, size_t) -> kstd::result { return 0; } diff --git a/kernel/kernel/filesystem/rootfs/inode.hpp b/kernel/kernel/filesystem/rootfs/inode.hpp index ee5b9012..777f13f9 100644 --- a/kernel/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/kernel/filesystem/rootfs/inode.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -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 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 override; /** @brief Check if this inode represents a directory. diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index 9aa8b2df..d128bbf5 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -287,7 +287,12 @@ namespace kernel::filesystem kstd::vector 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(buffer.data()), bytes_read}; + if (!bytes_read) + { + return kstd::failure(bytes_read.error()); + } + + auto const symbolic_link_path = std::string_view{reinterpret_cast(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()); diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index 8ef24a15..c99cea90 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -350,7 +350,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS kstd::vector buffer(7); auto bytes_read = sheep_1_ofd->read(buffer.data(), buffer.size()); - std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read}; + std::string_view buffer_as_str{reinterpret_cast(buffer.data()), *bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); REQUIRE(vfs.close(dentry.value()->absolute_path())); @@ -377,12 +377,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS kstd::vector sheep_buffer(7); auto bytes_read = sheep_1_ofd->read(sheep_buffer.data(), sheep_buffer.size()); - std::string_view buffer_as_str{reinterpret_cast(sheep_buffer.data()), bytes_read}; + std::string_view buffer_as_str{reinterpret_cast(sheep_buffer.data()), *bytes_read}; REQUIRE(buffer_as_str == "sheep_1"); kstd::vector goat_buffer(6); bytes_read = goat_1_ofd->read(goat_buffer.data(), goat_buffer.size()); - buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), bytes_read}; + buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), *bytes_read}; REQUIRE(buffer_as_str == "goat_1"); REQUIRE(vfs.close(sheep_1.value()->absolute_path())); diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp index 28429b84..8dce5143 100644 --- a/kernel/kernel/main.cpp +++ b/kernel/kernel/main.cpp @@ -147,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/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 +#include + #include 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 { 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 { 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 +#include + #include 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 override; + auto write(void const * buffer, size_t offset, size_t size) -> kstd::result override; [[nodiscard]] auto is_regular() const -> bool override; }; -- cgit v1.2.3