From 853eb183d46c1410507c53d19b00c52162592cfc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 17 Aug 2026 17:52:00 +0200 Subject: kapi: port block_special_file to std::span --- kernel/kapi/filesystem.cpp | 4 +- kernel/kernel/devices/block_device_utils.cpp | 72 +++++++++---------- kernel/kernel/devices/block_device_utils.hpp | 41 +++++------ kernel/kernel/devices/block_device_utils.tests.cpp | 81 ++++++++-------------- kernel/kernel/drivers/storage/ram_disk.cpp | 29 +++----- kernel/kernel/filesystem/devfs/inode.cpp | 7 +- kernel/kernel/filesystem/devfs/inode.hpp | 7 +- kernel/kernel/filesystem/devfs/inode.tests.cpp | 10 +-- kernel/kernel/filesystem/device_inode.cpp | 12 ++-- kernel/kernel/filesystem/device_inode.hpp | 6 +- kernel/kernel/filesystem/device_inode.tests.cpp | 27 ++++---- kernel/kernel/filesystem/ext2/filesystem.cpp | 39 +++++------ kernel/kernel/filesystem/ext2/filesystem.tests.cpp | 12 ++-- kernel/kernel/filesystem/ext2/inode.cpp | 28 ++++---- kernel/kernel/filesystem/ext2/inode.hpp | 5 +- kernel/kernel/filesystem/ext2/inode.tests.cpp | 53 +++++++------- kernel/kernel/filesystem/inode.hpp | 6 +- kernel/kernel/filesystem/open_file_descriptor.cpp | 11 +-- kernel/kernel/filesystem/open_file_descriptor.hpp | 9 +-- .../filesystem/open_file_descriptor.tests.cpp | 41 ++++++----- kernel/kernel/filesystem/rootfs/inode.cpp | 7 +- kernel/kernel/filesystem/rootfs/inode.hpp | 9 +-- kernel/kernel/filesystem/rootfs/inode.tests.cpp | 10 +-- kernel/kernel/filesystem/vfs.cpp | 5 +- kernel/kernel/filesystem/vfs.tests.cpp | 10 +-- .../kernel/test_support/devices/block_device.cpp | 17 ++--- .../kernel/test_support/devices/block_device.hpp | 6 +- kernel/kernel/test_support/filesystem/inode.cpp | 11 +-- kernel/kernel/test_support/filesystem/inode.hpp | 7 +- 29 files changed, 288 insertions(+), 294 deletions(-) (limited to 'kernel') diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index b0de244e..8582d89e 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -47,7 +47,7 @@ namespace kapi::filesystem auto read(size_t file_descriptor, std::span buffer) -> std::expected { return kernel::filesystem::open_file_table::get().file(file_descriptor).and_then([=](auto descriptor) { - return descriptor->read(buffer.data(), kstd::units::bytes{buffer.size()}); + return descriptor->read(buffer); }); } @@ -55,7 +55,7 @@ namespace kapi::filesystem -> std::expected { return kernel::filesystem::open_file_table::get().file(file_descriptor).and_then([=](auto descriptor) { - return descriptor->write(buffer.data(), kstd::units::bytes{buffer.size()}); + return descriptor->write(buffer); }); } diff --git a/kernel/kernel/devices/block_device_utils.cpp b/kernel/kernel/devices/block_device_utils.cpp index ee01d5c7..0f85acd0 100644 --- a/kernel/kernel/devices/block_device_utils.cpp +++ b/kernel/kernel/devices/block_device_utils.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include @@ -10,6 +9,7 @@ #include #include +#include using namespace kstd::units_literals; @@ -21,17 +21,14 @@ namespace kernel::devices::block_device_utils using block_op = kstd::result (*)(size_t idx, kstd::units::bytes off, kstd::units::bytes len, kstd::units::bytes done, kapi::filesystem::block_special_file & device, - std::byte * scratch, void * buffer); + std::span scratch, std::span buffer); auto process_blocks(kapi::filesystem::block_special_file & device, kstd::units::bytes offset, - kstd::units::bytes size, void * buffer, block_op op) -> kstd::result + std::span buffer, block_op op) -> kstd::result { - if (buffer == nullptr) - { - kapi::system::panic("[FILESYSTEM] device_file::process_blocks called with null buffer."); - } + auto requested_size = kstd::units::bytes{buffer.size()}; - if (size == 0_B) + if (requested_size == 0_B) { return 0_B; } @@ -43,7 +40,7 @@ namespace kernel::devices::block_device_utils { return 0_B; } - auto const total_to_process = std::min(size, capacity - offset); + auto const total_to_process = std::min(requested_size, capacity - offset); kstd::vector scratch_buffer{block_size.value}; auto processed = 0_B; @@ -55,8 +52,7 @@ namespace kernel::devices::block_device_utils auto const in_block_offset = absolute_offset % block_size; auto const chunk_size = std::min(total_to_process - processed, block_size - in_block_offset); - if (auto result = - op(block_index, in_block_offset, chunk_size, processed, device, scratch_buffer.data(), buffer); + if (auto result = op(block_index, in_block_offset, chunk_size, processed, device, scratch_buffer, buffer); !result) { return result; @@ -80,44 +76,42 @@ namespace kernel::devices::block_device_utils return {offset, to_transfer, device.block_size() - to_transfer}; } - auto read(kapi::filesystem::block_special_file & device, void * buffer, kstd::units::bytes offset, - kstd::units::bytes size) -> kstd::result + auto read(kapi::filesystem::block_special_file & device, std::span buffer, kstd::units::bytes offset) + -> kstd::result { - return process_blocks(device, offset, size, buffer, - [](size_t idx, kstd::units::bytes off, kstd::units::bytes len, kstd::units::bytes done, - kapi::filesystem::block_special_file & device, std::byte * scratch, void * buffer) { - auto * out = static_cast(buffer); - if (off == 0_B && len == device.block_size()) - { - return device.read_block(idx, out + done); - } - else - { - auto result = device.read_block(idx, scratch); - if (result) - { - kstd::libc::memcpy(out + done, scratch + off, len.value); - } - return result; - } - }); + return process_blocks( + device, offset, buffer, [](auto idx, auto off, auto len, auto done, auto & device, auto scratch, auto buffer) { + if (off == 0_B && len == device.block_size()) + { + return device.read_block(idx, buffer.subspan(done.value)); + } + else + { + auto result = device.read_block(idx, scratch); + if (result) + { + kstd::libc::memcpy(buffer.subspan(done.value).data(), scratch.subspan(off.value).data(), len.value); + } + return result; + } + }); } - auto write(kapi::filesystem::block_special_file & device, void const * buffer, kstd::units::bytes offset, - kstd::units::bytes size) -> kstd::result + auto write(kapi::filesystem::block_special_file & device, std::span buffer, + kstd::units::bytes offset) -> kstd::result { - return process_blocks(device, offset, size, const_cast(buffer), - [](size_t idx, kstd::units::bytes off, kstd::units::bytes len, kstd::units::bytes done, - kapi::filesystem::block_special_file & device, std::byte * scratch, void * buffer) { - auto const * in = static_cast(buffer); + auto non_cost_span = std::span{const_cast(buffer.data()), buffer.size()}; + return process_blocks(device, offset, non_cost_span, + [](auto idx, auto off, auto len, auto done, auto & device, auto scratch, auto buffer) { if (off == 0_B && len == device.block_size()) { - return device.write_block(idx, in + done); + return device.write_block(idx, buffer.subspan(done.value)); } else { return device.read_block(idx, scratch).and_then([&](auto) { - kstd::libc::memcpy(scratch + off, in + done, len.value); + kstd::libc::memcpy(scratch.subspan(off.value).data(), buffer.subspan(done.value).data(), + len.value); return device.write_block(idx, scratch); }); } diff --git a/kernel/kernel/devices/block_device_utils.hpp b/kernel/kernel/devices/block_device_utils.hpp index cafe0f3e..02d2f0e8 100644 --- a/kernel/kernel/devices/block_device_utils.hpp +++ b/kernel/kernel/devices/block_device_utils.hpp @@ -8,6 +8,7 @@ #include #include +#include /** @brief Utility functions for block devices, such as reading/writing data at specific offsets. These functions handle @@ -31,29 +32,23 @@ namespace kernel::devices::block_device_utils [[nodiscard]] auto calculate_transfer(kapi::filesystem::block_special_file const & device, size_t block_index) -> transfer_info; - /** - @brief Reads data from a @p device into a @p buffer, starting at a specific @p offset and for a given @p size. - @warning Panics if @p buffer or @p device is null. - @param device The block device to read from. - @param buffer The buffer to read data into. - @param offset The offset on the block device to start reading from. - @param size The number of bytes to read. - @return The number of bytes actually read, which may be less than the requested size. - */ - auto read(kapi::filesystem::block_special_file & device, void * buffer, kstd::units::bytes offset, - kstd::units::bytes size) -> kstd::result; - - /** - @brief Writes data from a @p buffer to a @p device, starting at a specific @p offset and for a given @p size. - @warning Panics if @p buffer or @p device is null. - @param device The block device to write to. - @param buffer The buffer to write data from. - @param offset The offset on the block device to start writing to. - @param size The number of bytes to write. - @return The number of bytes actually written, which may be less than the requested size. - */ - auto write(kapi::filesystem::block_special_file & device, void const * buffer, kstd::units::bytes offset, - kstd::units::bytes size) -> kstd::result; + //! Read data from a block device into a given buffer. + //! + //! @param device The block device to read from. + //! @param buffer The buffer to read data into. + //! @param offset The offset on the block device to start reading from. + //! @return The number of bytes actually read, which may be less than the requested size. + auto read(kapi::filesystem::block_special_file & device, std::span buffer, kstd::units::bytes offset) + -> kstd::result; + + //! @brief Write data from a buffer to a given block device. + //! + //! @param device The block device to write to. + //! @param buffer The buffer to write data from. + //! @param offset The offset on the block device to start writing to. + //! @return The number of bytes actually written, which may be less than the requested size. + auto write(kapi::filesystem::block_special_file & device, std::span buffer, + kstd::units::bytes offset) -> kstd::result; } // namespace kernel::devices::block_device_utils #endif \ No newline at end of file diff --git a/kernel/kernel/devices/block_device_utils.tests.cpp b/kernel/kernel/devices/block_device_utils.tests.cpp index 7d671c7e..16a1ca87 100644 --- a/kernel/kernel/devices/block_device_utils.tests.cpp +++ b/kernel/kernel/devices/block_device_utils.tests.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include using namespace kstd::units_literals; @@ -22,19 +22,18 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block { auto const block_size = 512_B; auto device = kstd::make_shared("test_block_device", block_size); - kstd::vector block_data(block_size.value); + kstd::vector block_data(block_size.value); for (size_t i = 0; i < block_data.size(); ++i) { - block_data[i] = static_cast(i % 256); + block_data[i] = static_cast(i % 256); } - CHECK(device->write_block(0, block_data.data())); - CHECK(device->write_block(1, block_data.data())); + CHECK(device->write_block(0, block_data)); + CHECK(device->write_block(1, block_data)); WHEN("reading from the block device using block_device_utils") { - kstd::vector read_buffer(block_size.value); - auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 0_B, - kstd::units::bytes{read_buffer.size()}); + kstd::vector read_buffer(block_size.value); + auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer, 0_B); THEN("the correct number of bytes is read") { @@ -49,9 +48,8 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block WHEN("reading over block boundaries") { - kstd::vector read_buffer(1024); - auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 256_B, - kstd::units::bytes{read_buffer.size()}); + kstd::vector read_buffer(1024); + auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer, 256_B); THEN("the correct number of bytes is read") { @@ -62,7 +60,7 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block { for (size_t i = 0; i < bytes_read.value().value; ++i) { - uint8_t expected_value = static_cast((256 + i) % 256); + auto expected_value = static_cast((256 + i) % 256); REQUIRE(read_buffer[i] == expected_value); } } @@ -70,9 +68,8 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block WHEN("reading beyond the device capacity") { - kstd::vector read_buffer(block_size.value); - auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 1024_B, - kstd::units::bytes{read_buffer.size()}); + kstd::vector read_buffer(block_size.value); + auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer, 1024_B); THEN("no bytes are read") { @@ -82,23 +79,14 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block WHEN("reading nothing") { - kstd::vector read_buffer(block_size.value); - auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 0_B, 0_B); + kstd::vector read_buffer(block_size.value); + auto bytes_read = kernel::devices::block_device_utils::read(*device, std::span{read_buffer}.subspan(0, 0), 0_B); THEN("no bytes are read") { REQUIRE(bytes_read == 0_B); } } - - WHEN("reading with a null buffer") - { - THEN("the system panics") - { - REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(*device, nullptr, 0_B, 512_B), - kernel::tests::cpu::halt); - } - } } } @@ -112,14 +100,13 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_ WHEN("writing to the block device using block_device_utils") { - kstd::vector write_buffer(block_size.value); + kstd::vector write_buffer(block_size.value); for (size_t i = 0; i < write_buffer.size(); ++i) { - write_buffer[i] = static_cast(i % 256); + write_buffer[i] = static_cast(i % 256); } - auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 0_B, - kstd::units::bytes{write_buffer.size()}); + auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer, 0_B); THEN("the correct number of bytes is written") { @@ -128,22 +115,21 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_ THEN("the data written matches the data read back from the block device") { - kstd::vector read_buffer(block_size.value); - CHECK(device->read_block(0, read_buffer.data())); + kstd::vector read_buffer(block_size.value); + CHECK(device->read_block(0, read_buffer)); REQUIRE(read_buffer == write_buffer); } } WHEN("writing over block boundaries") { - kstd::vector write_buffer(2 * block_size.value); + kstd::vector write_buffer(2 * block_size.value); for (size_t i = 0; i < write_buffer.size(); ++i) { - write_buffer[i] = static_cast(i % 256); + write_buffer[i] = static_cast(i % 256); } - auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 256_B, - kstd::units::bytes{write_buffer.size()}); + auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer, 256_B); THEN("the correct number of bytes is written") { @@ -152,8 +138,8 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_ THEN("the data written matches the data read back from the block device across block boundaries") { - kstd::vector read_buffer(2 * block_size.value); - auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 256_B, 2 * block_size); + kstd::vector read_buffer(2 * block_size.value); + auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer, 256_B); for (size_t i = 0; i < bytes_read.value().value; ++i) { @@ -164,9 +150,8 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_ WHEN("writing beyond the device capacity") { - kstd::vector write_buffer(block_size.value); - auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 1024_B, - kstd::units::bytes{write_buffer.size()}); + kstd::vector write_buffer(block_size.value); + auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer, 1024_B); THEN("no bytes are written") { @@ -176,22 +161,14 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_ WHEN("writing nothing") { - kstd::vector write_buffer(block_size.value); - auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 0_B, 0_B); + kstd::vector write_buffer(block_size.value); + auto bytes_written = + kernel::devices::block_device_utils::write(*device, std::span{write_buffer}.subspan(0, 0), 0_B); THEN("no bytes are written") { REQUIRE(bytes_written == 0_B); } } - - WHEN("writing with a null buffer") - { - THEN("the system panics") - { - REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(*device, nullptr, 0_B, block_size), - kernel::tests::cpu::halt); - } - } } } diff --git a/kernel/kernel/drivers/storage/ram_disk.cpp b/kernel/kernel/drivers/storage/ram_disk.cpp index f7e73cd1..d96e60c0 100644 --- a/kernel/kernel/drivers/storage/ram_disk.cpp +++ b/kernel/kernel/drivers/storage/ram_disk.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -19,6 +18,7 @@ #include #include #include +#include #include #include @@ -54,45 +54,38 @@ namespace kernel::drivers::storage : m_module(module) {} - auto read_block(std::size_t block_index, void * buffer) const -> kstd::result override + [[nodiscard]] auto read_block(std::size_t block_index, std::span buffer) const + -> kstd::result override { - if (!buffer) - { - kapi::system::panic("[RAM DISK] read_block called with null buffer."); - } - auto info = devices::block_device_utils::calculate_transfer(*this, block_index); if (info.to_transfer > 0_B) { auto source = static_cast(m_module.start_address) + info.offset; - kstd::libc::memcpy(buffer, source, info.to_transfer.value); + kstd::libc::memcpy(buffer.data(), source, info.to_transfer.value); } if (info.remainder > 0_B) { - kstd::libc::memset(static_cast(buffer) + info.to_transfer, 0, info.remainder.value); + kstd::libc::memset(buffer.data() + info.to_transfer, 0, info.remainder.value); } return info.to_transfer; } - auto write_block(std::size_t block_index, void const * buffer) -> kstd::result override + auto write_block(std::size_t block_index, std::span buffer) + -> kstd::result override { - if (buffer == nullptr) - { - kapi::system::panic("[RAM DISK] write_block called with null buffer."); - } - auto const info = devices::block_device_utils::calculate_transfer(*this, block_index); + auto transfer_size = std::min(info.to_transfer, kstd::units::bytes{buffer.size()}); - if (info.to_transfer > 0_B) + if (transfer_size > 0_B) { auto const dest = static_cast(m_module.start_address) + info.offset; - kstd::libc::memcpy(dest, buffer, info.to_transfer.value); + kstd::libc::memcpy(dest, buffer.data(), transfer_size.value); } - return info.to_transfer; + return transfer_size; } [[nodiscard]] auto block_size() const -> kstd::units::bytes override diff --git a/kernel/kernel/filesystem/devfs/inode.cpp b/kernel/kernel/filesystem/devfs/inode.cpp index 8d0a9b14..3f222f31 100644 --- a/kernel/kernel/filesystem/devfs/inode.cpp +++ b/kernel/kernel/filesystem/devfs/inode.cpp @@ -3,16 +3,19 @@ #include #include +#include +#include + using namespace kstd::units_literals; namespace kernel::filesystem::devfs { - auto inode::read(void *, kstd::units::bytes, kstd::units::bytes) const -> kstd::result + auto inode::read(std::span, kstd::units::bytes) const -> kstd::result { return 0_B; } - auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes) -> kstd::result + auto inode::write(std::span, kstd::units::bytes) -> kstd::result { return 0_B; } diff --git a/kernel/kernel/filesystem/devfs/inode.hpp b/kernel/kernel/filesystem/devfs/inode.hpp index 1e6d4e05..6639d180 100644 --- a/kernel/kernel/filesystem/devfs/inode.hpp +++ b/kernel/kernel/filesystem/devfs/inode.hpp @@ -6,6 +6,9 @@ #include #include +#include +#include + namespace kernel::filesystem::devfs { /** @@ -21,7 +24,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, kstd::units::bytes offset, kstd::units::bytes size) const + [[nodiscard]] auto read(std::span buffer, kstd::units::bytes offset) const -> kstd::result override; /** @@ -31,7 +34,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, kstd::units::bytes offset, kstd::units::bytes size) + auto write(std::span buffer, kstd::units::bytes offset) -> kstd::result override; /** diff --git a/kernel/kernel/filesystem/devfs/inode.tests.cpp b/kernel/kernel/filesystem/devfs/inode.tests.cpp index 9445be7d..0d8ed5d1 100644 --- a/kernel/kernel/filesystem/devfs/inode.tests.cpp +++ b/kernel/kernel/filesystem/devfs/inode.tests.cpp @@ -7,7 +7,7 @@ #include -#include +#include using namespace kstd::units_literals; @@ -35,8 +35,8 @@ SCENARIO("Devfs inode read/write", "[filesystem][devfs][inode]") WHEN("attempting to read from the devfs inode") { - kstd::vector buffer(512); - auto bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + kstd::vector buffer(512); + auto bytes_read = inode.read(buffer, 0_B); THEN("no bytes are read") { @@ -46,8 +46,8 @@ SCENARIO("Devfs inode read/write", "[filesystem][devfs][inode]") WHEN("attempting to write to the devfs inode") { - kstd::vector buffer(512); - auto bytes_written = inode.write(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + kstd::vector buffer(512); + auto bytes_written = inode.write(buffer, 0_B); THEN("no bytes are written") { diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp index d6f7637a..53201e08 100644 --- a/kernel/kernel/filesystem/device_inode.cpp +++ b/kernel/kernel/filesystem/device_inode.cpp @@ -40,7 +40,7 @@ namespace kernel::filesystem } } - auto device_inode::read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const + auto device_inode::read(std::span buffer, kstd::units::bytes offset) const -> kstd::result { if (m_device->state() == kapi::devices::state::removed) @@ -51,18 +51,18 @@ namespace kernel::filesystem if (auto block_device = kapi::devices::facet_registry::get().resolve(*m_device)) { - return devices::block_device_utils::read(*block_device, buffer, offset, size); + return devices::block_device_utils::read(*block_device, buffer, offset); } else if (auto character_device = kapi::devices::facet_registry::get().resolve(*m_device)) { - return character_device->read(std::span{static_cast(buffer), size.value}); + return character_device->read(buffer); } return kstd::failure(vfs_errc::no_such_device); } - auto device_inode::write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) + auto device_inode::write(std::span buffer, kstd::units::bytes offset) -> kstd::result { if (m_device->state() == kapi::devices::state::removed) @@ -73,12 +73,12 @@ namespace kernel::filesystem if (auto block_device = kapi::devices::facet_registry::get().resolve(*m_device)) { - return devices::block_device_utils::write(*block_device, buffer, offset, size); + return devices::block_device_utils::write(*block_device, buffer, offset); } else if (auto character_device = kapi::devices::facet_registry::get().resolve(*m_device)) { - return character_device->write(std::span{static_cast(buffer), size.value}); + return character_device->write(buffer); } return kstd::failure(vfs_errc::no_such_device); diff --git a/kernel/kernel/filesystem/device_inode.hpp b/kernel/kernel/filesystem/device_inode.hpp index 17ebe236..759119e7 100644 --- a/kernel/kernel/filesystem/device_inode.hpp +++ b/kernel/kernel/filesystem/device_inode.hpp @@ -10,7 +10,9 @@ #include #include +#include #include +#include namespace kernel::filesystem { @@ -40,7 +42,7 @@ namespace kernel::filesystem @param size The number of bytes to read. @return The number of bytes read. */ - auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const + [[nodiscard]] auto read(std::span buffer, kstd::units::bytes offset) const -> kstd::result override; /** @@ -51,7 +53,7 @@ namespace kernel::filesystem @param size The number of bytes to write. @return The number of bytes written. */ - auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) + auto write(std::span buffer, kstd::units::bytes offset) -> kstd::result override; /** diff --git a/kernel/kernel/filesystem/device_inode.tests.cpp b/kernel/kernel/filesystem/device_inode.tests.cpp index 59800531..2a5e54c7 100644 --- a/kernel/kernel/filesystem/device_inode.tests.cpp +++ b/kernel/kernel/filesystem/device_inode.tests.cpp @@ -22,6 +22,7 @@ #include #include +#include #include using namespace kstd::units_literals; @@ -38,12 +39,12 @@ namespace struct mock_origin_inode : kernel::filesystem::inode { - auto read(void *, kstd::units::bytes, kstd::units::bytes) const -> kstd::result override + auto read(std::span, kstd::units::bytes) const -> kstd::result override { return 0_B; } - auto write(void const *, kstd::units::bytes, kstd::units::bytes) -> kstd::result override + auto write(std::span, kstd::units::bytes) -> kstd::result override { return 0_B; } @@ -104,13 +105,13 @@ SCENARIO("Device inode read/write", "[filesystem][device_inode]") WHEN("writing to the device inode") { - kstd::vector write_buffer(1024); + kstd::vector write_buffer(1024); for (size_t i = 0; i < write_buffer.size(); ++i) { - write_buffer[i] = static_cast(i % 256); + write_buffer[i] = static_cast(i % 256); } - auto bytes_written = inode.write(write_buffer.data(), 256_B, kstd::units::bytes{write_buffer.size()}); + auto bytes_written = inode.write(write_buffer, 256_B); THEN("the correct number of bytes is written") { @@ -119,8 +120,8 @@ SCENARIO("Device inode read/write", "[filesystem][device_inode]") THEN("the data written matches the data read back from the device inode") { - kstd::vector read_buffer(1024); - auto bytes_read = inode.read(read_buffer.data(), 256_B, kstd::units::bytes{read_buffer.size()}); + kstd::vector read_buffer(1024); + auto bytes_read = inode.read(read_buffer, 256_B); REQUIRE(bytes_read.value().value == write_buffer.size()); REQUIRE(read_buffer == write_buffer); @@ -138,11 +139,11 @@ SCENARIO("Device inode read/write with a non-block device", "[filesystem][device WHEN("reading from the device inode") { - kstd::vector read_buffer(512); + kstd::vector read_buffer(512); THEN("the result is an error") { - auto result = inode.read(read_buffer.data(), 0_B, kstd::units::bytes{read_buffer.size()}); + auto result = inode.read(read_buffer, 0_B); REQUIRE(!result); REQUIRE(result.error() == kstd::errc::no_such_device); } @@ -150,11 +151,11 @@ SCENARIO("Device inode read/write with a non-block device", "[filesystem][device WHEN("writing to the device inode") { - kstd::vector write_buffer(512); + kstd::vector write_buffer(512); THEN("the system panics") { - auto result = inode.write(write_buffer.data(), 0_B, kstd::units::bytes{write_buffer.size()}); + auto result = inode.write(write_buffer, 0_B); REQUIRE(!result); REQUIRE(result.error() == kstd::errc::no_such_device); } @@ -235,8 +236,8 @@ SCENARIO("Device inode status()", "[filesystem][device_inode]") THEN("read/write still delegate to the device, never to the origin") { - kstd::vector buffer(512); - auto const result = inode.read(buffer.data(), 0_B, 512_B); + kstd::vector buffer(512); + auto const result = inode.read(buffer, 0_B); REQUIRE(result == 512_B); } } diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp index 132d2398..ff84a459 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,7 @@ namespace kernel::filesystem::ext2 std::ignore = kernel::filesystem::filesystem::mount(backing_inode); if (auto read_result = - m_backing_inode->read(&m_superblock, constants::superblock_offset, kstd::object_size(m_superblock)); + m_backing_inode->read(std::as_writable_bytes(std::span{&m_superblock, 1}), constants::superblock_offset); !read_result) { return kstd::failure(read_result.error()); @@ -101,9 +102,8 @@ namespace kernel::filesystem::ext2 m_block_group_descriptors = kstd::vector(num_block_groups); - if (auto read_result = - m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset(), - num_block_groups * kstd::type_size); + if (auto read_result = m_backing_inode->read(std::as_writable_bytes(std::span{m_block_group_descriptors}), + block_group_descriptor_table_offset()); !read_result) { return kstd::failure(read_result.error()); @@ -374,7 +374,7 @@ namespace kernel::filesystem::ext2 { auto new_inode_data = inode_data{}; - if (auto read_result = m_backing_inode->read(&new_inode_data, *inode_offset, kstd::type_size); + if (auto read_result = m_backing_inode->read(as_writable_bytes(std::span{&new_inode_data, 1}), *inode_offset); !read_result) { return kstd::failure(read_result.error()); @@ -394,7 +394,7 @@ namespace kernel::filesystem::ext2 { if (auto inode_offset = calculate_inode_offset(inode_number)) { - return m_backing_inode->write(&data, *inode_offset, kstd::type_size).transform([](auto) {}); + return m_backing_inode->write(as_bytes(std::span{&data, 1}), *inode_offset).transform([](auto) {}); } else { @@ -469,10 +469,9 @@ namespace kernel::filesystem::ext2 // TODO update all block group descriptors if (auto write_result = - m_backing_inode->write(&block_group_descriptor, + m_backing_inode->write(as_bytes(std::span{&block_group_descriptor, 1}), block_group_descriptor_table_offset() + - block_group_descriptor_index * kstd::object_size(block_group_descriptor), - kstd::object_size(block_group_descriptor)); + block_group_descriptor_index * kstd::object_size(block_group_descriptor)); !write_result) { return kstd::failure(write_result.error()); @@ -481,8 +480,7 @@ namespace kernel::filesystem::ext2 } // TODO update all superblocks - if (auto write_result = - m_backing_inode->write(&m_superblock, constants::superblock_offset, kstd::object_size(m_superblock)); + if (auto write_result = m_backing_inode->write(as_bytes(std::span{&m_superblock, 1}), constants::superblock_offset); !write_result) { return kstd::failure(write_result.error()); @@ -612,7 +610,8 @@ namespace kernel::filesystem::ext2 auto const block_start_offset = block_number * block_size(); auto const number_start_address = block_start_offset + index * kstd::type_size; - if (auto read_result = m_backing_inode->read(&block_number_buffer, number_start_address, kstd::type_size); + if (auto read_result = + m_backing_inode->read(as_writable_bytes(std::span{&block_number_buffer, 1}), number_start_address); !read_result) { return kstd::failure(read_result.error()); @@ -664,8 +663,7 @@ namespace kernel::filesystem::ext2 } else { - if (auto write_result = - m_backing_inode->write(&block_number, parent_byte_offset, kstd::type_size); + if (auto write_result = m_backing_inode->write(as_bytes(std::span{&block_number, 1}), parent_byte_offset); !write_result) { return kstd::failure(write_result.error()); @@ -677,7 +675,7 @@ namespace kernel::filesystem::ext2 if (stride == 1) { - if (auto write_result = m_backing_inode->write(&global_block_number, byte_offset, kstd::type_size); + if (auto write_result = m_backing_inode->write(as_bytes(std::span{&global_block_number, 1}), byte_offset); !write_result) { return kstd::failure(write_result.error()); @@ -704,13 +702,13 @@ namespace kernel::filesystem::ext2 auto filesystem::read_block(uint32_t block_number, void * buffer) const -> kstd::result { auto const block_offset = static_cast(block_number) * block_size(); - return m_backing_inode->read(buffer, block_offset, block_size()); + return m_backing_inode->read(std::span{static_cast(buffer), block_size().value}, block_offset); } auto filesystem::write_block(uint32_t block_number, void const * buffer) -> kstd::result { auto const block_offset = static_cast(block_number) * block_size(); - return m_backing_inode->write(buffer, block_offset, block_size()); + return m_backing_inode->write(std::span{static_cast(buffer), block_size().value}, block_offset); } auto filesystem::write_block_group_descriptor(block_group_descriptor const & block_group_descriptor, @@ -718,17 +716,16 @@ namespace kernel::filesystem::ext2 { // TODO update all block group descriptors return m_backing_inode - ->write(&block_group_descriptor, + ->write(as_bytes(std::span{&block_group_descriptor, 1}), block_group_descriptor_table_offset() + - block_group_descriptor_index * kstd::object_size(block_group_descriptor), - kstd::object_size(block_group_descriptor)) + block_group_descriptor_index * kstd::object_size(block_group_descriptor)) .transform([](auto) {}); } auto filesystem::write_superblock() const -> kstd::result { // TODO update all superblocks - return m_backing_inode->write(&m_superblock, constants::superblock_offset, kstd::object_size(m_superblock)) + return m_backing_inode->write(as_bytes(std::span{&m_superblock, 1}), constants::superblock_offset) .transform([](auto) {}); } diff --git a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp index e2259499..08232aa4 100644 --- a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp +++ b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp @@ -146,14 +146,14 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, auto new_inode = fs.create_inode(fs.root_inode(), "blub", kernel::filesystem::vfs_types::inode_type::regular); REQUIRE(new_inode); - auto buffer = std::vector{std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'}, - std::byte{'o'}, std::byte{' '}, std::byte{'W'}, std::byte{'o'}, - std::byte{'r'}, std::byte{'l'}, std::byte{'d'}, std::byte{'!'}}; - auto bytes_written = new_inode.value()->write(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + auto buffer = + std::vector{std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'}, std::byte{'o'}, std::byte{' '}, + std::byte{'W'}, std::byte{'o'}, std::byte{'r'}, std::byte{'l'}, std::byte{'d'}, std::byte{'!'}}; + auto bytes_written = new_inode.value()->write(buffer, 0_B); REQUIRE(bytes_written == kstd::units::bytes{buffer.size()}); auto read_buffer = std::vector(5, std::byte{0xAA}); - auto bytes_read = new_inode.value()->read(read_buffer.data(), 0_B, kstd::units::bytes{read_buffer.size()}); + auto bytes_read = new_inode.value()->read(read_buffer, 0_B); REQUIRE(bytes_read == kstd::units::bytes{read_buffer.size()}); std::string_view result{reinterpret_cast(read_buffer.data()), static_cast(*bytes_read)}; @@ -269,7 +269,7 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys block_bitmap[1] = std::byte{0b1111'1111}; auto dev_inode = kstd::make_shared(device); - REQUIRE(dev_inode->write(block_bitmap.data(), block_group_descriptor.block_bitmap * block_size, block_size)); + REQUIRE(dev_inode->write(block_bitmap, block_group_descriptor.block_bitmap * block_size)); kernel::tests::filesystem::ext2::setup_mock_ext2_layout(*device, superblock, block_group_descriptor); diff --git a/kernel/kernel/filesystem/ext2/inode.cpp b/kernel/kernel/filesystem/ext2/inode.cpp index 8e4c2e7c..cba0e70c 100644 --- a/kernel/kernel/filesystem/ext2/inode.cpp +++ b/kernel/kernel/filesystem/ext2/inode.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace kstd::units_literals; @@ -30,16 +31,15 @@ namespace kernel::filesystem::ext2 } } - auto inode::read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const - -> kstd::result + auto inode::read(std::span buffer, kstd::units::bytes offset) const -> kstd::result { auto const max_readable = this->size() - offset; - auto const requested_size = std::min(size, max_readable); + auto const requested_size = std::min(kstd::units::bytes{buffer.size()}, max_readable); if (is_symbolic_link() && this->size() <= kstd::units::bytes{sizeof(m_data.block)}) { auto inline_target = reinterpret_cast(m_data.block.data()); - kstd::libc::memcpy(static_cast(buffer), inline_target + offset, requested_size.value); + kstd::libc::memcpy(buffer.data(), inline_target + offset, requested_size.value); return requested_size; } @@ -59,15 +59,15 @@ namespace kernel::filesystem::ext2 auto const bytes_to_read = std::min(requested_size - bytes_read, m_filesystem->block_size() - in_block_offset); if (block_number == 0) { - kstd::libc::memset(static_cast(buffer) + bytes_read, 0, bytes_to_read.value); + kstd::libc::memset(buffer.data() + bytes_read, 0, bytes_to_read.value); bytes_read += bytes_to_read; } else { auto const block_start_offset = block_number.value() * m_filesystem->block_size(); auto const read_offset = block_start_offset + in_block_offset; - auto const read_result = m_filesystem->backing_inode()->read(static_cast(buffer) + bytes_read, - read_offset, bytes_to_read); + auto const read_result = + m_filesystem->backing_inode()->read(buffer.subspan(bytes_read.value, bytes_to_read.value), read_offset); if (!read_result) { return kstd::failure(read_result.error()); @@ -83,8 +83,7 @@ namespace kernel::filesystem::ext2 return bytes_read; } - auto inode::write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) - -> kstd::result + auto inode::write(std::span buffer, kstd::units::bytes offset) -> kstd::result { if (!is_regular()) { @@ -94,7 +93,7 @@ namespace kernel::filesystem::ext2 // TODO check maximum file size of filesystem // TODO handle sparse files - auto const new_inode_size = std::max(this->size(), offset + size); + auto const new_inode_size = std::max(this->size(), offset + kstd::units::bytes{buffer.size()}); auto const current_block_count = m_filesystem->inode_block_count(m_data); auto const max_new_inode_size_without_new_blocks = current_block_count * m_filesystem->block_size(); @@ -117,7 +116,7 @@ namespace kernel::filesystem::ext2 auto bytes_written = 0_B; - while (bytes_written < size) + while (bytes_written < kstd::units::bytes{buffer.size()}) { auto const block_number = m_filesystem->map_inode_block_index_to_global_block_number(block_index, m_data); // TODO BA-FS26 if blocknumber == 0 --> handle sparse file @@ -126,13 +125,14 @@ namespace kernel::filesystem::ext2 kstd::failure(block_number.error()); } - auto const bytes_to_write = std::min(size - bytes_written, m_filesystem->block_size() - in_block_offset); + auto const bytes_to_write = + std::min(kstd::units::bytes{buffer.size()} - bytes_written, m_filesystem->block_size() - in_block_offset); auto const block_start_offset = block_number.value() * m_filesystem->block_size(); auto const write_offset = block_start_offset + in_block_offset; - auto const write_result = m_filesystem->backing_inode()->write( - static_cast(buffer) + bytes_written, write_offset, bytes_to_write); + auto const write_result = + m_filesystem->backing_inode()->write(buffer.subspan(bytes_written.value, bytes_to_write.value), write_offset); if (!write_result) { return kstd::failure(write_result.error()); diff --git a/kernel/kernel/filesystem/ext2/inode.hpp b/kernel/kernel/filesystem/ext2/inode.hpp index ce7aae54..9d145dfc 100644 --- a/kernel/kernel/filesystem/ext2/inode.hpp +++ b/kernel/kernel/filesystem/ext2/inode.hpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace kernel::filesystem::ext2 { @@ -60,7 +61,7 @@ namespace kernel::filesystem::ext2 @param size Number of bytes requested. @return Number of bytes read. */ - auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const + [[nodiscard]] auto read(std::span buffer, kstd::units::bytes offset) const -> kstd::result override; /** @@ -70,7 +71,7 @@ namespace kernel::filesystem::ext2 @param size Number of bytes requested. @return Number of bytes written. */ - auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) + auto write(std::span buffer, kstd::units::bytes offset) -> kstd::result override; /** diff --git a/kernel/kernel/filesystem/ext2/inode.tests.cpp b/kernel/kernel/filesystem/ext2/inode.tests.cpp index ce5be2b0..78695b51 100644 --- a/kernel/kernel/filesystem/ext2/inode.tests.cpp +++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -119,7 +120,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in THEN("reading from offset zero returns expected file prefix") { auto buffer = kstd::vector(6); - auto const bytes_read = file.value()->read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + auto const bytes_read = file.value()->read(buffer, 0_B); REQUIRE(bytes_read == 6_B); @@ -130,7 +131,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.value()->read(buffer.data(), 5_B, kstd::units::bytes{buffer.size()}); + auto const bytes_read = file.value()->read(buffer, 5_B); REQUIRE(bytes_read == 1_B); REQUIRE(static_cast(buffer[0]) == '1'); @@ -167,7 +168,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste THEN("correct number of bytes are read and holes are returned as zeros") { - auto const bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + auto const bytes_read = inode.read(buffer, 0_B); REQUIRE(bytes_read == kstd::units::bytes{data.size}); auto const text = std::string_view{reinterpret_cast(buffer.data()), bytes_read->value}; @@ -209,7 +210,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste THEN("correct number of bytes are read and holes are returned as zeros") { - auto const bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + auto const bytes_read = inode.read(buffer, 0_B); REQUIRE(bytes_read == kstd::units::bytes{data.size}); auto const text = std::string_view{reinterpret_cast(buffer.data()), bytes_read->value}; @@ -245,7 +246,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste THEN("all direct blocks are zero when singly indirect block pointer is zero") { - auto const bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + auto const bytes_read = inode.read(buffer, 0_B); REQUIRE(bytes_read == kstd::units::bytes{buffer.size()}); REQUIRE(std::ranges::all_of(buffer, [](std::byte c) { return c == std::byte{0x00}; })); } @@ -278,7 +279,7 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") THEN("reading across the block boundary returns the combined content") { - auto const bytes_read = inode.read(buffer.data(), block_size - 6_B, kstd::units::bytes{buffer.size()}); + auto const bytes_read = inode.read(buffer, block_size - 6_B); REQUIRE(bytes_read == kstd::units::bytes{12}); auto const text = std::string_view{reinterpret_cast(buffer.data()), bytes_read->value}; @@ -316,11 +317,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in std::byte{'o'}, std::byte{' '}, std::byte{'W'}, std::byte{'o'}, std::byte{'r'}, std::byte{'l'}, std::byte{'d'}, std::byte{'!'}}; - auto const bytes_written = file.value()->write(write_buffer.data(), 0_B, kstd::units::bytes{write_buffer.size()}); + auto const bytes_written = file.value()->write(write_buffer, 0_B); REQUIRE(bytes_written == kstd::units::bytes{12}); auto read_buffer = kstd::vector(42, std::byte{0x00}); - auto const bytes_read = file.value()->read(read_buffer.data(), 0_B, kstd::units::bytes{read_buffer.size()}); + auto const bytes_read = file.value()->read(read_buffer, 0_B); REQUIRE(bytes_read == kstd::units::bytes{12}); auto const text = std::string_view{reinterpret_cast(read_buffer.data()), bytes_read->value}; @@ -339,11 +340,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in auto write_buffer = kstd::vector(block_size.value * expected_allocated_blocks, std::byte{'A'}); - auto const bytes_written = file.value()->write(write_buffer.data(), 0_B, kstd::units::bytes{write_buffer.size()}); + auto const bytes_written = file.value()->write(write_buffer, 0_B); REQUIRE(bytes_written == block_size * expected_allocated_blocks); auto read_buffer = kstd::vector(block_size.value * expected_allocated_blocks, std::byte{0x00}); - auto const bytes_read = file.value()->read(read_buffer.data(), 0_B, kstd::units::bytes{read_buffer.size()}); + auto const bytes_read = file.value()->read(read_buffer, 0_B); REQUIRE(bytes_read == block_size * expected_allocated_blocks); REQUIRE(std::ranges::all_of(read_buffer, [](std::byte c) { return c == std::byte{'A'}; })); @@ -355,8 +356,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in THEN("writing to a an inode of type directory panics") { auto write_buffer = kstd::vector(12, std::byte{0xAA}); - REQUIRE_THROWS_AS(information.value()->write(write_buffer.data(), 0_B, kstd::units::bytes{write_buffer.size()}), - kernel::tests::cpu::halt); + REQUIRE_THROWS_AS(information.value()->write(write_buffer, 0_B), kernel::tests::cpu::halt); } } } @@ -392,7 +392,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" block_bitmap[1] = std::byte{0b1111'1111}; block_bitmap[2] = std::byte{0b0011'0000}; - REQUIRE(dev_inode->write(block_bitmap.data(), block_group_descriptor.block_bitmap * block_size, block_size)); + REQUIRE(dev_inode->write(block_bitmap, block_group_descriptor.block_bitmap * block_size)); auto fs = kernel::filesystem::ext2::filesystem{}; REQUIRE(fs.mount(dev_inode)); @@ -408,17 +408,17 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" auto const inode_data_offset = block_group_descriptor.inode_table * block_size + (inode_number - 1) * fs.inode_size(); auto inode = kernel::filesystem::ext2::inode{&fs, inode_number, inode_data}; - REQUIRE(dev_inode->write(&inode, inode_data_offset, kstd::type_size)); + REQUIRE(dev_inode->write(as_bytes(std::span{&inode, 1}), inode_data_offset)); - auto const buffer = kstd::vector{std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'}, - std::byte{'o'}, std::byte{' '}, std::byte{'W'}, std::byte{'o'}, - std::byte{'r'}, std::byte{'l'}, std::byte{'d'}, std::byte{'!'}}; + auto const buffer = + kstd::vector{std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'}, std::byte{'o'}, std::byte{' '}, + std::byte{'W'}, std::byte{'o'}, std::byte{'r'}, std::byte{'l'}, std::byte{'d'}, std::byte{'!'}}; GIVEN("mocked ext2 filesystem") { auto do_read_inode = [&]() { auto inode_data = kernel::filesystem::ext2::inode_data{}; - REQUIRE(dev_inode->read(&inode_data, inode_data_offset, kstd::type_size)); + REQUIRE(dev_inode->read(as_writable_bytes(std::span{&inode_data, 1}), inode_data_offset)); auto read_inode = kernel::filesystem::ext2::inode{&fs, inode_number, inode_data}; return read_inode; }; @@ -426,14 +426,14 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" THEN("writing in the current size does not update the size and does not allocate new blocks") { auto const expected_bytes_written = 3_B; - auto const bytes_written = inode.write(buffer.data(), 0_B, expected_bytes_written); + auto const bytes_written = inode.write(std::span{buffer}.subspan(0, 3), 0_B); REQUIRE(bytes_written == expected_bytes_written); auto const text = std::string_view{reinterpret_cast(device->data.data() + 20 * block_size), 3}; REQUIRE(text == "Hel"); auto read_block_bitmap = std::vector(block_size.value, std::byte{0x00}); - REQUIRE(dev_inode->read(read_block_bitmap.data(), block_group_descriptor.block_bitmap * block_size, block_size)); + REQUIRE(dev_inode->read(read_block_bitmap, block_group_descriptor.block_bitmap * block_size)); REQUIRE(block_bitmap == read_block_bitmap); auto read_inode = do_read_inode(); @@ -449,7 +449,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" "blocks") { auto const offset = block_size - 4_B; - auto const bytes_written = inode.write(buffer.data(), offset, kstd::units::bytes{buffer.size()}); + auto const bytes_written = inode.write(buffer, offset); REQUIRE(bytes_written == kstd::units::bytes{buffer.size()}); auto const text = std::string_view{ @@ -457,7 +457,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" REQUIRE(text == "Hello World!"); auto read_block_bitmap = std::vector(block_size.value, std::byte{0x00}); - REQUIRE(dev_inode->read(read_block_bitmap.data(), block_group_descriptor.block_bitmap * block_size, block_size)); + REQUIRE(dev_inode->read(read_block_bitmap, block_group_descriptor.block_bitmap * block_size)); REQUIRE(block_bitmap == read_block_bitmap); auto read_inode = do_read_inode(); @@ -472,16 +472,16 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" THEN("writing over the current size and over allocated blocks updates size and allocates a new block") { auto const offset = block_size * 2 - 4_B; - auto const bytes_written = inode.write(buffer.data(), offset, kstd::units::bytes{buffer.size()}); + auto const bytes_written = inode.write(buffer, offset); REQUIRE(bytes_written == kstd::units::bytes{buffer.size()}); auto read_buffer = std::vector(buffer.size(), std::byte{0x00}); - auto const bytes_read = inode.read(read_buffer.data(), offset, kstd::units::bytes{buffer.size()}); + auto const bytes_read = inode.read(read_buffer, offset); auto const text = std::string_view{reinterpret_cast(read_buffer.data()), bytes_read->value}; REQUIRE(text == "Hello World!"); auto read_block_bitmap = std::vector(block_size.value, std::byte{0x00}); - REQUIRE(dev_inode->read(read_block_bitmap.data(), block_group_descriptor.block_bitmap * block_size, block_size)); + REQUIRE(dev_inode->read(read_block_bitmap, block_group_descriptor.block_bitmap * block_size)); auto expected_block_bitmap = block_bitmap; expected_block_bitmap[2] = std::byte{0b0011'0001}; @@ -500,8 +500,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]" THEN("writing over the current size and over the number of free blocks") { auto const offset = 65 * block_size; - REQUIRE_THROWS_AS(inode.write(buffer.data(), offset, kstd::units::bytes{buffer.size()}), - kernel::tests::cpu::halt); + REQUIRE_THROWS_AS(inode.write(buffer, offset), kernel::tests::cpu::halt); } } } diff --git a/kernel/kernel/filesystem/inode.hpp b/kernel/kernel/filesystem/inode.hpp index 25e5df31..7ebac995 100644 --- a/kernel/kernel/filesystem/inode.hpp +++ b/kernel/kernel/filesystem/inode.hpp @@ -6,7 +6,9 @@ #include #include +#include #include +#include namespace kernel::filesystem { @@ -25,7 +27,7 @@ namespace kernel::filesystem //! @param offset Read offset in bytes. //! @param size Number of bytes requested. //! @return The number of bytes read on success, an error otherwise. - virtual auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const + [[nodiscard]] virtual auto read(std::span buffer, kstd::units::bytes offset) const -> kstd::result = 0; //! Writes data from a buffer into this inode. @@ -34,7 +36,7 @@ namespace kernel::filesystem //! @param offset Write offset in bytes. //! @param size Number of bytes to write. //! @return The number of bytes written on success, an error otherwise. - virtual auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) + virtual auto write(std::span buffer, kstd::units::bytes offset) -> kstd::result = 0; //! Check if this inode is a directory. diff --git a/kernel/kernel/filesystem/open_file_descriptor.cpp b/kernel/kernel/filesystem/open_file_descriptor.cpp index e233b5da..71dd172b 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.cpp +++ b/kernel/kernel/filesystem/open_file_descriptor.cpp @@ -7,6 +7,9 @@ #include #include +#include +#include + namespace kernel::filesystem { open_file_descriptor::open_file_descriptor(kstd::shared_ptr const & dentry) @@ -19,9 +22,9 @@ namespace kernel::filesystem } } - auto open_file_descriptor::read(void * buffer, kstd::units::bytes size) -> kstd::result + auto open_file_descriptor::read(std::span buffer) -> kstd::result { - if (auto result = m_dentry->get_inode()->read(buffer, m_offset, size); !result) + if (auto result = m_dentry->get_inode()->read(buffer, m_offset); !result) { return kstd::failure(result.error()); } @@ -33,9 +36,9 @@ namespace kernel::filesystem } } - auto open_file_descriptor::write(void const * buffer, kstd::units::bytes size) -> kstd::result + auto open_file_descriptor::write(std::span buffer) -> kstd::result { - if (auto result = m_dentry->get_inode()->write(buffer, m_offset, size); !result) + if (auto result = m_dentry->get_inode()->write(buffer, m_offset); !result) { return kstd::failure(result.error()); } diff --git a/kernel/kernel/filesystem/open_file_descriptor.hpp b/kernel/kernel/filesystem/open_file_descriptor.hpp index 1ecc09a9..247108c1 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.hpp +++ b/kernel/kernel/filesystem/open_file_descriptor.hpp @@ -7,6 +7,9 @@ #include #include +#include +#include + namespace kernel::filesystem { /** @@ -31,20 +34,18 @@ namespace kernel::filesystem given @p size. The file offset is advanced by the number of bytes read. @param buffer The buffer to read data into. - @param size The number of bytes to read. @return The number of bytes read. */ - auto read(void * buffer, kstd::units::bytes size) -> kstd::result; + auto read(std::span buffer) -> kstd::result; /** @brief Writes data to the open file descriptor from a @p buffer, starting at the current file offset and for a given @p size. The file offset is advanced by the number of bytes written. @param buffer The buffer to write data from. - @param size The number of bytes to write. @return The number of bytes written. */ - auto write(void const * buffer, kstd::units::bytes size) -> kstd::result; + auto write(std::span buffer) -> 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 5301d201..ec86e8d3 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp +++ b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp @@ -21,7 +21,9 @@ #include #include +#include #include +#include using namespace kstd::units_literals; @@ -52,29 +54,35 @@ SCENARIO("Open file descriptor read/write offset management", "[filesystem][open THEN("the offset is updated correctly after reads") { - REQUIRE(file_descriptor.read(nullptr, 100_B) == 100_B); + auto buffer = std::vector{100}; + + REQUIRE(file_descriptor.read(buffer) == 100_B); REQUIRE(file_descriptor.offset() == 100_B); - REQUIRE(file_descriptor.read(nullptr, 50_B) == 50_B); + REQUIRE(file_descriptor.read(std::span{buffer}.subspan(0, 50)) == 50_B); REQUIRE(file_descriptor.offset() == 150_B); } THEN("the offset is updated correctly after writes") { - REQUIRE(file_descriptor.write(nullptr, 200_B) == 200_B); + auto buffer = std::vector{200}; + + REQUIRE(file_descriptor.write(buffer) == 200_B); REQUIRE(file_descriptor.offset() == 200_B); - REQUIRE(file_descriptor.write(nullptr, 25_B) == 25_B); + REQUIRE(file_descriptor.write(std::span{buffer}.subspan(0, 25)) == 25_B); REQUIRE(file_descriptor.offset() == 225_B); } THEN("reads and writes both update the same offset") { - REQUIRE(file_descriptor.read(nullptr, 10_B) == 10_B); + auto buffer = std::vector{20}; + + REQUIRE(file_descriptor.read(std::span{buffer}.subspan(0, 10)) == 10_B); REQUIRE(file_descriptor.offset() == 10_B); - REQUIRE(file_descriptor.write(nullptr, 20_B) == 20_B); + REQUIRE(file_descriptor.write(std::span{buffer}.subspan(0, 20)) == 20_B); REQUIRE(file_descriptor.offset() == 30_B); - REQUIRE(file_descriptor.read(nullptr, 5_B) == 5_B); + REQUIRE(file_descriptor.read(std::span{buffer}.subspan(0, 5)) == 5_B); REQUIRE(file_descriptor.offset() == 35_B); - REQUIRE(file_descriptor.write(nullptr, 15_B) == 15_B); + REQUIRE(file_descriptor.write(std::span{buffer}.subspan(0, 15)) == 15_B); REQUIRE(file_descriptor.offset() == 50_B); } } @@ -98,7 +106,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope THEN("the file can be read and the offset is updated") { kstd::vector buffer(32); - auto bytes_read = ofd->read(buffer.data(), kstd::units::bytes{buffer.size()}); + auto bytes_read = ofd->read(buffer); REQUIRE(bytes_read == 7_B); REQUIRE(ofd->offset() == 7_B); @@ -109,11 +117,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope THEN("the file can be read multiple times and the offset is updated") { kstd::vector buffer(4); - auto bytes_read_1 = ofd->read(buffer.data(), kstd::units::bytes{buffer.size() / 2}); + auto bytes_read_1 = ofd->read(std::span{buffer}.first(buffer.size() / 2)); REQUIRE(bytes_read_1 == kstd::units::bytes{buffer.size() / 2}); REQUIRE(ofd->offset() == kstd::units::bytes{buffer.size() / 2}); - auto bytes_read_2 = ofd->read(buffer.data() + buffer.size() / 2, kstd::units::bytes{buffer.size() / 2}); + auto bytes_read_2 = ofd->read(std::span{buffer}.last(buffer.size() / 2)); REQUIRE(bytes_read_2 == kstd::units::bytes{buffer.size() / 2}); REQUIRE(ofd->offset() == kstd::units::bytes{buffer.size()}); @@ -125,7 +133,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope THEN("the file can be written to and the offset is updated") { auto write_buffer = kstd::vector(12, std::byte{0xAA}); - auto const bytes_written = ofd->write(write_buffer.data(), kstd::units::bytes{write_buffer.size()}); + auto const bytes_written = ofd->write(write_buffer); REQUIRE(bytes_written == 12_B); REQUIRE(ofd->offset() == 12_B); } @@ -133,12 +141,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Ope THEN("the file can be written to multiple times and the offset is updated") { auto write_buffer = kstd::vector(8, std::byte{0xAA}); - auto const bytes_written_1 = ofd->write(write_buffer.data(), kstd::units::bytes{write_buffer.size() / 2}); + auto const bytes_written_1 = ofd->write(std::span{write_buffer}.first(write_buffer.size() / 2)); REQUIRE(bytes_written_1 == kstd::units::bytes{write_buffer.size() / 2}); REQUIRE(ofd->offset() == kstd::units::bytes{write_buffer.size() / 2}); - auto const bytes_written_2 = - ofd->write(write_buffer.data() + write_buffer.size() / 2, kstd::units::bytes{write_buffer.size() / 2}); + auto const bytes_written_2 = ofd->write(std::span{write_buffer}.last(write_buffer.size() / 2)); REQUIRE(bytes_written_2 == kstd::units::bytes{write_buffer.size() / 2}); REQUIRE(ofd->offset() == kstd::units::bytes{write_buffer.size()}); } @@ -179,7 +186,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Open fi THEN("reading through the file descriptor fails with 'no such device'") { auto buffer = kstd::vector(10); - auto bytes_read = fd->read(buffer.data(), kstd::units::bytes{buffer.size()}); + auto bytes_read = fd->read(buffer); REQUIRE(bytes_read.error() == kstd::errc::no_such_device); } @@ -187,7 +194,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Open fi THEN("writing through the file descriptor fails with 'no such device'") { auto buffer = kstd::vector(10); - auto bytes_written = fd->write(buffer.data(), kstd::units::bytes{buffer.size()}); + auto bytes_written = fd->write(buffer); REQUIRE(bytes_written.error() == kstd::errc::no_such_device); } diff --git a/kernel/kernel/filesystem/rootfs/inode.cpp b/kernel/kernel/filesystem/rootfs/inode.cpp index 43aee16e..07607417 100644 --- a/kernel/kernel/filesystem/rootfs/inode.cpp +++ b/kernel/kernel/filesystem/rootfs/inode.cpp @@ -5,14 +5,17 @@ #include #include +#include +#include + namespace kernel::filesystem::rootfs { - auto inode::read(void *, kstd::units::bytes, kstd::units::bytes) const -> kstd::result + auto inode::read(std::span, kstd::units::bytes) const -> kstd::result { return kstd::units::bytes{}; } - auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes) -> kstd::result + auto inode::write(std::span, kstd::units::bytes) -> kstd::result { return kstd::units::bytes{}; } diff --git a/kernel/kernel/filesystem/rootfs/inode.hpp b/kernel/kernel/filesystem/rootfs/inode.hpp index a61e83f1..e9c6e738 100644 --- a/kernel/kernel/filesystem/rootfs/inode.hpp +++ b/kernel/kernel/filesystem/rootfs/inode.hpp @@ -9,6 +9,9 @@ #include #include +#include +#include + namespace kernel::filesystem::rootfs { /** @@ -20,20 +23,18 @@ namespace kernel::filesystem::rootfs @brief Reads from the rootfs directory inode. @param buffer Destination buffer. @param offset Read offset in bytes. - @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, kstd::units::bytes offset, kstd::units::bytes size) const + [[nodiscard]] auto read(std::span buffer, kstd::units::bytes offset) const -> kstd::result override; /** @brief Writes to the rootfs directory inode. @param buffer Source buffer. @param offset Write offset in bytes. - @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, kstd::units::bytes offset, kstd::units::bytes size) + auto write(std::span buffer, kstd::units::bytes offset) -> kstd::result override; /** diff --git a/kernel/kernel/filesystem/rootfs/inode.tests.cpp b/kernel/kernel/filesystem/rootfs/inode.tests.cpp index 9819743d..560e7953 100644 --- a/kernel/kernel/filesystem/rootfs/inode.tests.cpp +++ b/kernel/kernel/filesystem/rootfs/inode.tests.cpp @@ -7,6 +7,8 @@ #include +#include + using namespace kstd::units_literals; SCENARIO("Rootfs inode read/write", "[filesystem][rootfs][inode]") @@ -17,8 +19,8 @@ SCENARIO("Rootfs inode read/write", "[filesystem][rootfs][inode]") WHEN("reading from the inode") { - kstd::vector buffer(10); - auto bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + kstd::vector buffer(10); + auto bytes_read = inode.read(buffer, 0_B); THEN("no bytes are read") { @@ -28,8 +30,8 @@ SCENARIO("Rootfs inode read/write", "[filesystem][rootfs][inode]") WHEN("writing to the inode") { - kstd::vector buffer(10, 'x'); - auto bytes_written = inode.write(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + kstd::vector buffer(10, std::byte{'x'}); + auto bytes_written = inode.write(buffer, 0_B); THEN("no bytes are written") { diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp index e1d539d8..835cbfd6 100644 --- a/kernel/kernel/filesystem/vfs.cpp +++ b/kernel/kernel/filesystem/vfs.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -395,8 +396,8 @@ namespace kernel::filesystem return kstd::failure(vfs_errc::too_many_symbolic_link_levels); } - kstd::vector buffer(constants::symlink_max_path_length); - auto const bytes_read = next_dentry->get_inode()->read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()}); + kstd::vector buffer(constants::symlink_max_path_length); + auto const bytes_read = next_dentry->get_inode()->read(buffer, 0_B); if (!bytes_read) { return kstd::failure(bytes_read.error()); diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp index 8667a914..8693b9f5 100644 --- a/kernel/kernel/filesystem/vfs.tests.cpp +++ b/kernel/kernel/filesystem/vfs.tests.cpp @@ -403,7 +403,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS auto sheep_1_ofd = kstd::make_shared(dentry.value()); kstd::vector buffer(7); - auto bytes_read = sheep_1_ofd->read(buffer.data(), kstd::units::bytes{buffer.size()}); + auto bytes_read = sheep_1_ofd->read(buffer); std::string_view buffer_as_str{reinterpret_cast(buffer.data()), bytes_read->value}; REQUIRE(buffer_as_str == "sheep_1"); @@ -430,12 +430,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS 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(), kstd::units::bytes{sheep_buffer.size()}); + auto bytes_read = sheep_1_ofd->read(sheep_buffer); std::string_view buffer_as_str{reinterpret_cast(sheep_buffer.data()), bytes_read->value}; REQUIRE(buffer_as_str == "sheep_1"); kstd::vector goat_buffer(6); - bytes_read = goat_1_ofd->read(goat_buffer.data(), kstd::units::bytes{goat_buffer.size()}); + bytes_read = goat_1_ofd->read(goat_buffer); buffer_as_str = std::string_view{reinterpret_cast(goat_buffer.data()), bytes_read->value}; REQUIRE(buffer_as_str == "goat_1"); @@ -665,11 +665,11 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "VFS REQUIRE(via_persistent_fs != nullptr); auto marker = kstd::vector{std::byte{'M'}, std::byte{'K'}, std::byte{'N'}, std::byte{'O'}, std::byte{'D'}}; - auto written = (*via_persistent_fs)->get_inode()->write(marker.data(), 0_B, kstd::units::bytes{marker.size()}); + auto written = (*via_persistent_fs)->get_inode()->write(marker, 0_B); REQUIRE(written == kstd::units::bytes{marker.size()}); auto read_back = kstd::vector(marker.size()); - auto read = (*via_devfs)->get_inode()->read(read_back.data(), 0_B, kstd::units::bytes{read_back.size()}); + auto read = (*via_devfs)->get_inode()->read(read_back, 0_B); REQUIRE(read == kstd::units::bytes{marker.size()}); REQUIRE(read_back == marker); diff --git a/kernel/kernel/test_support/devices/block_device.cpp b/kernel/kernel/test_support/devices/block_device.cpp index a92b095b..b0db0762 100644 --- a/kernel/kernel/test_support/devices/block_device.cpp +++ b/kernel/kernel/test_support/devices/block_device.cpp @@ -10,8 +10,8 @@ #include #include -#include #include +#include #include using namespace kstd::units_literals; @@ -25,27 +25,28 @@ namespace kernel::tests::devices data.resize(initial_size.value, 0); } - auto block_device::read_block(size_t block_index, void * buffer) const -> kstd::result + auto block_device::read_block(size_t block_index, std::span buffer) const + -> kstd::result { auto const offset = block_index * block_size(); if (offset.value >= data.size()) { - kstd::libc::memset(buffer, 0, block_size().value); + kstd::libc::memset(buffer.data(), 0, block_size().value); return 0_B; } auto const bytes_to_read = std::min(block_size(), kstd::units::bytes{data.size()} - offset); - kstd::libc::memcpy(buffer, data.data() + offset, bytes_to_read.value); + kstd::libc::memcpy(buffer.data(), data.data() + offset, bytes_to_read.value); if (bytes_to_read < block_size()) { - kstd::libc::memset(static_cast(buffer) + bytes_to_read, 0, - static_cast(block_size() - bytes_to_read)); + kstd::libc::memset(buffer.data() + bytes_to_read, 0, static_cast(block_size() - bytes_to_read)); } return bytes_to_read; } - auto block_device::write_block(size_t block_index, void const * buffer) -> kstd::result + auto block_device::write_block(size_t block_index, std::span buffer) + -> kstd::result { auto const offset = block_index * block_size(); auto const write_end = offset + block_size(); @@ -54,7 +55,7 @@ namespace kernel::tests::devices data.resize(write_end.value, 0); } - kstd::libc::memcpy(data.data() + offset, static_cast(buffer), block_size().value); + kstd::libc::memcpy(data.data() + offset, buffer.data(), block_size().value); return block_size(); } diff --git a/kernel/kernel/test_support/devices/block_device.hpp b/kernel/kernel/test_support/devices/block_device.hpp index 94201da1..9f7f698c 100644 --- a/kernel/kernel/test_support/devices/block_device.hpp +++ b/kernel/kernel/test_support/devices/block_device.hpp @@ -11,6 +11,7 @@ #include #include +#include namespace kernel::tests::devices { @@ -19,8 +20,9 @@ namespace kernel::tests::devices { block_device(kstd::string const & name, kstd::units::bytes block_size, kstd::units::bytes initial_size = {}); - auto read_block(size_t block_index, void * buffer) const -> kstd::result override; - auto write_block(size_t block_index, void const * buffer) -> kstd::result override; + auto read_block(size_t block_index, std::span buffer) const -> kstd::result override; + auto write_block(size_t block_index, std::span buffer) + -> kstd::result override; [[nodiscard]] auto block_size() const -> kstd::units::bytes override; [[nodiscard]] auto capacity() const -> kstd::units::bytes override; diff --git a/kernel/kernel/test_support/filesystem/inode.cpp b/kernel/kernel/test_support/filesystem/inode.cpp index 1d090589..96a30c33 100644 --- a/kernel/kernel/test_support/filesystem/inode.cpp +++ b/kernel/kernel/test_support/filesystem/inode.cpp @@ -5,16 +5,19 @@ #include #include +#include +#include + namespace kernel::tests::filesystem { - auto inode::read(void *, kstd::units::bytes, kstd::units::bytes size) const -> kstd::result + auto inode::read(std::span buffer, kstd::units::bytes) const -> kstd::result { - return size; + return kstd::units::bytes{buffer.size()}; } - auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes size) -> kstd::result + auto inode::write(std::span buffer, kstd::units::bytes) -> kstd::result { - return size; + return kstd::units::bytes{buffer.size()}; } auto inode::is_regular() const -> bool diff --git a/kernel/kernel/test_support/filesystem/inode.hpp b/kernel/kernel/test_support/filesystem/inode.hpp index d2fbf19d..383ca6f5 100644 --- a/kernel/kernel/test_support/filesystem/inode.hpp +++ b/kernel/kernel/test_support/filesystem/inode.hpp @@ -6,13 +6,16 @@ #include #include +#include +#include + namespace kernel::tests::filesystem { struct inode : kernel::filesystem::inode { - auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const + auto read(std::span buffer, kstd::units::bytes offset) const -> kstd::result override; - auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size) + auto write(std::span buffer, kstd::units::bytes offset) -> kstd::result override; [[nodiscard]] auto is_regular() const -> bool override; -- cgit v1.2.3