From 18d80c9159424014f204fb1b2545405eeea9221f Mon Sep 17 00:00:00 2001 From: Marcel Braun Date: Sat, 30 May 2026 10:10:15 +0200 Subject: Implement ext2 inode write --- kernel/kernel/filesystem/ext2/inode.cpp | 41 +++++++++++++++++++++++++-- kernel/kernel/filesystem/ext2/inode.tests.cpp | 15 ---------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/kernel/kernel/filesystem/ext2/inode.cpp b/kernel/kernel/filesystem/ext2/inode.cpp index 6dadbec5..e873d446 100644 --- a/kernel/kernel/filesystem/ext2/inode.cpp +++ b/kernel/kernel/filesystem/ext2/inode.cpp @@ -76,10 +76,45 @@ namespace kernel::filesystem::ext2 return bytes_read; } - auto inode::write(void const *, size_t, size_t) -> kstd::result + auto inode::write(void const * buffer, size_t offset, size_t size) -> kstd::result { - kapi::system::panic("[EXT2] inode::write is not implemented yet"); - return 0; + auto const max_writable = this->size() - offset; + auto const requested_size = std::min(size, max_writable); + + auto block_index = offset / m_filesystem->block_size(); + auto in_block_offset = offset % m_filesystem->block_size(); + + auto bytes_written = 0uz; + + while (bytes_written < requested_size) + { + auto const block_number = m_filesystem->map_inode_block_index_to_global_block_number(block_index, m_data); + // TODO BA-FS26 if blocknumber == 0 --> handle sparse file + if (!block_number) + { + kstd::failure(block_number.error()); + } + + auto const bytes_to_write = + std::min(requested_size - bytes_written, m_filesystem->block_size() - in_block_offset); + + auto const block_start_offset = block_number.value() * m_filesystem->block_size(); + auto const write_offset = block_start_offset + in_block_offset; + + auto const write_result = m_filesystem->backing_inode()->write( + static_cast(buffer) + bytes_written, write_offset, bytes_to_write); + if (!write_result) + { + return kstd::failure(write_result.error()); + } + + bytes_written += write_result.value(); + + block_index++; + in_block_offset = 0; // After the first block, we always start at the beginning of the block + } + + return bytes_written; } [[nodiscard]] auto inode::data() const -> inode_data const & diff --git a/kernel/kernel/filesystem/ext2/inode.tests.cpp b/kernel/kernel/filesystem/ext2/inode.tests.cpp index 496e7c4f..7041f886 100644 --- a/kernel/kernel/filesystem/ext2/inode.tests.cpp +++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp @@ -277,21 +277,6 @@ SCENARIO("Ext2 inode read across block boundaries", "[filesystem][ext2][inode]") } } -SCENARIO("Ext2 inode write is not implemented", "[filesystem][ext2][inode]") -{ - GIVEN("an ext2 inode") - { - auto fs = kernel::filesystem::ext2::filesystem{}; - auto inode = kernel::filesystem::ext2::inode{&fs, kernel::filesystem::ext2::inode_data{}}; - - THEN("writing to the inode panics") - { - auto buffer = kstd::vector(32, std::byte{0x00}); - REQUIRE_THROWS_AS(inode.write(buffer.data(), 0, buffer.size()), kernel::tests::cpu::halt); - } - } -} - SCENARIO("Ext2 inode get_size() correctly returns size depending on revision level", "[filesystem][ext2][inode]") { auto const block_size = 1024uz; -- cgit v1.2.3