aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kernel/filesystem/ext2/inode.cpp41
-rw-r--r--kernel/kernel/filesystem/ext2/inode.tests.cpp15
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;