aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Oesch <lukasoesch20@gmail.com>2026-05-30 21:48:42 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-07-14 20:02:54 +0200
commitc63737704b8e9b275d9f2c09c9c8a2904230846d (patch)
treedf02addb099a641ea4dc2ef8783045d307345f7a
parent071a6ba4643eccc1ac466ae1e96e8fed6f3e9f9e (diff)
downloadkernel-c63737704b8e9b275d9f2c09c9c8a2904230846d.tar.xz
kernel-c63737704b8e9b275d9f2c09c9c8a2904230846d.zip
add inode tests
-rw-r--r--kernel/kernel/filesystem/ext2/filesystem.hpp2
-rw-r--r--kernel/kernel/filesystem/ext2/inode.tests.cpp77
2 files changed, 69 insertions, 10 deletions
diff --git a/kernel/kernel/filesystem/ext2/filesystem.hpp b/kernel/kernel/filesystem/ext2/filesystem.hpp
index 7361943a..f440d4dc 100644
--- a/kernel/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/kernel/filesystem/ext2/filesystem.hpp
@@ -90,6 +90,7 @@ namespace kernel::filesystem::ext2
auto write_inode(uint32_t inode_number, inode_data const & data) -> kstd::result<void>;
+ [[nodiscard]] auto inode_size() const -> uint16_t;
/**
@brief Maps an inode block index to a global block number.
@param inode_block_index The index of the block within the inode.
@@ -116,7 +117,6 @@ namespace kernel::filesystem::ext2
auto ensure_and_get_block(uint32_t & block_number) -> bool;
- [[nodiscard]] auto inode_size() const -> uint16_t;
[[nodiscard]] auto block_group_descriptor_table_offset() const -> size_t;
[[nodiscard]] auto block_numbers_per_block() const -> size_t;
diff --git a/kernel/kernel/filesystem/ext2/inode.tests.cpp b/kernel/kernel/filesystem/ext2/inode.tests.cpp
index 752d17d7..90274f6f 100644
--- a/kernel/kernel/filesystem/ext2/inode.tests.cpp
+++ b/kernel/kernel/filesystem/ext2/inode.tests.cpp
@@ -359,7 +359,7 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
auto block_bitmap = std::vector<std::byte>(block_size, std::byte{0x00});
block_bitmap[0] = std::byte{0b1111'1111};
block_bitmap[1] = std::byte{0b1111'1111};
- block_bitmap[2] = std::byte{0b0001'1000};
+ block_bitmap[2] = std::byte{0b0011'0000};
dev_inode->write(block_bitmap.data(), block_group_descriptor.block_bitmap * block_size, block_size);
@@ -374,15 +374,47 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
inode_data.mode = kernel::filesystem::ext2::constants::mode_regular;
uint32_t inode_number = 3;
+ 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};
- dev_inode->write(&inode, inode_number * block_size, sizeof(kernel::filesystem::ext2::inode_data));
+ dev_inode->write(&inode, inode_data_offset, sizeof(kernel::filesystem::ext2::inode_data));
- THEN("writing over block boundaries updates backing device no additional blocks allocated")
+ auto buffer = kstd::vector<std::byte>{std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'},
+ std::byte{'o'}, std::byte{' '}, std::byte{'W'}, std::byte{'o'},
+ std::byte{'r'}, std::byte{'l'}, std::byte{'d'}, std::byte{'!'}};
+
+ auto do_read_inode = [&]() {
+ auto inode_data = kernel::filesystem::ext2::inode_data{};
+ dev_inode->read(&inode_data, inode_data_offset, sizeof(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 buffer = kstd::vector<std::byte>{std::byte{'H'}, std::byte{'e'}, std::byte{'l'}, std::byte{'l'},
- std::byte{'o'}, std::byte{' '}, std::byte{'W'}, std::byte{'o'},
- std::byte{'r'}, std::byte{'l'}, std::byte{'d'}, std::byte{'!'}};
+ auto const expected_bytes_written = 3;
+ auto const bytes_written = inode.write(buffer.data(), 0, 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});
+ 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.blocks == read_inode.data().blocks);
+
+ auto const current_blocks = inode_data.block;
+ auto const read_blocks = read_inode.data().block;
+ REQUIRE(current_blocks == read_blocks);
+ }
+ THEN("writing over block boundaries updates backing device no additional blocks allocated")
+ {
auto const offset = block_size - 4;
auto const bytes_written = inode.write(buffer.data(), offset, buffer.size());
REQUIRE(bytes_written == buffer.size());
@@ -395,15 +427,42 @@ SCENARIO("Ext2 inode write across block boundaries", "[filesystem][ext2][inode]"
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 = kernel::filesystem::ext2::inode{&fs, inode_number, {}};
- dev_inode->read(&read_inode, inode_number * block_size, sizeof(kernel::filesystem::ext2::inode));
- REQUIRE(offset + 12 == inode.size());
+ auto read_inode = do_read_inode();
+ REQUIRE(offset + buffer.size() == read_inode.size());
REQUIRE(inode_data.blocks == read_inode.data().blocks);
auto const current_blocks = inode_data.block;
auto const read_blocks = read_inode.data().block;
REQUIRE(current_blocks == read_blocks);
}
+
+ THEN("writing over the current size and over allocated blocks updates backing device 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 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};
+ REQUIRE(text == "Hello World!");
+
+ auto read_block_bitmap = std::vector<std::byte>(block_size, std::byte{0x00});
+ dev_inode->read(read_block_bitmap.data(), block_group_descriptor.block_bitmap * block_size, block_size);
+
+ auto expected_block_bitmap = block_bitmap;
+ expected_block_bitmap[2] = std::byte{0b0011'0001};
+ REQUIRE(expected_block_bitmap == read_block_bitmap);
+
+ auto read_inode = do_read_inode();
+ REQUIRE(offset + buffer.size() == read_inode.size());
+ REQUIRE(inode_data.blocks + 2 == read_inode.data().blocks);
+
+ auto expected_blocks = inode_data.block;
+ expected_blocks[2] = 16;
+ auto const read_blocks = read_inode.data().block;
+ REQUIRE(expected_blocks == read_blocks);
+ }
}
}