aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kapi/devices/device.cpp5
-rw-r--r--kernel/kapi/filesystem.cpp10
-rw-r--r--kernel/kapi/filesystem.tests.cpp16
-rw-r--r--kernel/kernel/devices/block_device.cpp32
-rw-r--r--kernel/kernel/devices/block_device.hpp56
-rw-r--r--kernel/kernel/devices/block_device.tests.cpp15
-rw-r--r--kernel/kernel/devices/block_device_utils.cpp91
-rw-r--r--kernel/kernel/devices/block_device_utils.hpp12
-rw-r--r--kernel/kernel/devices/block_device_utils.tests.cpp94
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.cpp30
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.hpp9
-rw-r--r--kernel/kernel/devices/storage/ram_disk/device.tests.cpp23
-rw-r--r--kernel/kernel/filesystem/devfs/inode.cpp11
-rw-r--r--kernel/kernel/filesystem/devfs/inode.hpp9
-rw-r--r--kernel/kernel/filesystem/devfs/inode.tests.cpp11
-rw-r--r--kernel/kernel/filesystem/device_inode.cpp14
-rw-r--r--kernel/kernel/filesystem/device_inode.hpp9
-rw-r--r--kernel/kernel/filesystem/device_inode.tests.cpp21
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.cpp112
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.hpp19
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.tests.cpp36
-rw-r--r--kernel/kernel/filesystem/ext2/inode.cpp35
-rw-r--r--kernel/kernel/filesystem/ext2/inode.hpp11
-rw-r--r--kernel/kernel/filesystem/ext2/inode.tests.cpp181
-rw-r--r--kernel/kernel/filesystem/inode.hpp9
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.cpp7
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.hpp11
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.tests.cpp81
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.cpp11
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.hpp9
-rw-r--r--kernel/kernel/filesystem/rootfs/inode.tests.cpp11
-rw-r--r--kernel/kernel/filesystem/vfs.cpp8
-rw-r--r--kernel/kernel/filesystem/vfs.tests.cpp12
-rw-r--r--kernel/kernel/main.cpp10
-rw-r--r--kernel/kernel/test_support/devices/block_device.cpp40
-rw-r--r--kernel/kernel/test_support/devices/block_device.hpp11
-rw-r--r--kernel/kernel/test_support/filesystem/ext2.cpp28
-rw-r--r--kernel/kernel/test_support/filesystem/ext2.hpp9
-rw-r--r--kernel/kernel/test_support/filesystem/inode.cpp7
-rw-r--r--kernel/kernel/test_support/filesystem/inode.hpp9
40 files changed, 616 insertions, 519 deletions
diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp
index d8cae29c..6ac92e79 100644
--- a/kernel/kapi/devices/device.cpp
+++ b/kernel/kapi/devices/device.cpp
@@ -31,11 +31,6 @@ namespace kapi::devices
return m_name;
}
- [[nodiscard]] auto device::is_block_device() const -> bool
- {
- return false;
- }
-
auto device::set_parent(kstd::observer_ptr<bus> parent) -> void
{
m_parent = parent;
diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp
index 982d5df0..b2f94747 100644
--- a/kernel/kapi/filesystem.cpp
+++ b/kernel/kapi/filesystem.cpp
@@ -7,6 +7,7 @@
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
+#include <kstd/units.hpp>
#include <cstddef>
#include <expected>
@@ -42,17 +43,18 @@ namespace kapi::filesystem
.and_then([=]() { return kernel::filesystem::open_file_table::get().remove_file(file_descriptor); });
}
- auto read(size_t file_descriptor, std::span<std::byte> buffer) -> std::expected<std::size_t, kstd::error_code>
+ 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(), buffer.size());
+ return descriptor->read(buffer.data(), kstd::units::bytes{buffer.size()});
});
}
- auto write(size_t file_descriptor, std::span<std::byte const> buffer) -> std::expected<std::size_t, kstd::error_code>
+ auto write(size_t file_descriptor, std::span<std::byte const> 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->write(buffer.data(), buffer.size());
+ return descriptor->write(buffer.data(), kstd::units::bytes{buffer.size()});
});
}
diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp
index ffd8d7f6..90609a6d 100644
--- a/kernel/kapi/filesystem.tests.cpp
+++ b/kernel/kapi/filesystem.tests.cpp
@@ -13,6 +13,8 @@
#include <string_view>
#include <vector>
+using namespace kstd::units_literals;
+
// NOLINTBEGIN (readability-magic-numbers)
SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kapi filesystem with real images",
@@ -36,7 +38,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
auto bytes_read = kapi::filesystem::read(fd, buffer);
auto buffer_as_str = bytes_read.transform(
- [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length}; });
+ [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length.value}; });
REQUIRE(buffer_as_str == "info_1");
@@ -51,7 +53,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
auto write_buffer = std::vector<std::byte>{std::byte{'H'}, std::byte{'e'}};
auto const bytes_written = kapi::filesystem::write(*write_fd, write_buffer);
- REQUIRE(bytes_written == 2);
+ REQUIRE(bytes_written == 2_B);
auto read_fd = kapi::filesystem::open("/information/info_1.txt");
REQUIRE(read_fd);
@@ -59,7 +61,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
auto read_buffer = std::vector<std::byte>(6);
auto const bytes_read = kapi::filesystem::read(*read_fd, read_buffer);
auto buffer_as_str = bytes_read.transform(
- [&](auto length) { return std::string_view{std::bit_cast<char *>(read_buffer.data()), length}; });
+ [&](auto length) { return std::string_view{std::bit_cast<char *>(read_buffer.data()), length.value}; });
REQUIRE(buffer_as_str == "Hefo_1");
@@ -74,7 +76,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
auto buffer = std::vector<std::byte>(6);
auto bytes_read = kapi::filesystem::read(fd, buffer);
auto buffer_as_str = bytes_read.transform(
- [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length}; });
+ [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length.value}; });
REQUIRE(buffer_as_str == "info_1");
@@ -88,7 +90,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
auto buffer = std::vector<std::byte>(6);
auto bytes_read = kapi::filesystem::read(fd, buffer);
auto buffer_as_str = bytes_read.transform(
- [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length}; });
+ [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length.value}; });
REQUIRE(buffer_as_str == "info_1");
@@ -104,7 +106,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
auto buffer = std::vector<std::byte>(7);
auto bytes_read = kapi::filesystem::read(fd, buffer);
auto buffer_as_str = bytes_read.transform(
- [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length}; });
+ [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length.value}; });
REQUIRE(buffer_as_str == "sheep_1");
@@ -120,7 +122,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap
auto buffer = std::vector<std::byte>(8);
auto bytes_read = kapi::filesystem::read(fd, buffer);
auto buffer_as_str = bytes_read.transform(
- [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length}; });
+ [&](auto length) { return std::string_view{std::bit_cast<char *>(buffer.data()), length.value}; });
REQUIRE(buffer_as_str == "monkey_1");
diff --git a/kernel/kernel/devices/block_device.cpp b/kernel/kernel/devices/block_device.cpp
index a3531121..4d85a520 100644
--- a/kernel/kernel/devices/block_device.cpp
+++ b/kernel/kernel/devices/block_device.cpp
@@ -1,19 +1,23 @@
#include <kernel/devices/block_device.hpp>
+#include <kapi/devices.hpp>
#include <kapi/devices/device.hpp>
#include <kapi/system.hpp>
#include <kstd/string.hpp>
+#include <kstd/units.hpp>
#include <cstddef>
+using namespace kstd::units_literals;
+
namespace kernel::devices
{
- block_device::block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size)
+ block_device::block_device(size_t major, size_t minor, kstd::string const & name, kstd::units::bytes block_size)
: kapi::devices::device(major, minor, name)
, m_block_size(block_size)
{
- if (m_block_size == 0)
+ if (m_block_size == 0_B)
{
kapi::system::panic("[DEVICES] block_device constructed with zero block size.");
}
@@ -21,22 +25,32 @@ namespace kernel::devices
auto block_device::calculate_transfer(size_t block_index) const -> transfer_info
{
- size_t const offset = block_index * m_block_size;
- size_t const limit = size();
+ auto const offset = block_index * m_block_size;
+ auto const limit = size();
- size_t const available = (offset < limit) ? (limit - offset) : 0;
- size_t const to_transfer = (available < m_block_size) ? available : m_block_size;
+ auto const available = (offset < limit) ? (limit - offset) : 0_B;
+ auto const to_transfer = (available < m_block_size) ? available : m_block_size;
return {offset, to_transfer, m_block_size - to_transfer};
}
- auto block_device::block_size() const -> size_t
+ auto block_device::block_size() const -> kstd::units::bytes
{
- return m_block_size;
+ return kstd::units::bytes{m_block_size};
}
- auto block_device::capacity() const -> size_t
+ auto block_device::capacity() const -> kstd::units::bytes
{
return size();
}
+
+ auto block_device::query_interface(kapi::devices::interface interface) -> void *
+ {
+ if (interface == kapi::devices::block_device::id)
+ {
+ return static_cast<kapi::devices::block_device *>(this);
+ }
+
+ return kapi::devices::device::query_interface(interface);
+ }
} // namespace kernel::devices \ No newline at end of file
diff --git a/kernel/kernel/devices/block_device.hpp b/kernel/kernel/devices/block_device.hpp
index 31599502..2b3b844c 100644
--- a/kernel/kernel/devices/block_device.hpp
+++ b/kernel/kernel/devices/block_device.hpp
@@ -1,9 +1,11 @@
#ifndef TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP
#define TEACH_OS_KERNEL_DEVICES_BLOCK_DEVICE_HPP
-#include <kapi/devices/device.hpp>
+#include <kapi/devices.hpp>
+#include <kstd/result.hpp>
#include <kstd/string.hpp>
+#include <kstd/units.hpp>
#include <cstddef>
@@ -12,7 +14,7 @@ namespace kernel::devices
/**
* @brief Base interface for block-addressable devices.
*/
- struct block_device : kapi::devices::device
+ struct block_device : kapi::devices::device, kapi::devices::block_device
{
/**
* @brief Create a block device descriptor.
@@ -21,50 +23,19 @@ namespace kernel::devices
* @param name Device name.
* @param block_size Size of one logical block in bytes.
*/
- block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size);
-
- /**
- * @brief Read data from the block at @p block_index into @p buffer.
- * @param block_index Zero-based block index.
- * @param buffer Destination buffer.
- * @warning Panics if @p buffer is null.
- * @note Reads up to one logical block (see constructor @p block_size). Implementations may perform a partial
- * transfer for the final block when fewer than @p block_size bytes remain.
- */
- virtual auto read_block(size_t block_index, void * buffer) const -> void = 0;
-
- /**
- * @brief Write data to the block at @p block_index.
- * @param block_index Zero-based block index.
- * @param buffer Source buffer, must not be null.
- * @warning Panics if @p buffer is null.
- * @note Writes up to one logical block (see constructor @p block_size).
- * Implementations may perform a partial transfer for the final block when
- * fewer than @p block_size bytes remain.
- */
- virtual auto write_block(size_t block_index, void const * buffer) -> void = 0;
+ block_device(size_t major, size_t minor, kstd::string const & name, kstd::units::bytes block_size);
/**
* @brief Return logical block size in bytes.
* @return One logical block size in bytes.
*/
- [[nodiscard]] auto block_size() const -> size_t;
+ [[nodiscard]] auto block_size() const -> kstd::units::bytes override;
/**
* @brief Return device capacity in bytes.
* @return Total number of addressable bytes.
*/
- [[nodiscard]] auto capacity() const -> size_t;
-
- /**
- * @brief Override to identify block devices.
- * @return true if this device is a block device, false otherwise.
- */
-
- [[nodiscard]] auto is_block_device() const -> bool override
- {
- return true;
- }
+ [[nodiscard]] auto capacity() const -> kstd::units::bytes override;
protected:
/**
@@ -72,16 +43,16 @@ namespace kernel::devices
*/
struct transfer_info
{
- size_t offset;
- size_t to_transfer;
- size_t remainder;
+ kstd::units::bytes offset;
+ kstd::units::bytes to_transfer;
+ kstd::units::bytes remainder;
};
/**
* @brief Return total device size in bytes.
* @return Total number of addressable bytes.
*/
- [[nodiscard]] virtual auto size() const -> size_t = 0;
+ [[nodiscard]] virtual auto size() const -> kstd::units::bytes = 0;
/**
* @brief Compute transfer information for @p block_index.
@@ -90,7 +61,10 @@ namespace kernel::devices
*/
[[nodiscard]] auto calculate_transfer(size_t block_index) const -> transfer_info;
- size_t m_block_size;
+ [[nodiscard]] auto query_interface(kapi::devices::interface interface) -> void * override;
+
+ private:
+ kstd::units::bytes m_block_size;
};
} // namespace kernel::devices
diff --git a/kernel/kernel/devices/block_device.tests.cpp b/kernel/kernel/devices/block_device.tests.cpp
index 98722638..23af74ef 100644
--- a/kernel/kernel/devices/block_device.tests.cpp
+++ b/kernel/kernel/devices/block_device.tests.cpp
@@ -5,20 +5,21 @@
#include <kstd/memory.hpp>
#include <kstd/print.hpp>
#include <kstd/string.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
-#include <cstddef>
+using namespace kstd::units_literals;
SCENARIO("Block device construction", "[devices][block_device]")
{
GIVEN("parameters for a block device")
{
- size_t major = 1;
- size_t minor = 0;
- kstd::string name = "test_block_device";
- size_t block_size = 512;
+ auto major = 1uz;
+ auto minor = 0uz;
+ auto name = "test_block_device";
+ auto block_size = 512_B;
WHEN("constructing a block device")
{
@@ -31,7 +32,7 @@ SCENARIO("Block device construction", "[devices][block_device]")
REQUIRE(device->minor() == minor);
REQUIRE(device->name() == name);
REQUIRE(device->block_size() == block_size);
- REQUIRE(device->capacity() == 3 * 512);
+ REQUIRE(device->capacity() == 3 * 512_B);
}
}
@@ -39,7 +40,7 @@ SCENARIO("Block device construction", "[devices][block_device]")
{
THEN("the constructor panics")
{
- REQUIRE_THROWS_AS((kernel::tests::devices::block_device(major, minor, name, 0)), kernel::tests::cpu::halt);
+ REQUIRE_THROWS_AS((kernel::tests::devices::block_device(major, minor, name, 0_B)), kernel::tests::cpu::halt);
}
}
}
diff --git a/kernel/kernel/devices/block_device_utils.cpp b/kernel/kernel/devices/block_device_utils.cpp
index 68a0a306..1fefd034 100644
--- a/kernel/kernel/devices/block_device_utils.cpp
+++ b/kernel/kernel/devices/block_device_utils.cpp
@@ -1,63 +1,72 @@
#include <kernel/devices/block_device_utils.hpp>
-#include <kernel/devices/block_device.hpp>
-
+#include <kapi/devices.hpp>
#include <kapi/devices/device.hpp>
#include <kapi/system.hpp>
#include <kstd/cstring.hpp>
#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <algorithm>
#include <cstddef>
+using namespace kstd::units_literals;
+
namespace kernel::devices::block_device_utils
{
- using block_op = void (*)(size_t idx, size_t off, size_t len, size_t done, devices::block_device * device,
- std::byte * scratch, void * buffer);
+ using block_op = kstd::result<kstd::units::bytes> (*)(size_t idx, kstd::units::bytes off, kstd::units::bytes len,
+ kstd::units::bytes done, kapi::devices::block_device * device,
+ std::byte * scratch, void * buffer);
- auto process_blocks(kstd::shared_ptr<kapi::devices::device> const & device, size_t offset, size_t size, void * buffer,
- block_op op) -> size_t
+ auto process_blocks(kstd::shared_ptr<kapi::devices::device> const & device, kstd::units::bytes offset,
+ kstd::units::bytes size, void * buffer, block_op op) -> kstd::result<kstd::units::bytes>
{
if (buffer == nullptr)
{
kapi::system::panic("[FILESYSTEM] device_file::process_blocks called with null buffer.");
}
- if (size == 0)
+ if (size == 0_B)
{
- return 0;
+ return 0_B;
}
- if (!device->is_block_device())
+ if (!device->is_a<kapi::devices::block_device>())
{
kapi::system::panic("[FILESYSTEM] device_file: expected block_device.");
}
- auto * block_dev = static_cast<devices::block_device *>(device.get());
+ auto * block_dev = device->as<kapi::devices::block_device>();
- size_t const block_size = block_dev->block_size();
- size_t const capacity = block_dev->capacity();
+ auto const block_size = block_dev->block_size();
+ auto const capacity = block_dev->capacity();
if (offset >= capacity)
{
- return 0;
+ return 0_B;
}
- size_t const total_to_process = std::min(size, capacity - offset);
+ auto const total_to_process = std::min(size, capacity - offset);
- kstd::vector<std::byte> scratch_buffer{block_size};
- auto processed = 0uz;
+ kstd::vector<std::byte> scratch_buffer{block_size.value};
+ auto processed = 0_B;
while (processed < total_to_process)
{
- size_t const absolute_offset = offset + processed;
- size_t const block_index = absolute_offset / block_size;
- size_t const in_block_offset = absolute_offset % block_size;
- size_t const chunk_size = std::min(total_to_process - processed, block_size - in_block_offset);
-
- op(block_index, in_block_offset, chunk_size, processed, block_dev, scratch_buffer.data(), buffer);
+ auto const absolute_offset = offset + processed;
+ auto const block_index = absolute_offset / block_size;
+ 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, block_dev, scratch_buffer.data(), buffer);
+ !result)
+ {
+ return result;
+ }
processed += chunk_size;
}
@@ -65,40 +74,46 @@ namespace kernel::devices::block_device_utils
return processed;
}
- auto read(kstd::shared_ptr<kapi::devices::device> const & device, void * buffer, size_t offset, size_t size) -> size_t
+ auto read(kstd::shared_ptr<kapi::devices::device> const & device, void * buffer, kstd::units::bytes offset,
+ kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
{
return process_blocks(device, offset, size, buffer,
- [](size_t idx, size_t off, size_t len, size_t done, devices::block_device * device,
- std::byte * scratch, void * buffer) {
+ [](size_t idx, kstd::units::bytes off, kstd::units::bytes len, kstd::units::bytes done,
+ kapi::devices::block_device * device, std::byte * scratch, void * buffer) {
auto * out = static_cast<std::byte *>(buffer);
- if (off == 0 && len == device->block_size())
+ if (off == 0_B && len == device->block_size())
{
- device->read_block(idx, out + done);
+ return device->read_block(idx, out + done);
}
else
{
- device->read_block(idx, scratch);
- kstd::libc::memcpy(out + done, scratch + off, len);
+ auto result = device->read_block(idx, scratch);
+ if (result)
+ {
+ kstd::libc::memcpy(out + done, scratch + off, len.value);
+ }
+ return result;
}
});
}
- auto write(kstd::shared_ptr<kapi::devices::device> const & device, void const * buffer, size_t offset, size_t size)
- -> size_t
+ auto write(kstd::shared_ptr<kapi::devices::device> const & device, void const * buffer, kstd::units::bytes offset,
+ kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
{
return process_blocks(device, offset, size, const_cast<void *>(buffer),
- [](size_t idx, size_t off, size_t len, size_t done, devices::block_device * device,
- std::byte * scratch, void * buffer) {
+ [](size_t idx, kstd::units::bytes off, kstd::units::bytes len, kstd::units::bytes done,
+ kapi::devices::block_device * device, std::byte * scratch, void * buffer) {
auto const * in = static_cast<std::byte const *>(buffer);
- if (off == 0 && len == device->block_size())
+ if (off == 0_B && len == device->block_size())
{
- device->write_block(idx, in + done);
+ return device->write_block(idx, in + done);
}
else
{
- device->read_block(idx, scratch);
- kstd::libc::memcpy(scratch + off, in + done, len);
- device->write_block(idx, scratch);
+ return device->read_block(idx, scratch).and_then([&](auto) {
+ kstd::libc::memcpy(scratch + off, in + done, 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 88e23347..6b626180 100644
--- a/kernel/kernel/devices/block_device_utils.hpp
+++ b/kernel/kernel/devices/block_device_utils.hpp
@@ -4,8 +4,8 @@
#include <kapi/devices/device.hpp>
#include <kstd/memory.hpp>
-
-#include <cstddef>
+#include <kstd/result.hpp>
+#include <kstd/units.hpp>
namespace kernel::devices::block_device_utils
{
@@ -25,8 +25,8 @@ namespace kernel::devices::block_device_utils
@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(kstd::shared_ptr<kapi::devices::device> const & device, void * buffer, size_t offset, size_t size)
- -> size_t;
+ auto read(kstd::shared_ptr<kapi::devices::device> const & 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.
@@ -37,8 +37,8 @@ namespace kernel::devices::block_device_utils
@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(kstd::shared_ptr<kapi::devices::device> const & device, void const * buffer, size_t offset, size_t size)
- -> size_t;
+ auto write(kstd::shared_ptr<kapi::devices::device> const & device, void const * buffer, kstd::units::bytes offset,
+ kstd::units::bytes size) -> 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 c8c4acfb..40c52948 100644
--- a/kernel/kernel/devices/block_device_utils.tests.cpp
+++ b/kernel/kernel/devices/block_device_utils.tests.cpp
@@ -6,6 +6,7 @@
#include <kstd/memory.hpp>
#include <kstd/print.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -13,28 +14,31 @@
#include <cstddef>
#include <cstdint>
+using namespace kstd::units_literals;
+
SCENARIO("reading from a block device with block_device_utils", "[devices][block_device_utils]")
{
GIVEN("a block device with known data")
{
- auto const block_size = 512;
+ auto const block_size = 512_B;
auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "test_block_device", block_size);
- kstd::vector<uint8_t> block_data(block_size);
+ kstd::vector<uint8_t> block_data(block_size.value);
for (size_t i = 0; i < block_data.size(); ++i)
{
block_data[i] = static_cast<uint8_t>(i % 256);
}
- device->write_block(0, block_data.data());
- device->write_block(1, block_data.data());
+ CHECK(device->write_block(0, block_data.data()));
+ CHECK(device->write_block(1, block_data.data()));
WHEN("reading from the block device using block_device_utils")
{
- kstd::vector<uint8_t> read_buffer(block_size);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 0, read_buffer.size());
+ 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()});
THEN("the correct number of bytes is read")
{
- REQUIRE(bytes_read == read_buffer.size());
+ REQUIRE(bytes_read == kstd::units::bytes{read_buffer.size()});
}
THEN("the data read matches the data written to the block device")
@@ -46,16 +50,17 @@ 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, read_buffer.size());
+ auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 256_B,
+ kstd::units::bytes{read_buffer.size()});
THEN("the correct number of bytes is read")
{
- REQUIRE(bytes_read == 1.5 * block_size);
+ REQUIRE(bytes_read == kstd::units::bytes{static_cast<std::size_t>(1.5 * block_size.value)});
}
THEN("the data read matches the expected data across block boundaries")
{
- for (size_t i = 0; i < bytes_read; ++i)
+ for (size_t i = 0; i < bytes_read.value().value; ++i)
{
uint8_t expected_value = static_cast<uint8_t>((256 + i) % 256);
REQUIRE(read_buffer[i] == expected_value);
@@ -65,23 +70,24 @@ 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);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 1024, read_buffer.size());
+ 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()});
THEN("no bytes are read")
{
- REQUIRE(bytes_read == 0);
+ REQUIRE(bytes_read == 0_B);
}
}
WHEN("reading nothing")
{
- kstd::vector<uint8_t> read_buffer(block_size);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 0, 0);
+ 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);
THEN("no bytes are read")
{
- REQUIRE(bytes_read == 0);
+ REQUIRE(bytes_read == 0_B);
}
}
@@ -89,7 +95,8 @@ SCENARIO("reading from a block device with block_device_utils", "[devices][block
{
THEN("the system panics")
{
- REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, nullptr, 0, 512), kernel::tests::cpu::halt);
+ REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, nullptr, 0_B, 512_B),
+ kernel::tests::cpu::halt);
}
}
}
@@ -99,56 +106,56 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_
{
GIVEN("a block device")
{
- auto const block_size = 512;
+ auto const block_size = 512_B;
auto device =
kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "test_block_device", block_size, 2 * block_size);
WHEN("writing to the block device using block_device_utils")
{
- kstd::vector<uint8_t> write_buffer(block_size);
+ kstd::vector<uint8_t> write_buffer(block_size.value);
for (size_t i = 0; i < write_buffer.size(); ++i)
{
write_buffer[i] = static_cast<uint8_t>(i % 256);
}
- auto bytes_written =
- kernel::devices::block_device_utils::write(device, write_buffer.data(), 0, write_buffer.size());
+ auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 0_B,
+ kstd::units::bytes{write_buffer.size()});
THEN("the correct number of bytes is written")
{
- REQUIRE(bytes_written == write_buffer.size());
+ REQUIRE(bytes_written == kstd::units::bytes{write_buffer.size()});
}
THEN("the data written matches the data read back from the block device")
{
- kstd::vector<uint8_t> read_buffer(block_size);
- device->read_block(0, read_buffer.data());
+ kstd::vector<uint8_t> read_buffer(block_size.value);
+ CHECK(device->read_block(0, read_buffer.data()));
REQUIRE(read_buffer == write_buffer);
}
}
WHEN("writing over block boundaries")
{
- kstd::vector<uint8_t> write_buffer(2 * block_size);
+ kstd::vector<uint8_t> 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);
}
- auto bytes_written =
- kernel::devices::block_device_utils::write(device, write_buffer.data(), 256, write_buffer.size());
+ auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 256_B,
+ kstd::units::bytes{write_buffer.size()});
THEN("the correct number of bytes is written")
{
- REQUIRE(bytes_written == 1.5 * block_size);
+ REQUIRE(bytes_written == kstd::units::bytes{static_cast<std::size_t>(1.5 * block_size.value)});
}
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);
- auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 256, 2 * block_size);
+ 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);
- for (size_t i = 0; i < bytes_read; ++i)
+ for (size_t i = 0; i < bytes_read.value().value; ++i)
{
REQUIRE(read_buffer[i] == write_buffer[i]);
}
@@ -157,24 +164,24 @@ 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);
- auto bytes_written =
- kernel::devices::block_device_utils::write(device, write_buffer.data(), 1024, write_buffer.size());
+ 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()});
THEN("no bytes are written")
{
- REQUIRE(bytes_written == 0);
+ REQUIRE(bytes_written == 0_B);
}
}
WHEN("writing nothing")
{
- kstd::vector<uint8_t> write_buffer(block_size);
- auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 0, 0);
+ 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);
THEN("no bytes are written")
{
- REQUIRE(bytes_written == 0);
+ REQUIRE(bytes_written == 0_B);
}
}
@@ -182,7 +189,7 @@ SCENARIO("writing to a block device using block_device_utils", "[devices][block_
{
THEN("the system panics")
{
- REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(device, nullptr, 0, block_size),
+ REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(device, nullptr, 0_B, block_size),
kernel::tests::cpu::halt);
}
}
@@ -200,7 +207,8 @@ SCENARIO("block_device_utils with a non-block device", "[devices][block_device_u
kstd::vector<uint8_t> read_buffer(512);
THEN("the system panics")
{
- REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, read_buffer.data(), 0, read_buffer.size()),
+ REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, read_buffer.data(), 0_B,
+ kstd::units::bytes{read_buffer.size()}),
kernel::tests::cpu::halt);
}
}
@@ -210,9 +218,9 @@ SCENARIO("block_device_utils with a non-block device", "[devices][block_device_u
kstd::vector<uint8_t> write_buffer(512);
THEN("the system panics")
{
- REQUIRE_THROWS_AS(
- kernel::devices::block_device_utils::write(device, write_buffer.data(), 0, write_buffer.size()),
- kernel::tests::cpu::halt);
+ REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(device, write_buffer.data(), 0_B,
+ kstd::units::bytes{write_buffer.size()}),
+ kernel::tests::cpu::halt);
}
}
}
diff --git a/kernel/kernel/devices/storage/ram_disk/device.cpp b/kernel/kernel/devices/storage/ram_disk/device.cpp
index eff6114d..1e2f2597 100644
--- a/kernel/kernel/devices/storage/ram_disk/device.cpp
+++ b/kernel/kernel/devices/storage/ram_disk/device.cpp
@@ -7,14 +7,18 @@
#include <kstd/cstring.hpp>
#include <kstd/format.hpp>
+#include <kstd/result.hpp>
+#include <kstd/units.hpp>
#include <cstddef>
+using namespace kstd::units_literals;
+
namespace kernel::devices::storage::ram_disk
{
namespace
{
- constexpr size_t ram_disk_block_size = 512uz;
+ constexpr auto ram_disk_block_size = 512_B;
} // namespace
device::device(kapi::boot_modules::boot_module const & module, size_t major, size_t minor, std::size_t device_index)
@@ -27,7 +31,7 @@ namespace kernel::devices::storage::ram_disk
return m_boot_module.start_address.raw() != 0 && m_boot_module.size > 0;
}
- auto device::read_block(size_t block_index, void * buffer) const -> void
+ auto device::read_block(size_t block_index, void * buffer) const -> kstd::result<kstd::units::bytes>
{
if (buffer == nullptr)
{
@@ -36,19 +40,21 @@ namespace kernel::devices::storage::ram_disk
auto const info = calculate_transfer(block_index);
- if (info.to_transfer > 0)
+ if (info.to_transfer > 0_B)
{
auto const src = static_cast<std::byte const *>(m_boot_module.start_address) + info.offset;
- kstd::libc::memcpy(buffer, src, info.to_transfer);
+ kstd::libc::memcpy(buffer, src, info.to_transfer.value);
}
- if (info.remainder > 0)
+ if (info.remainder > 0_B)
{
- kstd::libc::memset(static_cast<std::byte *>(buffer) + info.to_transfer, 0, info.remainder);
+ kstd::libc::memset(static_cast<std::byte *>(buffer) + info.to_transfer, 0, info.remainder.value);
}
+
+ return info.to_transfer;
}
- auto device::write_block(size_t block_index, void const * buffer) -> void
+ auto device::write_block(size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes>
{
if (buffer == nullptr)
{
@@ -57,15 +63,17 @@ namespace kernel::devices::storage::ram_disk
auto const info = calculate_transfer(block_index);
- if (info.to_transfer > 0)
+ if (info.to_transfer > 0_B)
{
auto const dest = static_cast<std::byte *>(m_boot_module.start_address) + info.offset;
- kstd::libc::memcpy(dest, buffer, info.to_transfer);
+ kstd::libc::memcpy(dest, buffer, info.to_transfer.value);
}
+
+ return info.to_transfer;
}
- auto device::size() const -> size_t
+ auto device::size() const -> kstd::units::bytes
{
- return m_boot_module.size;
+ return kstd::units::bytes{m_boot_module.size};
}
} // namespace kernel::devices::storage::ram_disk \ No newline at end of file
diff --git a/kernel/kernel/devices/storage/ram_disk/device.hpp b/kernel/kernel/devices/storage/ram_disk/device.hpp
index cd62a1ec..f4c83187 100644
--- a/kernel/kernel/devices/storage/ram_disk/device.hpp
+++ b/kernel/kernel/devices/storage/ram_disk/device.hpp
@@ -5,6 +5,9 @@
#include <kapi/boot_module/boot_module.hpp>
+#include <kstd/result.hpp>
+#include <kstd/units.hpp>
+
#include <cstddef>
namespace kernel::devices::storage::ram_disk
@@ -35,7 +38,7 @@ namespace kernel::devices::storage::ram_disk
* @note If the request reaches the module end, only available bytes are copied and the rest of the
* logical block is filled with zeros.
*/
- auto read_block(size_t block_index, void * buffer) const -> void override;
+ auto read_block(size_t block_index, void * buffer) const -> kstd::result<kstd::units::bytes> override;
/**
* @brief Write one logical block from @p buffer.
@@ -43,13 +46,13 @@ namespace kernel::devices::storage::ram_disk
* @param buffer Source buffer, must not be null.
* @note If the request reaches the module end, only the bytes in the module range are written.
*/
- auto write_block(size_t block_index, void const * buffer) -> void override;
+ auto write_block(size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes> override;
private:
/**
* @brief Return module size in bytes.
*/
- [[nodiscard]] auto size() const -> size_t override;
+ [[nodiscard]] auto size() const -> kstd::units::bytes override;
kapi::boot_modules::boot_module m_boot_module{};
};
diff --git a/kernel/kernel/devices/storage/ram_disk/device.tests.cpp b/kernel/kernel/devices/storage/ram_disk/device.tests.cpp
index 988c2d38..a10dc84e 100644
--- a/kernel/kernel/devices/storage/ram_disk/device.tests.cpp
+++ b/kernel/kernel/devices/storage/ram_disk/device.tests.cpp
@@ -61,23 +61,24 @@ SCENARIO("RAM Disk Device Read and Write", "[ram_disk_device]")
WHEN("reading a full block from the device")
{
- auto buffer = std::vector<std::byte>(device.block_size());
- device.read_block(0, buffer.data());
+ auto buffer = std::vector<std::byte>(device.block_size().value);
+ CHECK(device.read_block(0, buffer.data()));
THEN("the buffer is filled with the module data")
{
- REQUIRE_THAT(buffer, Catch::Matchers::RangeEquals(std::views::take(storage, device.block_size())));
+ REQUIRE_THAT(buffer, Catch::Matchers::RangeEquals(std::views::take(storage, device.block_size().value)));
}
}
WHEN("reading from a block index beyond the module size")
{
- auto buffer = std::vector<std::byte>(device.block_size());
- device.read_block(10, buffer.data());
+ auto buffer = std::vector<std::byte>(device.block_size().value);
+ CHECK(device.read_block(10, buffer.data()));
THEN("the buffer is filled with zeros")
{
- REQUIRE_THAT(buffer, Catch::Matchers::RangeEquals(std::vector<std::byte>(device.block_size(), std::byte{0})));
+ REQUIRE_THAT(buffer,
+ Catch::Matchers::RangeEquals(std::vector<std::byte>(device.block_size().value, std::byte{0})));
}
}
@@ -88,19 +89,19 @@ SCENARIO("RAM Disk Device Read and Write", "[ram_disk_device]")
WHEN("writing to a full block")
{
- auto buffer = std::vector<std::byte>(device.block_size(), std::byte{0x01});
- device.write_block(0, buffer.data());
+ auto buffer = std::vector<std::byte>(device.block_size().value, std::byte{0x01});
+ CHECK(device.write_block(0, buffer.data()));
THEN("the module data is updated")
{
- REQUIRE_THAT(std::views::take(storage, device.block_size()), Catch::Matchers::RangeEquals(buffer));
+ REQUIRE_THAT(std::views::take(storage, device.block_size().value), Catch::Matchers::RangeEquals(buffer));
}
}
WHEN("writing to a block index beyond the module size")
{
- auto buffer = std::vector<std::byte>(device.block_size(), std::byte{0x01});
- device.write_block(10, buffer.data());
+ auto buffer = std::vector<std::byte>(device.block_size().value, std::byte{0x01});
+ CHECK(device.write_block(10, buffer.data()));
THEN("the module data is not updated")
{
diff --git a/kernel/kernel/filesystem/devfs/inode.cpp b/kernel/kernel/filesystem/devfs/inode.cpp
index 2e4ee7de..8d0a9b14 100644
--- a/kernel/kernel/filesystem/devfs/inode.cpp
+++ b/kernel/kernel/filesystem/devfs/inode.cpp
@@ -1,19 +1,20 @@
#include <kernel/filesystem/devfs/inode.hpp>
#include <kstd/result.hpp>
+#include <kstd/units.hpp>
-#include <cstddef>
+using namespace kstd::units_literals;
namespace kernel::filesystem::devfs
{
- auto inode::read(void *, size_t, size_t) const -> kstd::result<size_t>
+ auto inode::read(void *, kstd::units::bytes, kstd::units::bytes) const -> kstd::result<kstd::units::bytes>
{
- return 0;
+ return 0_B;
}
- auto inode::write(void const *, size_t, size_t) -> kstd::result<size_t>
+ auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes) -> kstd::result<kstd::units::bytes>
{
- return 0;
+ return 0_B;
}
auto inode::is_directory() const -> bool
diff --git a/kernel/kernel/filesystem/devfs/inode.hpp b/kernel/kernel/filesystem/devfs/inode.hpp
index 3472079f..1e6d4e05 100644
--- a/kernel/kernel/filesystem/devfs/inode.hpp
+++ b/kernel/kernel/filesystem/devfs/inode.hpp
@@ -4,8 +4,7 @@
#include <kernel/filesystem/inode.hpp>
#include <kstd/result.hpp>
-
-#include <cstddef>
+#include <kstd/units.hpp>
namespace kernel::filesystem::devfs
{
@@ -22,7 +21,8 @@ namespace kernel::filesystem::devfs
@param size Number of bytes requested.
@return Number of bytes read (always 0 because this inode does not expose file data).
*/
- auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
+ auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
+ -> kstd::result<kstd::units::bytes> override;
/**
@brief Writes to the devfs directory inode.
@@ -31,7 +31,8 @@ namespace kernel::filesystem::devfs
@param size Number of bytes requested.
@return Number of bytes written (always 0 because writes are not supported for this inode).
*/
- auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
+ auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes> override;
/**
@brief Check if this inode represents a directory.
diff --git a/kernel/kernel/filesystem/devfs/inode.tests.cpp b/kernel/kernel/filesystem/devfs/inode.tests.cpp
index ecf9a79b..9445be7d 100644
--- a/kernel/kernel/filesystem/devfs/inode.tests.cpp
+++ b/kernel/kernel/filesystem/devfs/inode.tests.cpp
@@ -2,12 +2,15 @@
#include <kstd/memory.hpp>
#include <kstd/print.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
#include <cstdint>
+using namespace kstd::units_literals;
+
SCENARIO("Devfs inode creation", "[filesystem][devfs][inode]")
{
GIVEN("a devfs inode")
@@ -33,22 +36,22 @@ 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, buffer.size());
+ auto bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
THEN("no bytes are read")
{
- REQUIRE(bytes_read == 0);
+ REQUIRE(bytes_read == 0_B);
}
}
WHEN("attempting to write to the devfs inode")
{
kstd::vector<uint8_t> buffer(512);
- auto bytes_written = inode.write(buffer.data(), 0, buffer.size());
+ auto bytes_written = inode.write(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
THEN("no bytes are written")
{
- REQUIRE(bytes_written == 0);
+ REQUIRE(bytes_written == 0_B);
}
}
}
diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp
index 644e3df7..7019377b 100644
--- a/kernel/kernel/filesystem/device_inode.cpp
+++ b/kernel/kernel/filesystem/device_inode.cpp
@@ -2,13 +2,13 @@
#include <kernel/devices/block_device_utils.hpp>
+#include <kapi/devices.hpp>
#include <kapi/devices/device.hpp>
#include <kapi/system.hpp>
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
-
-#include <cstddef>
+#include <kstd/units.hpp>
namespace kernel::filesystem
{
@@ -21,9 +21,10 @@ namespace kernel::filesystem
}
}
- auto device_inode::read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t>
+ auto device_inode::read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
+ -> kstd::result<kstd::units::bytes>
{
- if (m_device->is_block_device())
+ if (m_device->is_a<kapi::devices::block_device>())
{
return devices::block_device_utils::read(m_device, buffer, offset, size);
}
@@ -33,9 +34,10 @@ namespace kernel::filesystem
}
}
- auto device_inode::write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t>
+ auto device_inode::write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes>
{
- if (m_device->is_block_device())
+ if (m_device->is_a<kapi::devices::block_device>())
{
return devices::block_device_utils::write(m_device, buffer, offset, size);
}
diff --git a/kernel/kernel/filesystem/device_inode.hpp b/kernel/kernel/filesystem/device_inode.hpp
index 5b22366a..23b9863d 100644
--- a/kernel/kernel/filesystem/device_inode.hpp
+++ b/kernel/kernel/filesystem/device_inode.hpp
@@ -7,8 +7,7 @@
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
-
-#include <cstddef>
+#include <kstd/units.hpp>
namespace kernel::filesystem
{
@@ -33,7 +32,8 @@ namespace kernel::filesystem
@param size The number of bytes to read.
@return The number of bytes read.
*/
- auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
+ auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
+ -> kstd::result<kstd::units::bytes> override;
/**
@brief Write data to the device inode (and in the background from the associated device) from a @p buffer, starting
@@ -43,7 +43,8 @@ namespace kernel::filesystem
@param size The number of bytes to write.
@return The number of bytes written.
*/
- auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
+ auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes> override;
/**
@brief Get the associated device.
diff --git a/kernel/kernel/filesystem/device_inode.tests.cpp b/kernel/kernel/filesystem/device_inode.tests.cpp
index d78d4a07..2a0b22db 100644
--- a/kernel/kernel/filesystem/device_inode.tests.cpp
+++ b/kernel/kernel/filesystem/device_inode.tests.cpp
@@ -6,6 +6,7 @@
#include <kstd/memory.hpp>
#include <kstd/print.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -13,11 +14,13 @@
#include <cstddef>
#include <cstdint>
+using namespace kstd::units_literals;
+
SCENARIO("Device inode construction", "[filesystem][device_inode]")
{
GIVEN("a block device")
{
- auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "test_block_device", 512, 3 * 512);
+ auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "test_block_device", 512_B, 3 * 512_B);
WHEN("constructing a device inode with the block device")
{
@@ -51,7 +54,7 @@ SCENARIO("Device inode read/write", "[filesystem][device_inode]")
{
GIVEN("a block device and a device inode for that device")
{
- auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "test_block_device", 512, 3 * 512);
+ auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "test_block_device", 512_B, 3 * 512_B);
auto inode = kernel::filesystem::device_inode{device};
WHEN("writing to the device inode")
@@ -62,19 +65,19 @@ SCENARIO("Device inode read/write", "[filesystem][device_inode]")
write_buffer[i] = static_cast<uint8_t>(i % 256);
}
- auto bytes_written = inode.write(write_buffer.data(), 256, write_buffer.size());
+ auto bytes_written = inode.write(write_buffer.data(), 256_B, kstd::units::bytes{write_buffer.size()});
THEN("the correct number of bytes is written")
{
- REQUIRE(bytes_written == 1024);
+ REQUIRE(bytes_written == 1024_B);
}
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, read_buffer.size());
+ auto bytes_read = inode.read(read_buffer.data(), 256_B, kstd::units::bytes{read_buffer.size()});
- REQUIRE(bytes_read == write_buffer.size());
+ REQUIRE(bytes_read.value().value == write_buffer.size());
REQUIRE(read_buffer == write_buffer);
}
}
@@ -93,7 +96,8 @@ SCENARIO("Device inode read/write with a non-block device", "[filesystem][device
kstd::vector<uint8_t> read_buffer(512);
THEN("the system panics")
{
- REQUIRE_THROWS_AS(inode.read(read_buffer.data(), 0, read_buffer.size()), kernel::tests::cpu::halt);
+ REQUIRE_THROWS_AS(inode.read(read_buffer.data(), 0_B, kstd::units::bytes{read_buffer.size()}),
+ kernel::tests::cpu::halt);
}
}
@@ -102,7 +106,8 @@ SCENARIO("Device inode read/write with a non-block device", "[filesystem][device
kstd::vector<uint8_t> write_buffer(512);
THEN("the system panics")
{
- REQUIRE_THROWS_AS(inode.write(write_buffer.data(), 0, write_buffer.size()), kernel::tests::cpu::halt);
+ REQUIRE_THROWS_AS(inode.write(write_buffer.data(), 0_B, kstd::units::bytes{write_buffer.size()}),
+ kernel::tests::cpu::halt);
}
}
}
diff --git a/kernel/kernel/filesystem/ext2/filesystem.cpp b/kernel/kernel/filesystem/ext2/filesystem.cpp
index 091b1399..89dac095 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.cpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.cpp
@@ -17,6 +17,7 @@
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <array>
@@ -26,6 +27,8 @@
#include <string_view>
#include <tuple>
+using namespace kstd::units_literals;
+
namespace kernel::filesystem::ext2
{
namespace
@@ -79,7 +82,8 @@ 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, sizeof(m_superblock));
+ if (auto read_result =
+ m_backing_inode->read(&m_superblock, constants::superblock_offset, kstd::object_size(m_superblock));
!read_result)
{
return kstd::failure(read_result.error());
@@ -97,7 +101,7 @@ namespace kernel::filesystem::ext2
if (auto read_result =
m_backing_inode->read(m_block_group_descriptors.data(), block_group_descriptor_table_offset(),
- num_block_groups * sizeof(block_group_descriptor));
+ num_block_groups * kstd::type_size<block_group_descriptor>);
!read_result)
{
return kstd::failure(read_result.error());
@@ -131,7 +135,7 @@ namespace kernel::filesystem::ext2
auto * ext2_parent = static_cast<inode *>(parent.get());
auto const & inode_data = ext2_parent->data();
- kstd::vector<uint8_t> buffer(block_size());
+ kstd::vector<uint8_t> buffer(block_size().value);
for (uint32_t i = 0; i < inode_block_count(inode_data); ++i)
{
@@ -147,7 +151,7 @@ namespace kernel::filesystem::ext2
}
auto const * entry = reinterpret_cast<linked_directory_entry const *>(buffer.data());
- auto bytes_read = 0uz;
+ auto bytes_read = 0_B;
while (bytes_read < block_size() && entry->inode != 0)
{
@@ -157,7 +161,7 @@ namespace kernel::filesystem::ext2
return read_inode(entry->inode);
}
- bytes_read += entry->rec_len;
+ bytes_read += kstd::units::bytes{entry->rec_len};
entry = reinterpret_cast<linked_directory_entry const *>(buffer.data() + bytes_read);
}
}
@@ -240,7 +244,7 @@ namespace kernel::filesystem::ext2
return kstd::failure(global_block.error());
}
- kstd::vector<uint8_t> buffer(block_size());
+ kstd::vector<uint8_t> buffer(block_size().value);
if (auto read_result = read_block(*global_block, buffer.data()); !read_result)
{
return kstd::failure(read_result.error());
@@ -248,27 +252,27 @@ namespace kernel::filesystem::ext2
// TODO handle "gaps" in directory entries (e.g., after deletions) in the current implementation, we only
// add new entries at the end of the last block, but we could also reuse space from deleted entries
- auto offset = 0uz;
+ auto offset = 0_B;
while (true)
{
auto const * entry = reinterpret_cast<linked_directory_entry const *>(buffer.data() + offset);
- if (offset + entry->rec_len >= block_size())
+ if (offset + kstd::units::bytes{entry->rec_len} >= block_size())
{
break;
}
- offset += entry->rec_len;
+ offset += kstd::units::bytes{entry->rec_len};
}
auto const file_type = map_inode_mode_to_file_type(mode);
auto const name_len = static_cast<uint8_t>(name.size());
- auto const needed_rec_len = static_cast<uint16_t>((8u + name_len + 3u) & ~3u);
+ auto const needed_rec_len = static_cast<kstd::units::bytes>((8u + name_len + 3u) & ~3u);
auto * last_entry = reinterpret_cast<linked_directory_entry *>(buffer.data() + offset);
- auto const last_entry_actual_len = static_cast<uint16_t>((8u + last_entry->name_len + 3u) & ~3u);
+ auto const last_entry_actual_len = static_cast<kstd::units::bytes>((8u + last_entry->name_len + 3u) & ~3u);
- if (last_entry->rec_len - last_entry_actual_len >= needed_rec_len)
+ if (kstd::units::bytes{last_entry->rec_len} - last_entry_actual_len >= needed_rec_len)
{
- last_entry->rec_len = last_entry_actual_len;
+ last_entry->rec_len = last_entry_actual_len.value;
write_directory_entry_to_buffer(buffer.data(), offset + last_entry_actual_len, child_inode_number, name,
file_type);
return global_block.and_then([&](auto block_number) { return write_block(block_number, buffer.data()); })
@@ -288,8 +292,8 @@ namespace kernel::filesystem::ext2
return kstd::failure(new_global_block.error());
}
- kstd::libc::memset(buffer.data(), 0, block_size());
- write_directory_entry_to_buffer(buffer.data(), 0, child_inode_number, name, file_type);
+ kstd::libc::memset(buffer.data(), 0, block_size().value);
+ write_directory_entry_to_buffer(buffer.data(), 0_B, child_inode_number, name, file_type);
if (auto update_result =
new_global_block.and_then([&](auto block_number) { return write_block(block_number, buffer.data()); });
!update_result)
@@ -298,7 +302,7 @@ namespace kernel::filesystem::ext2
}
}
- ext2_parent->data_mutable().size = inode_block_count(ext2_parent->data()) * block_size();
+ ext2_parent->data_mutable().size = (inode_block_count(ext2_parent->data()) * block_size()).value;
return write_inode(ext2_parent->number(), ext2_parent->data());
}
@@ -316,11 +320,11 @@ namespace kernel::filesystem::ext2
return kstd::failure(global_block.error());
}
- kstd::vector<uint8_t> buffer(block_size(), 0);
- write_directory_entry_to_buffer(buffer.data(), 0, new_inode->number(), ".", 2);
- auto const dot_actual_len = static_cast<uint16_t>((8u + 1 + 3u) & ~3u);
+ kstd::vector<uint8_t> buffer(block_size().value, 0);
+ write_directory_entry_to_buffer(buffer.data(), 0_B, new_inode->number(), ".", 2);
+ auto const dot_actual_len = static_cast<kstd::units::bytes>((8u + 1 + 3u) & ~3u);
auto * entry = reinterpret_cast<linked_directory_entry *>(buffer.data());
- entry->rec_len = dot_actual_len;
+ entry->rec_len = dot_actual_len.value;
write_directory_entry_to_buffer(buffer.data(), dot_actual_len, parent_inode->number(), "..", 2);
@@ -334,8 +338,9 @@ namespace kernel::filesystem::ext2
.transform([](auto) {});
}
- auto filesystem::write_directory_entry_to_buffer(uint8_t * block_buffer, size_t offset, uint32_t child_inode_number,
- std::string_view name, uint8_t file_type) -> void
+ auto filesystem::write_directory_entry_to_buffer(uint8_t * block_buffer, kstd::units::bytes offset,
+ uint32_t child_inode_number, std::string_view name,
+ uint8_t file_type) -> void
{
auto const name_len = static_cast<uint8_t>(name.size());
auto * entry = reinterpret_cast<linked_directory_entry *>(block_buffer + offset);
@@ -352,7 +357,8 @@ namespace kernel::filesystem::ext2
{
auto new_inode_data = inode_data{};
- if (auto read_result = m_backing_inode->read(&new_inode_data, *inode_offset, sizeof(inode_data)); !read_result)
+ if (auto read_result = m_backing_inode->read(&new_inode_data, *inode_offset, kstd::type_size<inode_data>);
+ !read_result)
{
return kstd::failure(read_result.error());
}
@@ -371,7 +377,7 @@ namespace kernel::filesystem::ext2
{
if (auto inode_offset = calculate_inode_offset(inode_number))
{
- return m_backing_inode->write(&data, *inode_offset, sizeof(inode_data)).transform([](auto) {});
+ return m_backing_inode->write(&data, *inode_offset, kstd::type_size<inode_data>).transform([](auto) {});
}
else
{
@@ -379,7 +385,7 @@ namespace kernel::filesystem::ext2
}
}
- auto filesystem::calculate_inode_offset(uint32_t inode_number) const -> kstd::result<size_t>
+ auto filesystem::calculate_inode_offset(uint32_t inode_number) const -> kstd::result<kstd::units::bytes>
{
auto const inodes_per_group = m_superblock.inodes_per_group;
auto const block_group_index = (inode_number - 1) / inodes_per_group;
@@ -392,7 +398,7 @@ namespace kernel::filesystem::ext2
auto const & block_group_descriptor = m_block_group_descriptors.at(block_group_index);
auto const inode_table_start_block = block_group_descriptor.inode_table;
- auto const inode_table_offset = static_cast<size_t>(inode_table_start_block) * block_size();
+ auto const inode_table_offset = inode_table_start_block * block_size();
auto const inode_offset = inode_table_offset + inode_index_within_group * inode_size();
return inode_offset;
@@ -416,7 +422,7 @@ namespace kernel::filesystem::ext2
continue;
}
- kstd::vector<uint8_t> block_bitmap(block_size(), 0);
+ kstd::vector<uint8_t> block_bitmap(block_size().value, 0);
if (auto read_result = read_block(block_group_descriptor.block_bitmap, block_bitmap.data()); !read_result)
{
return kstd::failure(read_result.error());
@@ -445,10 +451,11 @@ namespace kernel::filesystem::ext2
}
// TODO update all block group descriptors
- if (auto write_result = m_backing_inode->write(
- &block_group_descriptor,
- block_group_descriptor_table_offset() + block_group_descriptor_index * sizeof(block_group_descriptor),
- sizeof(block_group_descriptor));
+ if (auto write_result =
+ m_backing_inode->write(&block_group_descriptor,
+ block_group_descriptor_table_offset() +
+ block_group_descriptor_index * kstd::object_size(block_group_descriptor),
+ kstd::object_size(block_group_descriptor));
!write_result)
{
return kstd::failure(write_result.error());
@@ -457,7 +464,8 @@ namespace kernel::filesystem::ext2
}
// TODO update all superblocks
- if (auto write_result = m_backing_inode->write(&m_superblock, constants::superblock_offset, sizeof(m_superblock));
+ if (auto write_result =
+ m_backing_inode->write(&m_superblock, constants::superblock_offset, kstd::object_size(m_superblock));
!write_result)
{
return kstd::failure(write_result.error());
@@ -487,7 +495,7 @@ namespace kernel::filesystem::ext2
continue;
}
- kstd::vector<uint8_t> inode_bitmap(block_size(), 0);
+ kstd::vector<uint8_t> inode_bitmap(block_size().value, 0);
if (auto read_result = read_block(block_group_descriptor.inode_bitmap, inode_bitmap.data()); !read_result)
{
return kstd::failure(read_result.error());
@@ -586,8 +594,8 @@ namespace kernel::filesystem::ext2
uint32_t block_number_buffer = 0;
auto const block_start_offset = block_number * block_size();
- auto const number_start_address = block_start_offset + index * sizeof(uint32_t);
- if (auto read_result = m_backing_inode->read(&block_number_buffer, number_start_address, sizeof(uint32_t));
+ 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>);
!read_result)
{
return kstd::failure(read_result.error());
@@ -615,7 +623,7 @@ namespace kernel::filesystem::ext2
}
auto block_number = data.block[level.slot_index];
- auto parent_byte_offset = 0uz;
+ auto parent_byte_offset = 0_B;
bool is_root = true;
for (auto stride = level.capacity / block_numbers_per_block();; stride /= block_numbers_per_block())
@@ -639,7 +647,8 @@ namespace kernel::filesystem::ext2
}
else
{
- if (auto write_result = m_backing_inode->write(&block_number, parent_byte_offset, sizeof(uint32_t));
+ if (auto write_result =
+ m_backing_inode->write(&block_number, parent_byte_offset, kstd::type_size<uint32_t>);
!write_result)
{
return kstd::failure(write_result.error());
@@ -647,11 +656,11 @@ namespace kernel::filesystem::ext2
}
}
- auto const byte_offset = block_number * block_size() + idx * sizeof(uint32_t);
+ auto const byte_offset = block_number * block_size() + idx * kstd::type_size<uint32_t>;
if (stride == 1)
{
- if (auto write_result = m_backing_inode->write(&global_block_number, byte_offset, sizeof(uint32_t));
+ if (auto write_result = m_backing_inode->write(&global_block_number, byte_offset, kstd::type_size<uint32_t>);
!write_result)
{
return kstd::failure(write_result.error());
@@ -675,13 +684,13 @@ namespace kernel::filesystem::ext2
return kstd::success();
}
- auto filesystem::read_block(uint32_t block_number, void * buffer) const -> kstd::result<size_t>
+ 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());
}
- auto filesystem::write_block(uint32_t block_number, void const * buffer) -> kstd::result<size_t>
+ 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());
@@ -693,15 +702,16 @@ namespace kernel::filesystem::ext2
// TODO update all block group descriptors
return m_backing_inode
->write(&block_group_descriptor,
- block_group_descriptor_table_offset() + block_group_descriptor_index * sizeof(block_group_descriptor),
- sizeof(block_group_descriptor))
+ block_group_descriptor_table_offset() +
+ block_group_descriptor_index * kstd::object_size(block_group_descriptor),
+ 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, sizeof(m_superblock))
+ return m_backing_inode->write(&m_superblock, constants::superblock_offset, kstd::object_size(m_superblock))
.transform([](auto) {});
}
@@ -738,7 +748,7 @@ namespace kernel::filesystem::ext2
auto filesystem::block_numbers_per_block() const -> size_t
{
- return block_size() / sizeof(uint32_t);
+ return block_size() / kstd::type_size<uint32_t>;
}
auto filesystem::block_numbers_per_singly_indirect_block() const -> size_t
@@ -756,9 +766,9 @@ namespace kernel::filesystem::ext2
return block_numbers_per_doubly_indirect_block() * block_numbers_per_block();
}
- auto filesystem::block_size() const -> size_t
+ auto filesystem::block_size() const -> kstd::units::bytes
{
- return constants::base_block_size << m_superblock.log_block_size;
+ return kstd::units::bytes{constants::base_block_size.value << m_superblock.log_block_size};
}
auto filesystem::revision_level() const -> uint32_t
@@ -766,9 +776,9 @@ namespace kernel::filesystem::ext2
return m_superblock.rev_level;
}
- auto filesystem::inode_size() const -> uint16_t
+ auto filesystem::inode_size() const -> kstd::units::bytes
{
- return revision_level() == constants::good_old_revision ? 128 : m_superblock.inode_size;
+ return kstd::units::bytes(revision_level() == constants::good_old_revision ? 128 : m_superblock.inode_size);
}
auto filesystem::inode_block_count(inode_data const & data) const -> uint32_t
@@ -781,9 +791,9 @@ namespace kernel::filesystem::ext2
data.blocks += delta * (2 << m_superblock.log_block_size);
}
- auto filesystem::block_group_descriptor_table_offset() const -> size_t
+ auto filesystem::block_group_descriptor_table_offset() const -> kstd::units::bytes
{
- return block_size() == 1024 ? 2 * block_size() : block_size();
+ return block_size() == 1024_B ? 2 * block_size() : block_size();
}
} // namespace kernel::filesystem::ext2
diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp
index e5192ec0..23e56143 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.hpp
@@ -11,6 +11,7 @@
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <array>
@@ -25,8 +26,8 @@ namespace kernel::filesystem::ext2
*/
namespace constants
{
- constexpr size_t inline base_block_size = 1024;
- constexpr size_t inline superblock_offset = base_block_size;
+ constexpr kstd::units::bytes inline base_block_size = kstd::units::bytes{1024};
+ constexpr kstd::units::bytes inline superblock_offset = base_block_size;
constexpr uint16_t inline magic_number = 0xEF53;
constexpr uint32_t inline good_old_revision = 0;
@@ -82,7 +83,7 @@ namespace kernel::filesystem::ext2
@brief Gets the size of a block in the filesystem.
@return The size of a block in bytes.
*/
- [[nodiscard]] auto block_size() const -> size_t;
+ [[nodiscard]] auto block_size() const -> kstd::units::bytes;
/**
@brief Gets the revision level of the filesystem.
@@ -96,7 +97,7 @@ namespace kernel::filesystem::ext2
@param buffer The buffer to read the block data into.
@return The number of bytes read.
*/
- auto read_block(uint32_t block_number, void * buffer) const -> kstd::result<size_t>;
+ auto read_block(uint32_t block_number, void * buffer) const -> kstd::result<kstd::units::bytes>;
/**
@brief Writes a block of data from the provided buffer to the backing device.
@@ -104,7 +105,7 @@ namespace kernel::filesystem::ext2
@param buffer The buffer containing the data to write.
@return The number of bytes written.
*/
- auto write_block(uint32_t block_number, void const * buffer) -> kstd::result<size_t>;
+ auto write_block(uint32_t block_number, void const * buffer) -> kstd::result<kstd::units::bytes>;
/**
@brief Allocates a specified number of blocks.
@@ -117,7 +118,7 @@ namespace kernel::filesystem::ext2
@brief Gets the size of an inode in the filesystem.
@return The size of an inode in bytes.
*/
- [[nodiscard]] auto inode_size() const -> uint16_t;
+ [[nodiscard]] auto inode_size() const -> kstd::units::bytes;
/**
@brief Gets the number of blocks allocated to an inode.
@@ -172,14 +173,14 @@ namespace kernel::filesystem::ext2
-> kstd::result<void>;
auto init_directory(kstd::shared_ptr<kernel::filesystem::ext2::inode> const & new_inode,
kernel::filesystem::ext2::inode * parent_inode) -> kstd::result<void>;
- auto write_directory_entry_to_buffer(uint8_t * block_buffer, size_t offset, uint32_t child_inode_number,
+ auto write_directory_entry_to_buffer(uint8_t * block_buffer, kstd::units::bytes offset, uint32_t child_inode_number,
std::string_view name, uint8_t file_type) -> void;
- [[nodiscard]] auto calculate_inode_offset(uint32_t inode_number) const -> kstd::result<size_t>;
+ [[nodiscard]] auto calculate_inode_offset(uint32_t inode_number) const -> kstd::result<kstd::units::bytes>;
[[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::result<kstd::shared_ptr<inode>>;
[[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> kstd::result<uint32_t>;
- [[nodiscard]] auto block_group_descriptor_table_offset() const -> size_t;
+ [[nodiscard]] auto block_group_descriptor_table_offset() const -> kstd::units::bytes;
[[nodiscard]] auto block_numbers_per_block() const -> size_t;
[[nodiscard]] auto block_numbers_per_singly_indirect_block() const -> size_t;
diff --git a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp
index 8aecc847..9013ea22 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.tests.cpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.tests.cpp
@@ -14,6 +14,7 @@
#include <kernel/test_support/filesystem/storage_boot_module_fixture.hpp>
#include <kstd/memory.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -26,6 +27,10 @@
#include <string_view>
#include <vector>
+using namespace kstd::units_literals;
+
+// NOLINTBEGIN(readability-magic-numbers)
+
SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture,
"Ext2 filesystem mount and lookup with real image", "[filesystem][ext2][filesystem][img]")
{
@@ -144,12 +149,12 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture,
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, buffer.size());
- REQUIRE(bytes_written == buffer.size());
+ auto bytes_written = new_inode.value()->write(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ 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, read_buffer.size());
- REQUIRE(bytes_read == read_buffer.size());
+ auto bytes_read = new_inode.value()->read(read_buffer.data(), 0_B, kstd::units::bytes{read_buffer.size()});
+ 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)};
REQUIRE(result == "Hello");
@@ -166,7 +171,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture,
SCENARIO("Ext2 filesystem rejects invalid magic", "[filesystem][ext2][filesystem]")
{
- auto const block_size = 1024;
+ auto const block_size = 1024_B;
GIVEN("a block device that does not contain an ext2 superblock")
{
auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "mock", block_size, 2 * block_size);
@@ -185,7 +190,7 @@ SCENARIO("Ext2 filesystem rejects invalid magic", "[filesystem][ext2][filesystem
SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesystem][ext2][filesystem]")
{
- auto const block_size = 1024;
+ auto const block_size = 1024_B;
GIVEN("a minimally valid ext2 layout with configured indirect block tables")
{
@@ -214,7 +219,7 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys
kernel::tests::filesystem::ext2::write_u32(*device, 51 * block_size, 52);
kernel::tests::filesystem::ext2::write_u32(*device, 52 * block_size, 53);
- auto const numbers_per_block = static_cast<uint32_t>(block_size / sizeof(uint32_t));
+ auto const numbers_per_block = static_cast<uint32_t>(block_size / kstd::type_size<uint32_t>);
auto const singly_start = static_cast<uint32_t>(kernel::filesystem::ext2::constants::direct_block_count);
auto const doubly_start = singly_start + numbers_per_block;
auto const triply_start = doubly_start + numbers_per_block * numbers_per_block;
@@ -237,7 +242,7 @@ SCENARIO("Ext2 block mapping includes direct and all indirect levels", "[filesys
SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesystem][ext2][filesystem]")
{
- auto const block_size = 1024;
+ auto const block_size = 1024_B;
GIVEN("a mounted ext2 filesystem with free blocks available for indirect table allocation")
{
@@ -259,7 +264,7 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys
block_group_descriptor.inode_table = 5;
block_group_descriptor.free_blocks_count = 128;
- auto block_bitmap = std::vector<std::byte>(block_size, std::byte{0x00});
+ auto block_bitmap = std::vector<std::byte>(block_size.value, std::byte{0x00});
block_bitmap[0] = std::byte{0b1111'1111};
block_bitmap[1] = std::byte{0b1111'1111};
@@ -271,7 +276,7 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys
auto fs = kernel::filesystem::ext2::filesystem{};
REQUIRE(fs.mount(dev_inode));
- auto read_u32 = [&](size_t offset) -> uint32_t {
+ auto read_u32 = [&](kstd::units::bytes offset) -> uint32_t {
auto value = uint32_t{0};
std::memcpy(&value, device->data.data() + offset, sizeof(value));
return value;
@@ -279,7 +284,7 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys
auto inode_data = kernel::filesystem::ext2::inode_data{};
- auto const numbers_per_block = static_cast<uint32_t>(block_size / sizeof(uint32_t));
+ auto const numbers_per_block = static_cast<uint32_t>(block_size / kstd::type_size<uint32_t>);
auto const singly_start = static_cast<uint32_t>(kernel::filesystem::ext2::constants::direct_block_count);
auto const doubly_start = singly_start + numbers_per_block;
auto const triply_start = doubly_start + numbers_per_block * numbers_per_block;
@@ -296,12 +301,13 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys
REQUIRE(fs.write_global_block_number_to_inode_block_index(singly_start, inode_data, singly_global_block_number));
REQUIRE(inode_data.block[12] == 16);
- REQUIRE(read_u32(static_cast<size_t>(inode_data.block[12]) * block_size) == singly_global_block_number);
+ REQUIRE(read_u32(static_cast<kstd::units::bytes>(inode_data.block[12]) * block_size.value) ==
+ singly_global_block_number);
REQUIRE(fs.write_global_block_number_to_inode_block_index(singly_start + 1, inode_data,
singly_global_block_number + 1));
- REQUIRE(read_u32(static_cast<size_t>(inode_data.block[12]) * block_size + 1 * sizeof(uint32_t)) ==
- singly_global_block_number + 1);
+ REQUIRE(read_u32(static_cast<kstd::units::bytes>(inode_data.block[12]) * block_size.value +
+ 1 * kstd::type_size<uint32_t>) == singly_global_block_number + 1);
REQUIRE(fs.write_global_block_number_to_inode_block_index(doubly_start, inode_data, doubly_global_block_number));
REQUIRE(inode_data.block[13] == 17);
@@ -324,3 +330,5 @@ SCENARIO("Ext2 block writing includes direct and all indirect levels", "[filesys
}
}
}
+
+// NOLINTEND(readability-magic-numbers) \ No newline at end of file
diff --git a/kernel/kernel/filesystem/ext2/inode.cpp b/kernel/kernel/filesystem/ext2/inode.cpp
index 8af168b9..f42e2c0c 100644
--- a/kernel/kernel/filesystem/ext2/inode.cpp
+++ b/kernel/kernel/filesystem/ext2/inode.cpp
@@ -7,11 +7,14 @@
#include <kstd/cstring.hpp>
#include <kstd/result.hpp>
+#include <kstd/units.hpp>
#include <algorithm>
#include <cstddef>
#include <cstdint>
+using namespace kstd::units_literals;
+
namespace kernel::filesystem::ext2
{
inode::inode(filesystem * fs, uint32_t inode_number, inode_data const & data)
@@ -25,22 +28,23 @@ namespace kernel::filesystem::ext2
}
}
- auto inode::read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t>
+ auto inode::read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
+ -> kstd::result<kstd::units::bytes>
{
auto const max_readable = this->size() - offset;
auto const requested_size = std::min(size, max_readable);
- if (is_symbolic_link() && this->size() <= sizeof(m_data.block))
+ 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);
+ kstd::libc::memcpy(static_cast<uint8_t *>(buffer), inline_target + offset, requested_size.value);
return requested_size;
}
auto block_index = offset / m_filesystem->block_size();
auto in_block_offset = offset % m_filesystem->block_size();
- auto bytes_read = 0uz;
+ auto bytes_read = 0_B;
while (bytes_read < requested_size)
{
@@ -53,7 +57,7 @@ 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);
+ kstd::libc::memset(static_cast<uint8_t *>(buffer) + bytes_read, 0, bytes_to_read.value);
bytes_read += bytes_to_read;
}
else
@@ -71,13 +75,14 @@ namespace kernel::filesystem::ext2
}
block_index++;
- in_block_offset = 0; // After the first block, we always start at the beginning of the block
+ in_block_offset = 0_B; // After the first block, we always start at the beginning of the block
}
return bytes_read;
}
- auto inode::write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t>
+ auto inode::write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes>
{
if (!is_regular())
{
@@ -95,7 +100,7 @@ namespace kernel::filesystem::ext2
if (new_inode_size > max_new_inode_size_without_new_blocks)
{
auto const additional_blocks_needed =
- (new_inode_size - max_new_inode_size_without_new_blocks + m_filesystem->block_size() - 1) /
+ (new_inode_size - max_new_inode_size_without_new_blocks + m_filesystem->block_size() - 1_B) /
m_filesystem->block_size();
if (!append_blocks(additional_blocks_needed))
@@ -108,7 +113,7 @@ namespace kernel::filesystem::ext2
auto block_index = offset / m_filesystem->block_size();
auto in_block_offset = offset % m_filesystem->block_size();
- auto bytes_written = 0uz;
+ auto bytes_written = 0_B;
while (bytes_written < size)
{
@@ -134,7 +139,7 @@ namespace kernel::filesystem::ext2
bytes_written += write_result.value();
block_index++;
- in_block_offset = 0;
+ in_block_offset = 0_B;
}
set_size(std::max(this->size(), offset + bytes_written));
@@ -196,7 +201,7 @@ namespace kernel::filesystem::ext2
return (m_data.mode & constants::mode_mask) == constants::mode_symbolic_link;
}
- auto inode::size() const -> uint64_t
+ auto inode::size() const -> kstd::units::bytes
{
uint64_t size = m_data.size;
@@ -205,16 +210,16 @@ namespace kernel::filesystem::ext2
size |= static_cast<uint64_t>(m_data.dir_acl) << 32;
}
- return size;
+ return kstd::units::bytes{size};
}
- auto inode::set_size(uint64_t new_size) -> void
+ auto inode::set_size(kstd::units::bytes new_size) -> void
{
if (m_filesystem->revision_level() > constants::good_old_revision && is_regular())
{
- m_data.dir_acl = static_cast<uint32_t>(new_size >> 32);
+ m_data.dir_acl = static_cast<uint32_t>(new_size.value >> 32);
}
- m_data.size = static_cast<uint32_t>(new_size);
+ m_data.size = static_cast<uint32_t>(new_size.value);
}
[[nodiscard]] auto inode::number() const -> uint32_t
diff --git a/kernel/kernel/filesystem/ext2/inode.hpp b/kernel/kernel/filesystem/ext2/inode.hpp
index 61542ef8..1d364a54 100644
--- a/kernel/kernel/filesystem/ext2/inode.hpp
+++ b/kernel/kernel/filesystem/ext2/inode.hpp
@@ -5,6 +5,7 @@
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
+#include <kstd/units.hpp>
#include <array>
#include <cstddef>
@@ -56,7 +57,8 @@ namespace kernel::filesystem::ext2
@param size Number of bytes requested.
@return Number of bytes read.
*/
- auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
+ auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
+ -> kstd::result<kstd::units::bytes> override;
/**
@brief Writes to the ext2 inode into a @p buffer, starting at the specified @p offset and for a given @p size.
@@ -65,7 +67,8 @@ namespace kernel::filesystem::ext2
@param size Number of bytes requested.
@return Number of bytes written.
*/
- auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
+ auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes> override;
/**
@brief Appends the specified number of blocks to the inode.
@@ -108,13 +111,13 @@ namespace kernel::filesystem::ext2
@brief Get the size of the file represented by this inode.
@return The size of the file in bytes.
*/
- [[nodiscard]] auto size() const -> uint64_t;
+ [[nodiscard]] auto size() const -> kstd::units::bytes;
/**
@brief Set the size of the file represented by this inode.
@param new_size The new size of the file in bytes.
*/
- auto set_size(uint64_t new_size) -> void;
+ auto set_size(kstd::units::bytes new_size) -> void;
/**
@brief Get the inode number of this inode.
diff --git a/kernel/kernel/filesystem/ext2/inode.tests.cpp b/kernel/kernel/filesystem/ext2/inode.tests.cpp
index 7e293d14..e3c06407 100644
--- a/kernel/kernel/filesystem/ext2/inode.tests.cpp
+++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp
@@ -12,6 +12,7 @@
#include <kernel/test_support/filesystem/storage_boot_module_fixture.hpp>
#include <kstd/memory.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -23,6 +24,8 @@
#include <string_view>
#include <vector>
+using namespace kstd::units_literals;
+
// NOLINTBEGIN(readability-magic-numbers)
SCENARIO("Ext2 inode initialization and properties", "[filesystem][ext2][inode]")
@@ -113,20 +116,20 @@ 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, buffer.size());
+ auto const bytes_read = file.value()->read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
- REQUIRE(bytes_read == 6);
+ REQUIRE(bytes_read == 6_B);
- auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read->value};
REQUIRE(text == "info_1");
}
THEN("reading with an offset returns the expected byte")
{
auto buffer = kstd::vector<std::byte>(1);
- auto const bytes_read = file.value()->read(buffer.data(), 5, buffer.size());
+ auto const bytes_read = file.value()->read(buffer.data(), 5_B, kstd::units::bytes{buffer.size()});
- REQUIRE(bytes_read == 1);
+ REQUIRE(bytes_read == 1_B);
REQUIRE(static_cast<char>(buffer[0]) == '1');
}
}
@@ -134,7 +137,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in
SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesystem][ext2][inode]")
{
- auto const block_size = 1024uz;
+ auto const block_size = 1024_B;
GIVEN("an ext2 inode with only direct mapped data blocks")
{
auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "mock", block_size, 64 * block_size);
@@ -150,10 +153,10 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
data.block[0] = 30;
data.block[1] = 0;
data.block[2] = 31;
- data.size = block_size * 3;
+ data.size = block_size.value * 3;
- kernel::tests::filesystem::ext2::write_bytes(*device, 30 * block_size, "Hello", 5);
- kernel::tests::filesystem::ext2::write_bytes(*device, 31 * block_size, "World!", 6);
+ kernel::tests::filesystem::ext2::write_bytes(*device, 30 * block_size, "Hello", 5_B);
+ kernel::tests::filesystem::ext2::write_bytes(*device, 31 * block_size, "World!", 6_B);
auto inode = kernel::filesystem::ext2::inode{&fs, 42, data};
@@ -161,14 +164,15 @@ 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, buffer.size());
- REQUIRE(bytes_read == data.size);
+ auto const bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ REQUIRE(bytes_read == kstd::units::bytes{data.size});
- auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read->value};
REQUIRE(text.substr(0, 5) == "Hello");
- REQUIRE(std::ranges::all_of(text.substr(5, block_size - 5), [](char c) { return c == '\0'; }));
- REQUIRE(text.substr(2 * block_size, 6) == "World!");
- REQUIRE(std::ranges::all_of(text.substr(2 * block_size + 6, 3 * block_size), [](char c) { return c == '\0'; }));
+ REQUIRE(std::ranges::all_of(text.substr(5, block_size.value - 5), [](char c) { return c == '\0'; }));
+ REQUIRE(text.substr(2 * block_size.value, 6) == "World!");
+ REQUIRE(std::ranges::all_of(text.substr(2 * block_size.value + 6, 3 * block_size.value),
+ [](char c) { return c == '\0'; }));
}
}
@@ -186,15 +190,15 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
auto data = kernel::filesystem::ext2::inode_data{};
data.block[0] = 30;
data.block[12] = 31;
- data.size = block_size * 15;
+ data.size = block_size.value * 15;
kernel::tests::filesystem::ext2::write_u32(*device, 31 * block_size, 50);
- kernel::tests::filesystem::ext2::write_u32(*device, 31 * block_size + 4, 0);
- kernel::tests::filesystem::ext2::write_u32(*device, 31 * block_size + 8, 51);
+ kernel::tests::filesystem::ext2::write_u32(*device, 31 * block_size + 4_B, 0);
+ kernel::tests::filesystem::ext2::write_u32(*device, 31 * block_size + 8_B, 51);
- kernel::tests::filesystem::ext2::write_bytes(*device, 30 * block_size, "Hello", 5);
- kernel::tests::filesystem::ext2::write_bytes(*device, 50 * block_size, "Blub", 4);
- kernel::tests::filesystem::ext2::write_bytes(*device, 51 * block_size, "World!", 6);
+ kernel::tests::filesystem::ext2::write_bytes(*device, 30 * block_size, "Hello", 5_B);
+ kernel::tests::filesystem::ext2::write_bytes(*device, 50 * block_size, "Blub", 4_B);
+ kernel::tests::filesystem::ext2::write_bytes(*device, 51 * block_size, "World!", 6_B);
auto inode = kernel::filesystem::ext2::inode{&fs, 42, data};
@@ -202,18 +206,18 @@ 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, buffer.size());
- REQUIRE(bytes_read == data.size);
+ auto const bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ REQUIRE(bytes_read == kstd::units::bytes{data.size});
- auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read->value};
REQUIRE(text.substr(0, 5) == "Hello");
- REQUIRE(std::ranges::all_of(text.substr(5, 12 * block_size - 5), [](char c) { return c == '\0'; }));
- REQUIRE(text.substr(12 * block_size, 4) == "Blub");
- REQUIRE(
- std::ranges::all_of(text.substr(12 * block_size + 4, 2 * block_size - 4), [](char c) { return c == '\0'; }));
- REQUIRE(text.substr(14 * block_size, 6) == "World!");
- REQUIRE(
- std::ranges::all_of(text.substr(14 * block_size + 6, 1 * block_size - 6), [](char c) { return c == '\0'; }));
+ REQUIRE(std::ranges::all_of(text.substr(5, 12 * block_size.value - 5), [](char c) { return c == '\0'; }));
+ REQUIRE(text.substr(12 * block_size.value, 4) == "Blub");
+ REQUIRE(std::ranges::all_of(text.substr(12 * block_size.value + 4, 2 * block_size.value - 4),
+ [](char c) { return c == '\0'; }));
+ REQUIRE(text.substr(14 * block_size.value, 6) == "World!");
+ REQUIRE(std::ranges::all_of(text.substr(14 * block_size.value + 6, 1 * block_size.value - 6),
+ [](char c) { return c == '\0'; }));
}
}
@@ -230,16 +234,16 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
auto data = kernel::filesystem::ext2::inode_data{};
data.block[12] = 0;
- data.size = block_size * 15;
+ data.size = block_size.value * 15;
auto inode = kernel::filesystem::ext2::inode{&fs, 42, data};
- auto buffer = kstd::vector<std::byte>(block_size * 15, std::byte{0xAB});
+ auto buffer = kstd::vector<std::byte>(block_size.value * 15, std::byte{0xAB});
THEN("all direct blocks are zero when singly indirect block pointer is zero")
{
- auto const bytes_read = inode.read(buffer.data(), 0, buffer.size());
- REQUIRE(bytes_read == buffer.size());
+ auto const bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
+ REQUIRE(bytes_read == kstd::units::bytes{buffer.size()});
REQUIRE(std::ranges::all_of(buffer, [](std::byte c) { return c == std::byte{0x00}; }));
}
}
@@ -247,7 +251,7 @@ SCENARIO("Ext2 inode handles zeros in block mappings as file holes", "[filesyste
SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]")
{
- auto const block_size = 1024uz;
+ auto const block_size = 1024_B;
GIVEN("an ext2 inode with two direct blocks and a block size of 1024 bytes")
{
auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "mock", block_size, 64 * block_size);
@@ -260,21 +264,21 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]")
REQUIRE(fs.mount(dev_inode));
auto inode_data = kernel::filesystem::ext2::inode_data{};
- inode_data.size = block_size * 2;
+ inode_data.size = block_size.value * 2;
inode_data.block[0] = 20;
- kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size - 6, "Hello ", 6);
+ kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size - 6_B, "Hello ", 6_B);
inode_data.block[1] = 21;
- kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size, "World!", 6);
+ kernel::tests::filesystem::ext2::write_bytes(*device, 21 * block_size, "World!", 6_B);
auto inode = kernel::filesystem::ext2::inode{&fs, 42, inode_data};
auto buffer = kstd::vector<std::byte>(12, std::byte{0x00});
THEN("reading across the block boundary returns the combined content")
{
- auto const bytes_read = inode.read(buffer.data(), block_size - 6, buffer.size());
- REQUIRE(bytes_read == 12);
+ auto const bytes_read = inode.read(buffer.data(), block_size - 6_B, kstd::units::bytes{buffer.size()});
+ REQUIRE(bytes_read == kstd::units::bytes{12});
- auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read->value};
REQUIRE(text == "Hello World!");
}
}
@@ -309,18 +313,18 @@ 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, write_buffer.size());
- REQUIRE(bytes_written == 12);
+ auto const bytes_written = file.value()->write(write_buffer.data(), 0_B, kstd::units::bytes{write_buffer.size()});
+ 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, read_buffer.size());
- REQUIRE(bytes_read == 12);
+ auto const bytes_read = file.value()->read(read_buffer.data(), 0_B, kstd::units::bytes{read_buffer.size()});
+ REQUIRE(bytes_read == kstd::units::bytes{12});
- auto const text = std::string_view{reinterpret_cast<char const *>(read_buffer.data()), *bytes_read};
+ auto const text = std::string_view{reinterpret_cast<char const *>(read_buffer.data()), bytes_read->value};
REQUIRE(text == "Hello World!");
auto inode_data = static_cast<kernel::filesystem::ext2::inode *>(file.value().get())->data();
- REQUIRE(inode_data.size == bytes_read);
+ REQUIRE(inode_data.size == bytes_read->value);
}
THEN("writing allocates new blocks and updates the inode size")
@@ -330,13 +334,13 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in
auto const block_size = fs.block_size();
auto const expected_allocated_blocks = 32 * fs.inode_block_count(inode_data);
- auto write_buffer = kstd::vector<std::byte>(block_size * expected_allocated_blocks, std::byte{'A'});
+ 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, write_buffer.size());
+ auto const bytes_written = file.value()->write(write_buffer.data(), 0_B, kstd::units::bytes{write_buffer.size()});
REQUIRE(bytes_written == block_size * expected_allocated_blocks);
- auto read_buffer = kstd::vector<std::byte>(block_size * expected_allocated_blocks, std::byte{0x00});
- auto const bytes_read = file.value()->read(read_buffer.data(), 0, read_buffer.size());
+ 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()});
REQUIRE(bytes_read == block_size * expected_allocated_blocks);
REQUIRE(std::ranges::all_of(read_buffer, [](std::byte c) { return c == std::byte{'A'}; }));
@@ -348,7 +352,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, write_buffer.size()),
+ REQUIRE_THROWS_AS(information.value()->write(write_buffer.data(), 0_B, kstd::units::bytes{write_buffer.size()}),
kernel::tests::cpu::halt);
}
}
@@ -356,7 +360,7 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_fixture, "Ext2 in
SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]")
{
- auto const block_size = 1024uz;
+ auto const block_size = 1024_B;
auto device = kstd::make_shared<kernel::tests::devices::block_device>(0, 0, "mock", block_size, 128 * block_size);
REQUIRE(device != nullptr);
@@ -380,7 +384,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
auto dev_inode = kstd::make_shared<kernel::filesystem::device_inode>(device);
- auto block_bitmap = std::vector<std::byte>(block_size, std::byte{0x00});
+ auto block_bitmap = std::vector<std::byte>(block_size.value, std::byte{0x00});
block_bitmap[0] = std::byte{0b1111'1111};
block_bitmap[1] = std::byte{0b1111'1111};
block_bitmap[2] = std::byte{0b0011'0000};
@@ -392,7 +396,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
auto inode_data = kernel::filesystem::ext2::inode_data{};
inode_data.size = 5;
- inode_data.blocks = 2 * block_size / 512;
+ inode_data.blocks = 2 * block_size.value / 512;
inode_data.block[0] = 20;
inode_data.block[1] = 21;
inode_data.mode = kernel::filesystem::ext2::constants::mode_regular;
@@ -401,7 +405,7 @@ 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, sizeof(kernel::filesystem::ext2::inode_data)));
+ REQUIRE(dev_inode->write(&inode, inode_data_offset, kstd::type_size<kernel::filesystem::ext2::inode_data>));
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'},
@@ -411,26 +415,26 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
{
auto do_read_inode = [&]() {
auto inode_data = kernel::filesystem::ext2::inode_data{};
- REQUIRE(dev_inode->read(&inode_data, inode_data_offset, sizeof(kernel::filesystem::ext2::inode_data)));
+ REQUIRE(dev_inode->read(&inode_data, inode_data_offset, kstd::type_size<kernel::filesystem::ext2::inode_data>));
auto read_inode = kernel::filesystem::ext2::inode{&fs, inode_number, inode_data};
return read_inode;
};
THEN("writing in the current size does not update the size and does not allocate new blocks")
{
- auto const expected_bytes_written = 3;
- auto const bytes_written = inode.write(buffer.data(), 0, expected_bytes_written);
+ auto const expected_bytes_written = 3_B;
+ auto const bytes_written = inode.write(buffer.data(), 0_B, expected_bytes_written);
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, std::byte{0x00});
+ 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(block_bitmap == read_block_bitmap);
auto read_inode = do_read_inode();
- REQUIRE(inode_data.size == read_inode.size());
+ REQUIRE(inode_data.size == read_inode.size().value);
REQUIRE(inode_data.blocks == read_inode.data().blocks);
auto const current_blocks = inode_data.block;
@@ -441,20 +445,20 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
THEN("writing over the current size (within an existing block) updates the size but does not allocate additional "
"blocks")
{
- auto const offset = block_size - 4;
- auto const bytes_written = inode.write(buffer.data(), offset, buffer.size());
- REQUIRE(bytes_written == buffer.size());
+ auto const offset = block_size - 4_B;
+ auto const bytes_written = inode.write(buffer.data(), offset, kstd::units::bytes{buffer.size()});
+ REQUIRE(bytes_written == kstd::units::bytes{buffer.size()});
- auto const text =
- std::string_view{reinterpret_cast<char const *>(device->data.data() + 21 * block_size - 4), *bytes_written};
+ auto const text = std::string_view{
+ reinterpret_cast<char const *>(device->data.data() + 21 * block_size.value - 4), bytes_written->value};
REQUIRE(text == "Hello World!");
- auto read_block_bitmap = std::vector<std::byte>(block_size, std::byte{0x00});
+ 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(block_bitmap == read_block_bitmap);
auto read_inode = do_read_inode();
- REQUIRE(offset + buffer.size() == read_inode.size());
+ REQUIRE(offset + kstd::units::bytes{buffer.size()} == read_inode.size());
REQUIRE(inode_data.blocks == read_inode.data().blocks);
auto const current_blocks = inode_data.block;
@@ -464,16 +468,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;
- auto const bytes_written = inode.write(buffer.data(), offset, buffer.size());
- REQUIRE(bytes_written == buffer.size());
+ auto const offset = block_size * 2 - 4_B;
+ auto const bytes_written = inode.write(buffer.data(), offset, kstd::units::bytes{buffer.size()});
+ 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, buffer.size());
- auto const text = std::string_view{reinterpret_cast<char const *>(read_buffer.data()), *bytes_read};
+ auto const bytes_read = inode.read(read_buffer.data(), offset, kstd::units::bytes{buffer.size()});
+ 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, std::byte{0x00});
+ 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));
auto expected_block_bitmap = block_bitmap;
@@ -481,7 +485,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
REQUIRE(expected_block_bitmap == read_block_bitmap);
auto read_inode = do_read_inode();
- REQUIRE(offset + buffer.size() == read_inode.size());
+ REQUIRE(offset + kstd::units::bytes{buffer.size()} == read_inode.size());
REQUIRE(inode_data.blocks + 2 == read_inode.data().blocks);
auto expected_blocks = inode_data.block;
@@ -493,7 +497,8 @@ 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, buffer.size()), kernel::tests::cpu::halt);
+ REQUIRE_THROWS_AS(inode.write(buffer.data(), offset, kstd::units::bytes{buffer.size()}),
+ kernel::tests::cpu::halt);
}
}
}
@@ -501,7 +506,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending on revision level",
"[filesystem][ext2][inode]")
{
- auto const block_size = 1024uz;
+ auto const block_size = 1024_B;
auto superblock = kernel::filesystem::ext2::superblock{};
superblock.magic = kernel::filesystem::ext2::constants::magic_number;
@@ -528,7 +533,7 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending
data.size = 256;
data.dir_acl = 32;
- auto const verify_size_and_set_size = [&](uint16_t mode, uint64_t expected_initial_size,
+ auto const verify_size_and_set_size = [&](uint16_t mode, kstd::units::bytes expected_initial_size,
uint32_t expected_dir_acl_after_set_size) {
data.mode = mode;
@@ -536,21 +541,21 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending
REQUIRE(inode.size() == expected_initial_size);
- inode.set_size(12);
+ inode.set_size(12_B);
- REQUIRE(inode.size() == 12);
+ REQUIRE(inode.size() == 12_B);
REQUIRE(inode.data().size == 12);
REQUIRE(inode.data().dir_acl == expected_dir_acl_after_set_size);
};
THEN("the inode size is 256 if mode = regular")
{
- verify_size_and_set_size(kernel::filesystem::ext2::constants::mode_regular, 256, 32);
+ verify_size_and_set_size(kernel::filesystem::ext2::constants::mode_regular, 256_B, 32);
}
THEN("the inode size is 256 if mode = directory")
{
- verify_size_and_set_size(kernel::filesystem::ext2::constants::mode_directory, 256, 32);
+ verify_size_and_set_size(kernel::filesystem::ext2::constants::mode_directory, 256_B, 32);
}
}
@@ -571,7 +576,7 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending
data.size = 256;
data.dir_acl = 32;
- auto const verify_size_and_set_size = [&](uint16_t mode, uint64_t expected_initial_size,
+ auto const verify_size_and_set_size = [&](uint16_t mode, kstd::units::bytes expected_initial_size,
uint32_t expected_dir_acl_after_set_size) {
data.mode = mode;
@@ -579,21 +584,21 @@ SCENARIO("Ext2 inode get_size() and set_size() handles size correctly depending
REQUIRE(inode.size() == expected_initial_size);
- inode.set_size(12);
+ inode.set_size(12_B);
- REQUIRE(inode.size() == 12);
+ REQUIRE(inode.size() == 12_B);
REQUIRE(inode.data().size == 12);
REQUIRE(inode.data().dir_acl == expected_dir_acl_after_set_size);
};
THEN("the inode size is 256 if mode = regular")
{
- verify_size_and_set_size(kernel::filesystem::ext2::constants::mode_regular, 0x0000'0020'0000'0100, 0);
+ verify_size_and_set_size(kernel::filesystem::ext2::constants::mode_regular, 0x0000'0020'0000'0100_B, 0);
}
THEN("the inode size is 256 if mode = directory")
{
- verify_size_and_set_size(kernel::filesystem::ext2::constants::mode_directory, 256, 32);
+ verify_size_and_set_size(kernel::filesystem::ext2::constants::mode_directory, 256_B, 32);
}
}
}
diff --git a/kernel/kernel/filesystem/inode.hpp b/kernel/kernel/filesystem/inode.hpp
index cfddebf6..67487a8b 100644
--- a/kernel/kernel/filesystem/inode.hpp
+++ b/kernel/kernel/filesystem/inode.hpp
@@ -2,8 +2,7 @@
#define TEACH_OS_KERNEL_FILESYSTEM_INODE_HPP
#include <kstd/result.hpp>
-
-#include <cstddef>
+#include <kstd/units.hpp>
namespace kernel::filesystem
{
@@ -30,7 +29,8 @@ namespace kernel::filesystem
@param size Number of bytes requested.
@return Number of bytes read.
*/
- virtual auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> = 0;
+ virtual auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
+ -> kstd::result<kstd::units::bytes> = 0;
/**
@brief Writes to the inode into a @p buffer, starting at the specified @p offset and for a given @p size. This
@@ -40,7 +40,8 @@ namespace kernel::filesystem
@param size Number of bytes to write.
@return Number of bytes written.
*/
- virtual auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> = 0;
+ virtual auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes> = 0;
/**
@brief Returns whether the inode is a directory.
diff --git a/kernel/kernel/filesystem/open_file_descriptor.cpp b/kernel/kernel/filesystem/open_file_descriptor.cpp
index ecf3e725..6277d0b6 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.cpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.cpp
@@ -5,6 +5,7 @@
#include <kstd/memory.hpp>
#include <kstd/os/error.hpp>
#include <kstd/result.hpp>
+#include <kstd/units.hpp>
#include <cstddef>
@@ -20,7 +21,7 @@ namespace kernel::filesystem
}
}
- auto open_file_descriptor::read(void * buffer, size_t size) -> kstd::result<size_t>
+ auto open_file_descriptor::read(void * buffer, kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
{
if (auto result = m_dentry->get_inode()->read(buffer, m_offset, size); !result)
{
@@ -34,7 +35,7 @@ namespace kernel::filesystem
}
}
- auto open_file_descriptor::write(void const * buffer, size_t size) -> kstd::result<size_t>
+ auto open_file_descriptor::write(void const * buffer, kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
{
if (auto result = m_dentry->get_inode()->write(buffer, m_offset, size); !result)
{
@@ -48,7 +49,7 @@ namespace kernel::filesystem
}
}
- auto open_file_descriptor::offset() const -> size_t
+ auto open_file_descriptor::offset() const -> kstd::units::bytes
{
return m_offset;
}
diff --git a/kernel/kernel/filesystem/open_file_descriptor.hpp b/kernel/kernel/filesystem/open_file_descriptor.hpp
index f6899a31..1ecc09a9 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.hpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.hpp
@@ -5,8 +5,7 @@
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
-
-#include <cstddef>
+#include <kstd/units.hpp>
namespace kernel::filesystem
{
@@ -35,7 +34,7 @@ namespace kernel::filesystem
@param size The number of bytes to read.
@return The number of bytes read.
*/
- auto read(void * buffer, size_t size) -> kstd::result<size_t>;
+ auto read(void * buffer, kstd::units::bytes size) -> 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
@@ -45,13 +44,13 @@ namespace kernel::filesystem
@param size The number of bytes to write.
@return The number of bytes written.
*/
- auto write(void const * buffer, size_t size) -> kstd::result<size_t>;
+ auto write(void const * buffer, kstd::units::bytes size) -> kstd::result<kstd::units::bytes>;
/**
@brief Returns the current file offset for this open file descriptor.
@return The current file offset in bytes.
*/
- [[nodiscard]] auto offset() const -> size_t;
+ [[nodiscard]] auto offset() const -> kstd::units::bytes;
/**
@brief Return a reference to the dentry associated with this open file descriptor.
@@ -61,7 +60,7 @@ namespace kernel::filesystem
private:
kstd::shared_ptr<dentry> m_dentry;
- size_t m_offset;
+ kstd::units::bytes m_offset;
};
} // namespace kernel::filesystem
diff --git a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp
index 67883efd..6653ed86 100644
--- a/kernel/kernel/filesystem/open_file_descriptor.tests.cpp
+++ b/kernel/kernel/filesystem/open_file_descriptor.tests.cpp
@@ -8,6 +8,7 @@
#include <kstd/memory.hpp>
#include <kstd/print.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -16,6 +17,8 @@
#include <filesystem>
#include <string_view>
+using namespace kstd::units_literals;
+
SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor]")
{
GIVEN("a dentry and an open file descriptor for that dentry")
@@ -26,7 +29,7 @@ SCENARIO("Open file descriptor construction", "[filesystem][open_file_descriptor
THEN("the initial offset is zero")
{
- REQUIRE(file_descriptor.offset() == 0);
+ REQUIRE(file_descriptor.offset() == 0_B);
}
}
}
@@ -41,30 +44,30 @@ SCENARIO("Open file descriptor read/write offset management", "[filesystem][open
THEN("the offset is updated correctly after reads")
{
- REQUIRE(file_descriptor.read(nullptr, 100) == 100);
- REQUIRE(file_descriptor.offset() == 100);
- REQUIRE(file_descriptor.read(nullptr, 50) == 50);
- REQUIRE(file_descriptor.offset() == 150);
+ REQUIRE(file_descriptor.read(nullptr, 100_B) == 100_B);
+ REQUIRE(file_descriptor.offset() == 100_B);
+ REQUIRE(file_descriptor.read(nullptr, 50_B) == 50_B);
+ REQUIRE(file_descriptor.offset() == 150_B);
}
THEN("the offset is updated correctly after writes")
{
- REQUIRE(file_descriptor.write(nullptr, 200) == 200);
- REQUIRE(file_descriptor.offset() == 200);
- REQUIRE(file_descriptor.write(nullptr, 25) == 25);
- REQUIRE(file_descriptor.offset() == 225);
+ REQUIRE(file_descriptor.write(nullptr, 200_B) == 200_B);
+ REQUIRE(file_descriptor.offset() == 200_B);
+ REQUIRE(file_descriptor.write(nullptr, 25_B) == 25_B);
+ REQUIRE(file_descriptor.offset() == 225_B);
}
THEN("reads and writes both update the same offset")
{
- REQUIRE(file_descriptor.read(nullptr, 10) == 10);
- REQUIRE(file_descriptor.offset() == 10);
- REQUIRE(file_descriptor.write(nullptr, 20) == 20);
- REQUIRE(file_descriptor.offset() == 30);
- REQUIRE(file_descriptor.read(nullptr, 5) == 5);
- REQUIRE(file_descriptor.offset() == 35);
- REQUIRE(file_descriptor.write(nullptr, 15) == 15);
- REQUIRE(file_descriptor.offset() == 50);
+ REQUIRE(file_descriptor.read(nullptr, 10_B) == 10_B);
+ REQUIRE(file_descriptor.offset() == 10_B);
+ REQUIRE(file_descriptor.write(nullptr, 20_B) == 20_B);
+ REQUIRE(file_descriptor.offset() == 30_B);
+ REQUIRE(file_descriptor.read(nullptr, 5_B) == 5_B);
+ REQUIRE(file_descriptor.offset() == 35_B);
+ REQUIRE(file_descriptor.write(nullptr, 15_B) == 15_B);
+ REQUIRE(file_descriptor.offset() == 50_B);
}
}
}
@@ -87,47 +90,49 @@ 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(), buffer.size());
- REQUIRE(bytes_read == 7);
- REQUIRE(ofd->offset() == 7);
+ auto bytes_read = ofd->read(buffer.data(), kstd::units::bytes{buffer.size()});
+ REQUIRE(bytes_read == 7_B);
+ REQUIRE(ofd->offset() == 7_B);
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), *bytes_read};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), bytes_read->value};
REQUIRE(buffer_as_str == "info_1\n");
}
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(), buffer.size() / 2);
- REQUIRE(bytes_read_1 == buffer.size() / 2);
- REQUIRE(ofd->offset() == buffer.size() / 2);
+ auto bytes_read_1 = ofd->read(buffer.data(), kstd::units::bytes{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, buffer.size() / 2);
- REQUIRE(bytes_read_2 == buffer.size() / 2);
- REQUIRE(ofd->offset() == buffer.size());
+ auto bytes_read_2 = ofd->read(buffer.data() + buffer.size() / 2, kstd::units::bytes{buffer.size() / 2});
+ REQUIRE(bytes_read_2 == kstd::units::bytes{buffer.size() / 2});
+ REQUIRE(ofd->offset() == kstd::units::bytes{buffer.size()});
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), *bytes_read_1 + *bytes_read_2};
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()),
+ bytes_read_1->value + bytes_read_2->value};
REQUIRE(buffer_as_str == "info");
}
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(), write_buffer.size());
- REQUIRE(bytes_written == 12);
- REQUIRE(ofd->offset() == 12);
+ auto const bytes_written = ofd->write(write_buffer.data(), kstd::units::bytes{write_buffer.size()});
+ REQUIRE(bytes_written == 12_B);
+ REQUIRE(ofd->offset() == 12_B);
}
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(), write_buffer.size() / 2);
- REQUIRE(bytes_written_1 == write_buffer.size() / 2);
- REQUIRE(ofd->offset() == write_buffer.size() / 2);
-
- auto const bytes_written_2 = ofd->write(write_buffer.data() + write_buffer.size() / 2, write_buffer.size() / 2);
- REQUIRE(bytes_written_2 == write_buffer.size() / 2);
- REQUIRE(ofd->offset() == write_buffer.size());
+ auto const bytes_written_1 = ofd->write(write_buffer.data(), kstd::units::bytes{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});
+ REQUIRE(bytes_written_2 == kstd::units::bytes{write_buffer.size() / 2});
+ REQUIRE(ofd->offset() == kstd::units::bytes{write_buffer.size()});
}
}
}
diff --git a/kernel/kernel/filesystem/rootfs/inode.cpp b/kernel/kernel/filesystem/rootfs/inode.cpp
index e3e9d641..43aee16e 100644
--- a/kernel/kernel/filesystem/rootfs/inode.cpp
+++ b/kernel/kernel/filesystem/rootfs/inode.cpp
@@ -3,19 +3,18 @@
#include <kernel/filesystem/rootfs/inode.hpp>
#include <kstd/result.hpp>
-
-#include <cstddef>
+#include <kstd/units.hpp>
namespace kernel::filesystem::rootfs
{
- auto inode::read(void *, size_t, size_t) const -> kstd::result<size_t>
+ auto inode::read(void *, kstd::units::bytes, kstd::units::bytes) const -> kstd::result<kstd::units::bytes>
{
- return 0;
+ return kstd::units::bytes{};
}
- auto inode::write(void const *, size_t, size_t) -> kstd::result<size_t>
+ auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes) -> kstd::result<kstd::units::bytes>
{
- return 0;
+ return kstd::units::bytes{};
}
auto inode::is_directory() const -> bool
diff --git a/kernel/kernel/filesystem/rootfs/inode.hpp b/kernel/kernel/filesystem/rootfs/inode.hpp
index 777f13f9..a61e83f1 100644
--- a/kernel/kernel/filesystem/rootfs/inode.hpp
+++ b/kernel/kernel/filesystem/rootfs/inode.hpp
@@ -6,10 +6,9 @@
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/string.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
-#include <cstddef>
-
namespace kernel::filesystem::rootfs
{
/**
@@ -24,7 +23,8 @@ namespace kernel::filesystem::rootfs
@param size Number of bytes requested.
@return Number of bytes read (always 0 because this inode does not expose file data).
*/
- auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
+ auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
+ -> kstd::result<kstd::units::bytes> override;
/**
@brief Writes to the rootfs directory inode.
@@ -33,7 +33,8 @@ namespace kernel::filesystem::rootfs
@param size Number of bytes requested.
@return Number of bytes written (always 0 because writes are not supported for this inode).
*/
- auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
+ auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes> override;
/**
@brief Check if this inode represents a directory.
diff --git a/kernel/kernel/filesystem/rootfs/inode.tests.cpp b/kernel/kernel/filesystem/rootfs/inode.tests.cpp
index 0b48ca71..9819743d 100644
--- a/kernel/kernel/filesystem/rootfs/inode.tests.cpp
+++ b/kernel/kernel/filesystem/rootfs/inode.tests.cpp
@@ -2,10 +2,13 @@
#include <kstd/memory.hpp>
#include <kstd/print.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <catch2/catch_test_macros.hpp>
+using namespace kstd::units_literals;
+
SCENARIO("Rootfs inode read/write", "[filesystem][rootfs][inode]")
{
GIVEN("a rootfs inode")
@@ -15,22 +18,22 @@ 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, buffer.size());
+ auto bytes_read = inode.read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
THEN("no bytes are read")
{
- REQUIRE(bytes_read == 0);
+ REQUIRE(bytes_read == 0_B);
}
}
WHEN("writing to the inode")
{
kstd::vector<char> buffer(10, 'x');
- auto bytes_written = inode.write(buffer.data(), 0, buffer.size());
+ auto bytes_written = inode.write(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
THEN("no bytes are written")
{
- REQUIRE(bytes_written == 0);
+ REQUIRE(bytes_written == 0_B);
}
}
}
diff --git a/kernel/kernel/filesystem/vfs.cpp b/kernel/kernel/filesystem/vfs.cpp
index 9a78b6f8..66faf15a 100644
--- a/kernel/kernel/filesystem/vfs.cpp
+++ b/kernel/kernel/filesystem/vfs.cpp
@@ -16,6 +16,7 @@
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <algorithm>
@@ -26,6 +27,8 @@
#include <string_view>
#include <utility>
+using namespace kstd::units_literals;
+
namespace
{
constinit auto static active_vfs = std::optional<kernel::filesystem::vfs>{};
@@ -337,13 +340,14 @@ namespace kernel::filesystem
}
kstd::vector<uint8_t> buffer(constants::symlink_max_path_length);
- auto const bytes_read = next_dentry->get_inode()->read(buffer.data(), 0, buffer.size());
+ auto const bytes_read = next_dentry->get_inode()->read(buffer.data(), 0_B, kstd::units::bytes{buffer.size()});
if (!bytes_read)
{
return kstd::failure(bytes_read.error());
}
- auto const symbolic_link_path = std::string_view{reinterpret_cast<char const *>(buffer.data()), *bytes_read};
+ auto const symbolic_link_path =
+ std::string_view{reinterpret_cast<char const *>(buffer.data()), bytes_read->value};
auto symbolic_link_parts = path::split(symbolic_link_path);
kstd::vector symbolic_link_parts_vector(symbolic_link_parts.begin(), symbolic_link_parts.end());
diff --git a/kernel/kernel/filesystem/vfs.tests.cpp b/kernel/kernel/filesystem/vfs.tests.cpp
index c70c13c8..5e73db4a 100644
--- a/kernel/kernel/filesystem/vfs.tests.cpp
+++ b/kernel/kernel/filesystem/vfs.tests.cpp
@@ -396,8 +396,8 @@ 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(), buffer.size());
- std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), *bytes_read};
+ auto bytes_read = sheep_1_ofd->read(buffer.data(), kstd::units::bytes{buffer.size()});
+ std::string_view buffer_as_str{reinterpret_cast<char *>(buffer.data()), bytes_read->value};
REQUIRE(buffer_as_str == "sheep_1");
REQUIRE(vfs.close(dentry.value()->absolute_path()));
@@ -423,13 +423,13 @@ 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(), sheep_buffer.size());
- std::string_view buffer_as_str{reinterpret_cast<char *>(sheep_buffer.data()), *bytes_read};
+ auto bytes_read = sheep_1_ofd->read(sheep_buffer.data(), kstd::units::bytes{sheep_buffer.size()});
+ 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(), goat_buffer.size());
- buffer_as_str = std::string_view{reinterpret_cast<char *>(goat_buffer.data()), *bytes_read};
+ bytes_read = goat_1_ofd->read(goat_buffer.data(), kstd::units::bytes{goat_buffer.size()});
+ buffer_as_str = std::string_view{reinterpret_cast<char *>(goat_buffer.data()), bytes_read->value};
REQUIRE(buffer_as_str == "goat_1");
REQUIRE(vfs.close(sheep_1.value()->absolute_path()));
diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp
index 525e25c4..366fcc26 100644
--- a/kernel/kernel/main.cpp
+++ b/kernel/kernel/main.cpp
@@ -40,7 +40,7 @@ auto run_demo() -> void
// 2) read from the file
kstd::vector<std::byte> buffer_1{10};
- auto bytes_read = *kapi::filesystem::read(fd_1.value(), buffer_1);
+ auto bytes_read = kapi::filesystem::read(fd_1.value(), buffer_1)->value;
auto buffer_as_str = std::string_view{reinterpret_cast<char *>(buffer_1.data()), bytes_read};
kstd::println("--> read {} bytes from /entrance/tickets.txt: {}", bytes_read, buffer_as_str);
kstd::println("");
@@ -79,7 +79,7 @@ auto run_demo() -> void
// 6) read from the new file
kstd::vector<std::byte> buffer_2{10};
- bytes_read = *kapi::filesystem::read(fd_2.value(), buffer_2);
+ bytes_read = kapi::filesystem::read(fd_2.value(), buffer_2)->value;
buffer_as_str = std::string_view{reinterpret_cast<char *>(buffer_2.data()), static_cast<size_t>(bytes_read)};
kstd::println("--> read {} bytes from /entrance/information/info_1.txt: {} ", bytes_read, buffer_as_str);
@@ -97,13 +97,13 @@ auto run_demo() -> void
// 8) read from the device file
kstd::vector<std::byte> buffer_3{2};
- bytes_read = *kapi::filesystem::read(fd_3.value(), buffer_3);
+ bytes_read = kapi::filesystem::read(fd_3.value(), buffer_3)->value;
kstd::println("--> read {} bytes from /dev/ram2: {::#04x} ", bytes_read, buffer_3);
// 9) write to the device file
auto const default_buffer_value = std::byte{0xAA};
kstd::vector<std::byte> write_buffer{default_buffer_value, default_buffer_value};
- auto bytes_written = *kapi::filesystem::write(fd_3.value(), write_buffer);
+ auto bytes_written = kapi::filesystem::write(fd_3.value(), write_buffer)->value;
kstd::println("--> written {} bytes to /dev/ram2: {::#04x}", bytes_written, write_buffer);
// 10) do memory dump to show that the write to the device file had an effect
@@ -135,7 +135,7 @@ auto run_demo() -> void
kstd::vector<std::byte> test_write_buffer{
std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'}, std::byte{'o'}, std::byte{' '}, std::byte{'T'},
std::byte{'e'}, std::byte{'a'}, std::byte{'c'}, std::byte{'h'}, std::byte{'O'}, std::byte{'S'}};
- bytes_written = *kapi::filesystem::write(*fd_4, test_write_buffer);
+ bytes_written = kapi::filesystem::write(*fd_4, test_write_buffer)->value;
kstd::println("--> written {} bytes to /test_files/test_file.txt: {::#04x}", bytes_written, test_write_buffer);
// 14) dmp the module after create new directory and file
diff --git a/kernel/kernel/test_support/devices/block_device.cpp b/kernel/kernel/test_support/devices/block_device.cpp
index 2dda5dec..cb80370b 100644
--- a/kernel/kernel/test_support/devices/block_device.cpp
+++ b/kernel/kernel/test_support/devices/block_device.cpp
@@ -2,7 +2,9 @@
#include <kernel/devices/block_device.hpp>
+#include <kstd/result.hpp>
#include <kstd/string.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <algorithm>
@@ -11,13 +13,15 @@
#include <cstring>
#include <string.h>
+using namespace kstd::units_literals;
+
namespace kernel::tests::devices
{
- block_device::block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size,
- size_t initial_size)
+ block_device::block_device(size_t major, size_t minor, kstd::string const & name, kstd::units::bytes block_size,
+ kstd::units::bytes initial_size)
: kernel::devices::block_device(major, minor, name, block_size)
{
- data.resize(initial_size, 0);
+ data.resize(initial_size.value, 0);
}
auto block_device::init() -> bool
@@ -25,37 +29,41 @@ namespace kernel::tests::devices
return true;
}
- auto block_device::read_block(size_t block_index, void * buffer) const -> void
+ auto block_device::read_block(size_t block_index, void * buffer) const -> kstd::result<kstd::units::bytes>
{
auto const offset = block_index * block_size();
- if (offset >= data.size())
+ if (offset.value >= data.size())
{
- kstd::libc::memset(buffer, 0, block_size());
- return;
+ kstd::libc::memset(buffer, 0, block_size().value);
+ return 0_B;
}
- auto const bytes_to_read = std::min(block_size(), data.size() - offset);
- kstd::libc::memcpy(buffer, data.data() + offset, bytes_to_read);
+ 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);
if (bytes_to_read < block_size())
{
- kstd::libc::memset(static_cast<uint8_t *>(buffer) + bytes_to_read, 0, block_size() - bytes_to_read);
+ kstd::libc::memset(static_cast<uint8_t *>(buffer) + 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) -> void
+ auto block_device::write_block(size_t block_index, void const * buffer) -> kstd::result<kstd::units::bytes>
{
auto const offset = block_index * block_size();
auto const write_end = offset + block_size();
- if (write_end > data.size())
+ if (write_end.value > data.size())
{
- data.resize(write_end, 0);
+ data.resize(write_end.value, 0);
}
- kstd::libc::memcpy(data.data() + offset, static_cast<uint8_t const *>(buffer), block_size());
+ kstd::libc::memcpy(data.data() + offset, static_cast<uint8_t const *>(buffer), block_size().value);
+ return block_size();
}
- auto block_device::size() const -> size_t
+ auto block_device::size() const -> kstd::units::bytes
{
- return data.size();
+ return kstd::units::bytes{data.size()};
}
} // namespace kernel::tests::devices \ No newline at end of file
diff --git a/kernel/kernel/test_support/devices/block_device.hpp b/kernel/kernel/test_support/devices/block_device.hpp
index d83dddd1..147c117c 100644
--- a/kernel/kernel/test_support/devices/block_device.hpp
+++ b/kernel/kernel/test_support/devices/block_device.hpp
@@ -3,7 +3,9 @@
#include <kernel/devices/block_device.hpp>
+#include <kstd/result.hpp>
#include <kstd/string.hpp>
+#include <kstd/units.hpp>
#include <kstd/vector.hpp>
#include <cstddef>
@@ -14,14 +16,15 @@ namespace kernel::tests::devices
struct block_device : kernel::devices::block_device
{
- block_device(size_t major, size_t minor, kstd::string const & name, size_t block_size, size_t initial_size = 0);
+ block_device(size_t major, size_t minor, kstd::string const & name, kstd::units::bytes block_size,
+ kstd::units::bytes initial_size = {});
auto init() -> bool override;
- auto read_block(size_t block_index, void * buffer) const -> void override;
- auto write_block(size_t block_index, void const * buffer) -> void override;
+ 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;
- [[nodiscard]] auto size() const -> size_t override;
+ [[nodiscard]] auto size() const -> kstd::units::bytes override;
kstd::vector<uint8_t> data{};
};
diff --git a/kernel/kernel/test_support/filesystem/ext2.cpp b/kernel/kernel/test_support/filesystem/ext2.cpp
index 3a7449ed..ff01cbb2 100644
--- a/kernel/kernel/test_support/filesystem/ext2.cpp
+++ b/kernel/kernel/test_support/filesystem/ext2.cpp
@@ -6,9 +6,12 @@
#include <kernel/filesystem/ext2/superblock.hpp>
#include <kernel/test_support/devices/block_device.hpp>
+#include <kstd/units.hpp>
+
#include <cstdint>
#include <cstring>
-#include <vector>
+
+using namespace kstd::units_literals;
namespace kernel::tests::filesystem::ext2
{
@@ -17,21 +20,21 @@ namespace kernel::tests::filesystem::ext2
constexpr uint32_t root_directory_data_block = 20;
} // namespace
- auto write_bytes(kernel::tests::devices::block_device & device, size_t offset, void const * source, size_t size)
- -> void
+ auto write_bytes(kernel::tests::devices::block_device & device, kstd::units::bytes offset, void const * source,
+ kstd::units::bytes size) -> void
{
auto const required_size = offset + size;
- if (device.data.size() < required_size)
+ if (kstd::units::bytes{device.data.size()} < required_size)
{
- device.data.resize(required_size, 0);
+ device.data.resize(required_size.value, 0);
}
- std::memcpy(device.data.data() + offset, source, size);
+ std::memcpy(device.data.data() + offset, source, size.value);
}
- auto write_u32(kernel::tests::devices::block_device & device, size_t offset, uint32_t value) -> void
+ auto write_u32(kernel::tests::devices::block_device & device, kstd::units::bytes offset, uint32_t value) -> void
{
- write_bytes(device, offset, &value, sizeof(value));
+ write_bytes(device, offset, &value, kstd::object_size(value));
}
auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device) -> void
@@ -60,8 +63,9 @@ namespace kernel::tests::filesystem::ext2
kernel::filesystem::ext2::superblock const & superblock,
kernel::filesystem::ext2::block_group_descriptor const & group_descriptor) -> void
{
- write_bytes(device, kernel::filesystem::ext2::constants::superblock_offset, &superblock, sizeof(superblock));
- write_bytes(device, 2048, &group_descriptor, sizeof(group_descriptor));
+ write_bytes(device, kernel::filesystem::ext2::constants::superblock_offset, &superblock,
+ kstd::object_size(superblock));
+ write_bytes(device, 2048_B, &group_descriptor, kstd::object_size(group_descriptor));
auto root_inode_data = kernel::filesystem::ext2::inode_data{};
root_inode_data.mode = kernel::filesystem::ext2::constants::mode_directory;
@@ -70,7 +74,7 @@ namespace kernel::tests::filesystem::ext2
auto const root_inode_offset =
static_cast<size_t>(group_descriptor.inode_table) * kernel::filesystem::ext2::constants::base_block_size +
- (kernel::filesystem::ext2::constants::root_inode_number - 1) * superblock.inode_size;
- write_bytes(device, root_inode_offset, &root_inode_data, sizeof(root_inode_data));
+ (kernel::filesystem::ext2::constants::root_inode_number - 1) * kstd::units::bytes{superblock.inode_size};
+ write_bytes(device, root_inode_offset, &root_inode_data, kstd::object_size(root_inode_data));
}
} // namespace kernel::tests::filesystem::ext2 \ No newline at end of file
diff --git a/kernel/kernel/test_support/filesystem/ext2.hpp b/kernel/kernel/test_support/filesystem/ext2.hpp
index 3dd80ea3..a8f73ab5 100644
--- a/kernel/kernel/test_support/filesystem/ext2.hpp
+++ b/kernel/kernel/test_support/filesystem/ext2.hpp
@@ -5,14 +5,15 @@
#include <kernel/filesystem/ext2/superblock.hpp>
#include <kernel/test_support/devices/block_device.hpp>
-#include <cstddef>
+#include <kstd/units.hpp>
+
#include <cstdint>
namespace kernel::tests::filesystem::ext2
{
- auto write_bytes(kernel::tests::devices::block_device & device, size_t offset, void const * source, size_t size)
- -> void;
- auto write_u32(kernel::tests::devices::block_device & device, size_t offset, uint32_t value) -> void;
+ auto write_bytes(kernel::tests::devices::block_device & device, kstd::units::bytes offset, void const * source,
+ kstd::units::bytes size) -> void;
+ auto write_u32(kernel::tests::devices::block_device & device, kstd::units::bytes offset, uint32_t value) -> void;
auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device) -> void;
auto setup_mock_ext2_layout(kernel::tests::devices::block_device & device,
kernel::filesystem::ext2::superblock const & superblock) -> void;
diff --git a/kernel/kernel/test_support/filesystem/inode.cpp b/kernel/kernel/test_support/filesystem/inode.cpp
index fd8e4d69..1d090589 100644
--- a/kernel/kernel/test_support/filesystem/inode.cpp
+++ b/kernel/kernel/test_support/filesystem/inode.cpp
@@ -3,17 +3,16 @@
#include <kernel/filesystem/inode.hpp>
#include <kstd/result.hpp>
-
-#include <cstddef>
+#include <kstd/units.hpp>
namespace kernel::tests::filesystem
{
- auto inode::read(void *, size_t, size_t size) const -> kstd::result<size_t>
+ auto inode::read(void *, kstd::units::bytes, kstd::units::bytes size) const -> kstd::result<kstd::units::bytes>
{
return size;
}
- auto inode::write(void const *, size_t, size_t size) -> kstd::result<size_t>
+ auto inode::write(void const *, kstd::units::bytes, kstd::units::bytes size) -> kstd::result<kstd::units::bytes>
{
return size;
}
diff --git a/kernel/kernel/test_support/filesystem/inode.hpp b/kernel/kernel/test_support/filesystem/inode.hpp
index da2e3e21..d2fbf19d 100644
--- a/kernel/kernel/test_support/filesystem/inode.hpp
+++ b/kernel/kernel/test_support/filesystem/inode.hpp
@@ -4,15 +4,16 @@
#include <kernel/filesystem/inode.hpp>
#include <kstd/result.hpp>
-
-#include <cstddef>
+#include <kstd/units.hpp>
namespace kernel::tests::filesystem
{
struct inode : kernel::filesystem::inode
{
- auto read(void * buffer, size_t offset, size_t size) const -> kstd::result<size_t> override;
- auto write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> override;
+ auto read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
+ -> kstd::result<kstd::units::bytes> override;
+ auto write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
+ -> kstd::result<kstd::units::bytes> override;
[[nodiscard]] auto is_regular() const -> bool override;
};