aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kapi/filesystem.cpp4
-rw-r--r--kernel/kernel/devices/block_device_utils.cpp72
-rw-r--r--kernel/kernel/devices/block_device_utils.hpp41
-rw-r--r--kernel/kernel/devices/block_device_utils.tests.cpp81
-rw-r--r--kernel/kernel/drivers/storage/ram_disk.cpp29
-rw-r--r--kernel/kernel/filesystem/devfs/inode.cpp7
-rw-r--r--kernel/kernel/filesystem/devfs/inode.hpp7
-rw-r--r--kernel/kernel/filesystem/devfs/inode.tests.cpp10
-rw-r--r--kernel/kernel/filesystem/device_inode.cpp12
-rw-r--r--kernel/kernel/filesystem/device_inode.hpp6
-rw-r--r--kernel/kernel/filesystem/device_inode.tests.cpp27
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.cpp39
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.tests.cpp12
-rw-r--r--kernel/kernel/filesystem/ext2/inode.cpp28
-rw-r--r--kernel/kernel/filesystem/ext2/inode.hpp5
-rw-r--r--kernel/kernel/filesystem/ext2/inode.tests.cpp53
-rw-r--r--kernel/kernel/filesystem/inode.hpp6
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.cpp11
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.hpp9
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.tests.cpp41
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.cpp7
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.hpp9
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.tests.cpp10
-rw-r--r--kernel/kernel/filesystem/vfs.cpp5
-rw-r--r--kernel/kernel/filesystem/vfs.tests.cpp10
-rw-r--r--kernel/kernel/test_support/devices/block_device.cpp17
-rw-r--r--kernel/kernel/test_support/devices/block_device.hpp6
-rw-r--r--kernel/kernel/test_support/filesystem/inode.cpp11
-rw-r--r--kernel/kernel/test_support/filesystem/inode.hpp7
29 files changed, 288 insertions, 294 deletions
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<std::byte> buffer) -> std::expected<kstd::units::bytes, kstd::error_code>
{
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<kstd::units::bytes, kstd::error_code>
{
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 <kernel/devices/block_device_utils.hpp>
#include <kapi/filesystem.hpp>
-#include <kapi/system.hpp>
#include <kstd/cstring.hpp>
#include <kstd/result.hpp>
@@ -10,6 +9,7 @@
#include <algorithm>
#include <cstddef>
+#include <span>
using namespace kstd::units_literals;
@@ -21,17 +21,14 @@ namespace kernel::devices::block_device_utils
using block_op = kstd::result<kstd::units::bytes> (*)(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<std::byte> scratch, std::span<std::byte> 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<kstd::units::bytes>
+ std::span<std::byte> buffer, block_op op) -> kstd::result<kstd::units::bytes>
{
- 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<std::byte> 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<kstd::units::bytes>
+ auto read(kapi::filesystem::block_special_file & device, std::span<std::byte> buffer, kstd::units::bytes offset)
+ -> kstd::result<kstd::units::bytes>
{
- 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<std::byte *>(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<kstd::units::bytes>
+ auto write(kapi::filesystem::block_special_file & device, std::span<std::byte const> buffer,
+ kstd::units::bytes offset) -> kstd::result<kstd::units::bytes>
{
- return process_blocks(device, offset, size, const_cast<void *>(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<std::byte const *>(buffer);
+ auto non_cost_span = std::span{const_cast<std::byte *>(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 <kstd/units.hpp>
#include <cstddef>
+#include <span>
/**
@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<kstd::units::bytes>;
-
- /**
- @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<kstd::units::bytes>;
+ //! 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<std::byte> buffer, kstd::units::bytes offset)
+ -> kstd::result<kstd::units::bytes>;
+
+ //! @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<std::byte const> buffer,
+ kstd::units::bytes offset) -> kstd::result<kstd::units::bytes>;
} // 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 <catch2/catch_test_macros.hpp>
#include <cstddef>
-#include <cstdint>
+#include <span>
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<kernel::tests::devices::block_device>("test_block_device", block_size);
- kstd::vector<uint8_t> block_data(block_size.value);
+ kstd::vector<std::byte> block_data(block_size.value);
for (size_t i = 0; i < block_data.size(); ++i)
{
- block_data[i] = static_cast<uint8_t>(i % 256);
+ block_data[i] = static_cast<std::byte>(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<uint8_t> 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<std::byte> 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<uint8_t> 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<std::byte> 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<uint8_t>((256 + i) % 256);
+ auto expected_value = static_cast<std::byte>((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<uint8_t> 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<std::byte> 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<uint8_t> read_buffer(block_size.value);
- auto bytes_read = kernel::devices::block_device_utils::read(*device, read_buffer.data(), 0_B, 0_B);
+ kstd::vector<std::byte> 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<uint8_t> write_buffer(block_size.value);
+ kstd::vector<std::byte> write_buffer(block_size.value);
for (size_t i = 0; i < write_buffer.size(); ++i)
{
- write_buffer[i] = static_cast<uint8_t>(i % 256);
+ write_buffer[i] = static_cast<std::byte>(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<uint8_t> read_buffer(block_size.value);
- CHECK(device->read_block(0, read_buffer.data()));
+ kstd::vector<std::byte> read_buffer(block_size.value);
+ CHECK(device->read_block(0, read_buffer));
REQUIRE(read_buffer == write_buffer);
}
}
WHEN("writing over block boundaries")
{
- kstd::vector<uint8_t> write_buffer(2 * block_size.value);
+ kstd::vector<std::byte> write_buffer(2 * block_size.value);
for (size_t i = 0; i < write_buffer.size(); ++i)
{
- write_buffer[i] = static_cast<uint8_t>(i % 256);
+ write_buffer[i] = static_cast<std::byte>(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<uint8_t> 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<std::byte> 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<uint8_t> 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<std::byte> 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<uint8_t> write_buffer(block_size.value);
- auto bytes_written = kernel::devices::block_device_utils::write(*device, write_buffer.data(), 0_B, 0_B);
+ kstd::vector<std::byte> 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 <kapi/boot_modules.hpp>
#include <kapi/devices.hpp>
#include <kapi/filesystem.hpp>
-#include <kapi/system.hpp>
#include <kstd/cstring.hpp>
#include <kstd/format.hpp>
@@ -19,6 +18,7 @@
#include <cstddef>
#include <cstdint>
#include <optional>
+#include <span>
#include <string_view>
#include <utility>
@@ -54,45 +54,38 @@ namespace kernel::drivers::storage
: m_module(module)
{}
- auto read_block(std::size_t block_index, void * buffer) const -> kstd::result<kstd::units::bytes> override
+ [[nodiscard]] auto read_block(std::size_t block_index, std::span<std::byte> buffer) const
+ -> kstd::result<kstd::units::bytes> 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<std::byte const *>(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<std::byte *>(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<kstd::units::bytes> override
+ auto write_block(std::size_t block_index, std::span<std::byte const> buffer)
+ -> kstd::result<kstd::units::bytes> 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<std::byte *>(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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
+#include <span>
+
using namespace kstd::units_literals;
namespace kernel::filesystem::devfs
{
- auto inode::read(void *, kstd::units::bytes, kstd::units::bytes) const -> kstd::result<kstd::units::bytes>
+ auto inode::read(std::span<std::byte>, kstd::units::bytes) const -> kstd::result<kstd::units::bytes>
{
return 0_B;
}
- auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes) -> kstd::result<kstd::units::bytes>
+ auto inode::write(std::span<std::byte const>, kstd::units::bytes) -> kstd::result<kstd::units::bytes>
{
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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
+#include <span>
+
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<std::byte> buffer, kstd::units::bytes offset) const
-> kstd::result<kstd::units::bytes> 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<std::byte const> buffer, kstd::units::bytes offset)
-> kstd::result<kstd::units::bytes> 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 <catch2/catch_test_macros.hpp>
-#include <cstdint>
+#include <cstddef>
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<uint8_t> buffer(512);
- auto bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ kstd::vector<std::byte> 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<uint8_t> buffer(512);
- auto bytes_written = inode.write(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ kstd::vector<std::byte> 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<std::byte> buffer, kstd::units::bytes offset) const
-> kstd::result<kstd::units::bytes>
{
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<kapi::filesystem::block_special_file>(*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<kapi::filesystem::character_special_file>(*m_device))
{
- return character_device->read(std::span{static_cast<std::byte *>(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<std::byte const> buffer, kstd::units::bytes offset)
-> kstd::result<kstd::units::bytes>
{
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<kapi::filesystem::block_special_file>(*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<kapi::filesystem::character_special_file>(*m_device))
{
- return character_device->write(std::span{static_cast<std::byte const *>(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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
#include <optional>
+#include <span>
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<std::byte> buffer, kstd::units::bytes offset) const
-> kstd::result<kstd::units::bytes> 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<std::byte const> buffer, kstd::units::bytes offset)
-> kstd::result<kstd::units::bytes> 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 <cstddef>
#include <cstdint>
+#include <span>
#include <utility>
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<kstd::units::bytes> override
+ auto read(std::span<std::byte>, kstd::units::bytes) const -> kstd::result<kstd::units::bytes> override
{
return 0_B;
}
- auto write(void const *, kstd::units::bytes, kstd::units::bytes) -> kstd::result<kstd::units::bytes> override
+ auto write(std::span<std::byte const>, kstd::units::bytes) -> kstd::result<kstd::units::bytes> override
{
return 0_B;
}
@@ -104,13 +105,13 @@ SCENARIO("Device inode read/write", "[filesystem][device_inode]")
WHEN("writing to the device inode")
{
- kstd::vector<uint8_t> write_buffer(1024);
+ kstd::vector<std::byte> write_buffer(1024);
for (size_t i = 0; i < write_buffer.size(); ++i)
{
- write_buffer[i] = static_cast<uint8_t>(i % 256);
+ write_buffer[i] = static_cast<std::byte>(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<uint8_t> read_buffer(1024);
- auto bytes_read = inode.read(read_buffer.data(), 256_B, kstd::units::bytes{read_buffer.size()});
+ kstd::vector<std::byte> 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<uint8_t> read_buffer(512);
+ kstd::vector<std::byte> 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<uint8_t> write_buffer(512);
+ kstd::vector<std::byte> 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<uint8_t> buffer(512);
- auto const result = inode.read(buffer.data(), 0_B, 512_B);
+ kstd::vector<std::byte> 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 <cstdint>
#include <expected>
#include <optional>
+#include <span>
#include <string_view>
#include <tuple>
@@ -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<block_group_descriptor>(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<block_group_descriptor>);
+ 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<inode_data>);
+ 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<inode_data>).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<uint32_t>;
- if (auto read_result = m_backing_inode->read(&block_number_buffer, number_start_address, kstd::type_size<uint32_t>);
+ 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<uint32_t>);
+ 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<uint32_t>);
+ 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<kstd::units::bytes>
{
auto const block_offset = static_cast<size_t>(block_number) * block_size();
- return m_backing_inode->read(buffer, block_offset, block_size());
+ return m_backing_inode->read(std::span{static_cast<std::byte *>(buffer), block_size().value}, block_offset);
}
auto filesystem::write_block(uint32_t block_number, void const * buffer) -> kstd::result<kstd::units::bytes>
{
auto const block_offset = static_cast<size_t>(block_number) * block_size();
- return m_backing_inode->write(buffer, block_offset, block_size());
+ return m_backing_inode->write(std::span{static_cast<std::byte const *>(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<void>
{
// 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>{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<std::byte>(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<char *>(read_buffer.data()), static_cast<size_t>(*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<kernel::filesystem::device_inode>(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 <cstddef>
#include <cstdint>
#include <optional>
+#include <span>
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<kstd::units::bytes>
+ auto inode::read(std::span<std::byte> buffer, kstd::units::bytes offset) const -> kstd::result<kstd::units::bytes>
{
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<uint8_t const *>(m_data.block.data());
- kstd::libc::memcpy(static_cast<uint8_t *>(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<uint8_t *>(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<uint8_t *>(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<kstd::units::bytes>
+ auto inode::write(std::span<std::byte const> buffer, kstd::units::bytes offset) -> kstd::result<kstd::units::bytes>
{
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<uint8_t const *>(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 <cstddef>
#include <cstdint>
#include <optional>
+#include <span>
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<std::byte> buffer, kstd::units::bytes offset) const
-> kstd::result<kstd::units::bytes> 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<std::byte const> buffer, kstd::units::bytes offset)
-> kstd::result<kstd::units::bytes> 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 <cstddef>
#include <cstdint>
#include <filesystem>
+#include <span>
#include <string_view>
#include <utility>
#include <vector>
@@ -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<std::byte>(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<std::byte>(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<char>(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<char const *>(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<char const *>(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<char const *>(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<std::byte>(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<char const *>(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<std::byte>(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<std::byte>(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<std::byte>(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<kernel::filesystem::ext2::inode_data>));
+ REQUIRE(dev_inode->write(as_bytes(std::span{&inode, 1}), inode_data_offset));
- auto const buffer = kstd::vector<std::byte>{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<kernel::filesystem::ext2::inode_data>));
+ 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<char const *>(device->data.data() + 20 * block_size), 3};
REQUIRE(text == "Hel");
auto read_block_bitmap = std::vector<std::byte>(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<std::byte>(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<std::byte>(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<char const *>(read_buffer.data()), bytes_read->value};
REQUIRE(text == "Hello World!");
auto read_block_bitmap = std::vector<std::byte>(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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
#include <optional>
+#include <span>
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<std::byte> buffer, kstd::units::bytes offset) const
-> kstd::result<kstd::units::bytes> = 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<std::byte const> buffer, kstd::units::bytes offset)
-> kstd::result<kstd::units::bytes> = 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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
+#include <span>
+
namespace kernel::filesystem
{
open_file_descriptor::open_file_descriptor(kstd::shared_ptr<dentry> const & dentry)
@@ -19,9 +22,9 @@ namespace kernel::filesystem
}
}
- auto open_file_descriptor::read(void * buffer, kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
+ auto open_file_descriptor::read(std::span<std::byte> buffer) -> kstd::result<kstd::units::bytes>
{
- 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<kstd::units::bytes>
+ auto open_file_descriptor::write(std::span<std::byte const> buffer) -> kstd::result<kstd::units::bytes>
{
- 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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
+#include <span>
+
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<kstd::units::bytes>;
+ auto read(std::span<std::byte> buffer) -> kstd::result<kstd::units::bytes>;
/**
@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<kstd::units::bytes>;
+ auto write(std::span<std::byte const> buffer) -> kstd::result<kstd::units::bytes>;
/**
@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 <cstddef>
#include <filesystem>
+#include <span>
#include <string_view>
+#include <vector>
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<std::byte>{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<std::byte>{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<std::byte>{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<std::byte> 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<std::byte> 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<std::byte>(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<std::byte>(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<std::byte>(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<std::byte>(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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
+#include <span>
+
namespace kernel::filesystem::rootfs
{
- auto inode::read(void *, kstd::units::bytes, kstd::units::bytes) const -> kstd::result<kstd::units::bytes>
+ auto inode::read(std::span<std::byte>, kstd::units::bytes) const -> kstd::result<kstd::units::bytes>
{
return kstd::units::bytes{};
}
- auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes) -> kstd::result<kstd::units::bytes>
+ auto inode::write(std::span<std::byte const>, kstd::units::bytes) -> kstd::result<kstd::units::bytes>
{
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 <kstd/units.hpp>
#include <kstd/vector.hpp>
+#include <cstddef>
+#include <span>
+
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<std::byte> buffer, kstd::units::bytes offset) const
-> kstd::result<kstd::units::bytes> 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<std::byte const> buffer, kstd::units::bytes offset)
-> kstd::result<kstd::units::bytes> 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 <catch2/catch_test_macros.hpp>
+#include <cstddef>
+
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<char> buffer(10);
- auto bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ kstd::vector<std::byte> 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<char> buffer(10, 'x');
- auto bytes_written = inode.write(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ kstd::vector<std::byte> 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 <kstd/vector.hpp>
#include <algorithm>
+#include <cstddef>
#include <cstdint>
#include <expected>
#include <optional>
@@ -395,8 +396,8 @@ namespace kernel::filesystem
return kstd::failure(vfs_errc::too_many_symbolic_link_levels);
}
- kstd::vector<uint8_t> buffer(constants::symlink_max_path_length);
- auto const bytes_read = next_dentry->get_inode()->read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ kstd::vector<std::byte> 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<kernel::filesystem::open_file_descriptor>(dentry.value());
kstd::vector<std::byte> 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<char *>(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<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(), kstd::units::bytes{sheep_buffer.size()});
+ auto bytes_read = sheep_1_ofd->read(sheep_buffer);
std::string_view buffer_as_str{reinterpret_cast<char *>(sheep_buffer.data()), bytes_read->value};
REQUIRE(buffer_as_str == "sheep_1");
kstd::vector<std::byte> 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<char *>(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<std::byte>(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 <algorithm>
#include <cstddef>
-#include <cstdint>
#include <cstring>
+#include <span>
#include <string.h>
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<kstd::units::bytes>
+ auto block_device::read_block(size_t block_index, std::span<std::byte> buffer) const
+ -> kstd::result<kstd::units::bytes>
{
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<uint8_t *>(buffer) + bytes_to_read, 0,
- static_cast<std::size_t>(block_size() - bytes_to_read));
+ kstd::libc::memset(buffer.data() + bytes_to_read, 0, static_cast<std::size_t>(block_size() - bytes_to_read));
}
return bytes_to_read;
}
- auto block_device::write_block(size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes>
+ auto block_device::write_block(size_t block_index, std::span<std::byte const> buffer)
+ -> kstd::result<kstd::units::bytes>
{
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<uint8_t const *>(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 <cstddef>
#include <cstdint>
+#include <span>
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<kstd::units::bytes> override;
- auto write_block(size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes> override;
+ auto read_block(size_t block_index, std::span<std::byte> buffer) const -> kstd::result<kstd::units::bytes> override;
+ auto write_block(size_t block_index, std::span<std::byte const> buffer)
+ -> kstd::result<kstd::units::bytes> 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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
+#include <span>
+
namespace kernel::tests::filesystem
{
- auto inode::read(void *, kstd::units::bytes, kstd::units::bytes size) const -> kstd::result<kstd::units::bytes>
+ auto inode::read(std::span<std::byte> buffer, kstd::units::bytes) const -> kstd::result<kstd::units::bytes>
{
- return size;
+ return kstd::units::bytes{buffer.size()};
}
- auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
+ auto inode::write(std::span<std::byte const> buffer, kstd::units::bytes) -> kstd::result<kstd::units::bytes>
{
- 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 <kstd/result.hpp>
#include <kstd/units.hpp>
+#include <cstddef>
+#include <span>
+
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<std::byte> buffer, kstd::units::bytes offset) const
-> kstd::result<kstd::units::bytes> override;
- auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ auto write(std::span<std::byte const> buffer, kstd::units::bytes offset)
-> kstd::result<kstd::units::bytes> override;
[[nodiscard]] auto is_regular() const -> bool override;