aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kapi/filesystem.cpp11
-rw-r--r--kernel/kapi/filesystem.tests.cpp32
-rw-r--r--kernel/kernel/filesystem/error.hpp106
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.tests.cpp4
-rw-r--r--kernel/kernel/filesystem/vfs.cpp36
-rw-r--r--kernel/kernel/filesystem/vfs.hpp8
-rw-r--r--kernel/kernel/filesystem/vfs.tests.cpp51
-rw-r--r--kernel/kernel/main.cpp20
8 files changed, 188 insertions, 80 deletions
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 <kernel/filesystem/vfs.hpp>
#include <kstd/memory.hpp>
+#include <kstd/system_error.hpp>
#include <kstd/unikstd.h>
#include <cstddef>
+#include <expected>
#include <string_view>
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<std::size_t, kstd::error_code>
{
- 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<kernel::filesystem::open_file_descriptor>(dentry);
return kernel::filesystem::open_file_table::get().add_file(open_file_descriptor);
- }
-
- return -1;
+ });
}
auto close(size_t file_descriptor) -> kstd::ssize_t
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<std::byte>(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<std::byte>(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<std::byte>(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<std::byte>(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<std::byte>(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<std::byte>(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<std::byte>(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<std::byte>(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 <kstd/system_error.hpp>
+
+#include <string_view>
+#include <type_traits>
+
+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<vfs_errc>(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<vfs_errc>(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<int>(error), vfs_category()};
+ }
+
+ [[nodiscard]] constexpr auto inline make_error_condition(vfs_errc error) noexcept -> kstd::error_condition
+ {
+ return {static_cast<int>(error), vfs_category()};
+ }
+
+} // namespace kernel::filesystem
+
+namespace kstd
+{
+ template<>
+ struct is_error_code_enum<kernel::filesystem::vfs_errc> : std::true_type
+ {
+ };
+
+ template<>
+ struct is_error_condition_enum<kernel::filesystem::vfs_errc> : std::true_type
+ {
+ };
+} // namespace kstd
+
+#endif
diff --git a/kernel/kernel/filesystem/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<kernel::filesystem::open_file_descriptor>(dentry);
+ REQUIRE(dentry);
+ auto ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry.value());
THEN("the file can be read and the offset is updated")
{
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 <kernel/filesystem/constants.hpp>
#include <kernel/filesystem/dentry.hpp>
#include <kernel/filesystem/devfs/filesystem.hpp>
+#include <kernel/filesystem/error.hpp>
#include <kernel/filesystem/filesystem.hpp>
#include <kernel/filesystem/mount.hpp>
#include <kernel/filesystem/mount_table.hpp>
@@ -12,10 +13,12 @@
#include <kapi/system.hpp>
#include <kstd/memory.hpp>
+#include <kstd/system_error.hpp>
#include <kstd/vector.hpp>
#include <algorithm>
#include <cstdint>
+#include <expected>
#include <optional>
#include <ranges>
#include <string_view>
@@ -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<dentry>
+ auto vfs::open(std::string_view path) -> std::expected<kstd::shared_ptr<dentry>, 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<devfs::filesystem> const & device_fs) -> void
{
- auto [root_mount_point_dentry, root_mount] = resolve_path_internal("/");
+ auto [root_mount_point_dentry, root_mount] = resolve_path_internal("/").value_or(std::pair{nullptr, nullptr});
if (root_mount_point_dentry && root_mount)
{
auto dev_dentry = root_mount_point_dentry->find_child("dev");
@@ -171,11 +177,11 @@ namespace kernel::filesystem
}
auto vfs::resolve_path_internal(std::string_view path) const
- -> std::pair<kstd::shared_ptr<dentry>, kstd::shared_ptr<mount>>
+ -> std::expected<std::pair<kstd::shared_ptr<dentry>, kstd::shared_ptr<mount>>, 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<dentry>(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<uint8_t> 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<dentry>
{
- 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<mount>
{
- 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 <kernel/filesystem/mount_table.hpp>
#include <kstd/memory.hpp>
+#include <kstd/system_error.hpp>
+#include <expected>
#include <string_view>
#include <utility>
@@ -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<dentry>;
+ auto open(std::string_view path) -> std::expected<kstd::shared_ptr<dentry>, 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<dentry>, kstd::shared_ptr<mount>>;
+ -> std::expected<std::pair<kstd::shared_ptr<dentry>, kstd::shared_ptr<mount>>, kstd::error_code>;
[[nodiscard]] auto resolve_path(std::string_view path) const -> kstd::shared_ptr<dentry>;
[[nodiscard]] auto find_mount(std::string_view path) const -> kstd::shared_ptr<mount>;
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<kernel::filesystem::open_file_descriptor>(dentry);
+ auto sheep_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(dentry.value());
kstd::vector<std::byte> buffer(7);
auto bytes_read = sheep_1_ofd->read(buffer.data(), buffer.size());
std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), bytes_read};
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<kernel::filesystem::open_file_descriptor>(sheep_1);
- auto goat_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(goat_1);
+ auto sheep_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(sheep_1.value());
+ auto goat_1_ofd = kstd::make_shared<kernel::filesystem::open_file_descriptor>(goat_1.value());
kstd::vector<std::byte> sheep_buffer(7);
auto bytes_read = sheep_1_ofd->read(sheep_buffer.data(), sheep_buffer.size());
@@ -392,8 +396,8 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS
buffer_as_str = std::string_view{reinterpret_cast<char *>(goat_buffer.data()), bytes_read};
REQUIRE(buffer_as_str == "goat_1");
- REQUIRE(vfs.close(sheep_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
- REQUIRE(vfs.close(goat_1->absolute_path()) == kernel::filesystem::vfs::operation_result::success);
+ REQUIRE(vfs.close(sheep_1.value()->absolute_path()) == 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<std::byte> 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<char *>(buffer_1.data()), static_cast<size_t>(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<std::byte> buffer_2{10};
- bytes_read = kapi::filesystem::read(fd_2, buffer_2.data(), buffer_2.size());
+ bytes_read = kapi::filesystem::read(fd_2.value(), buffer_2.data(), buffer_2.size());
buffer_as_str = std::string_view{reinterpret_cast<char *>(buffer_2.data()), static_cast<size_t>(bytes_read)};
kstd::println("--> read {} bytes from /entrance/information/info_1.txt: {} ", bytes_read, buffer_as_str);
// 7) open device as file
kstd::println("attempting to open /dev/ram32 as a file");
auto fd_3 = kapi::filesystem::open("/dev/ram32");
- if (fd_3 != -1)
+ if (fd_3)
{
- kstd::println("--> successfully opened /dev/ram32 as a file with file descriptor {}", fd_3);
+ kstd::println("--> successfully opened /dev/ram32 as a file with file descriptor {}", fd_3.value());
}
else
{
@@ -96,13 +96,13 @@ auto run_demo() -> void
// 8) read from the device file
kstd::vector<std::byte> buffer_3{2};
- bytes_read = kapi::filesystem::read(fd_3, buffer_3.data(), buffer_3.size());
+ bytes_read = kapi::filesystem::read(fd_3.value(), buffer_3.data(), buffer_3.size());
kstd::println("--> read {} bytes from /dev/ram32: {::#04x} ", bytes_read, buffer_3);
// 9) write to the device file
auto const default_buffer_value = std::byte{0xAA};
kstd::vector<std::byte> write_buffer{default_buffer_value, default_buffer_value};
- auto bytes_written = kapi::filesystem::write(fd_3, write_buffer.data(), write_buffer.size());
+ auto bytes_written = kapi::filesystem::write(fd_3.value(), write_buffer.data(), write_buffer.size());
kstd::println("--> written {} bytes to /dev/ram32: {::#04x}", bytes_written, write_buffer);
// 10) do memory dump to show that the write to the device file had an effect