diff options
| author | Marcel Braun <marcel.braun@ost.ch> | 2026-05-30 10:10:15 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-07-14 19:43:49 +0200 |
| commit | 18d80c9159424014f204fb1b2545405eeea9221f (patch) | |
| tree | 27f3f57a12d7d7b0c3a77ccd0371ad1533b3106a /kernel | |
| parent | d6735726d9cc6e98142e94001250076592279d36 (diff) | |
| download | kernel-18d80c9159424014f204fb1b2545405eeea9221f.tar.xz kernel-18d80c9159424014f204fb1b2545405eeea9221f.zip | |
Implement ext2 inode write
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kernel/filesystem/ext2/inode.cpp | 41 | ||||
| -rw-r--r-- | 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<size_t> + auto inode::write(void const * buffer, size_t offset, size_t size) -> kstd::result<size_t> { - 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<uint8_t const *>(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<std::byte>(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; |
