aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Braun <marcel.braun@ost.ch>2026-06-02 15:02:01 +0200
committerMarcel Braun <marcel.braun@ost.ch>2026-06-02 15:02:01 +0200
commite92df52c599f78f36a278508a2b6be5f3a15f3db (patch)
tree64823890d38038cdc207cfc3323d96d00843442f
parent0ab7525951b0116241f393090987bedc07a18c33 (diff)
parentf26569c6a4e5f0ed61b7efa81ebdddd532d542c5 (diff)
downloadkernel-e92df52c599f78f36a278508a2b6be5f3a15f3db.tar.xz
kernel-e92df52c599f78f36a278508a2b6be5f3a15f3db.zip
Merge branch 'refactor-map-inode-block-to-global-block-number' into 'develop-BA-FS26'
refactor and simplify mapping logic See merge request teachos/kernel!45
-rw-r--r--kernel/include/kernel/filesystem/ext2/filesystem.hpp16
-rw-r--r--kernel/src/filesystem/ext2/filesystem.cpp100
2 files changed, 47 insertions, 69 deletions
diff --git a/kernel/include/kernel/filesystem/ext2/filesystem.hpp b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
index d5e5b8b..2284d7b 100644
--- a/kernel/include/kernel/filesystem/ext2/filesystem.hpp
+++ b/kernel/include/kernel/filesystem/ext2/filesystem.hpp
@@ -11,6 +11,7 @@
#include <kstd/unikstd.h>
#include <kstd/vector>
+#include <array>
#include <cstddef>
#include <cstdint>
#include <string_view>
@@ -86,16 +87,17 @@ namespace kernel::filesystem::ext2
-> kstd::ssize_t;
private:
+ struct indirect_level
+ {
+ uint32_t slot_index;
+ size_t capacity;
+ };
+
+ [[nodiscard]] auto indirect_levels() const -> std::array<indirect_level, 3>;
+
[[nodiscard]] auto read_inode(uint32_t inode_number) const -> kstd::shared_ptr<kernel::filesystem::ext2::inode>;
[[nodiscard]] auto read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t;
- [[nodiscard]] auto read_singly_indirect_block_number(uint32_t singly_indirect_block_number,
- size_t block_index_in_singly_indirect_block) const -> size_t;
- [[nodiscard]] auto read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number,
- size_t block_index_in_doubly_indirect_block) const -> size_t;
- [[nodiscard]] auto read_triply_indirect_block_number(uint32_t triply_indirect_block_number,
- size_t block_index_in_triply_indirect_block) const -> size_t;
-
[[nodiscard]] auto inode_size() const -> uint16_t;
[[nodiscard]] auto inode_block_count(inode_data const & data) const -> uint32_t;
[[nodiscard]] auto block_group_descriptor_table_offset() const -> size_t;
diff --git a/kernel/src/filesystem/ext2/filesystem.cpp b/kernel/src/filesystem/ext2/filesystem.cpp
index a30149e..12aeaaa 100644
--- a/kernel/src/filesystem/ext2/filesystem.cpp
+++ b/kernel/src/filesystem/ext2/filesystem.cpp
@@ -11,6 +11,7 @@
#include <kstd/unikstd.h>
#include <kstd/vector>
+#include <array>
#include <cstddef>
#include <cstdint>
#include <string_view>
@@ -109,6 +110,15 @@ namespace kernel::filesystem::ext2
return kstd::make_shared<inode>(this, new_inode_data);
}
+ auto filesystem::indirect_levels() const -> std::array<indirect_level, 3>
+ {
+ return {
+ {{constants::singly_indirect_block_index, block_numbers_per_singly_indirect_block()},
+ {constants::doubly_indirect_block_index, block_numbers_per_doubly_indirect_block()},
+ {constants::triply_indirect_block_index, block_numbers_per_triply_indirect_block()}}
+ };
+ }
+
auto filesystem::map_inode_block_index_to_global_block_number(size_t inode_block_index, inode_data data) const
-> kstd::ssize_t
{
@@ -116,78 +126,44 @@ namespace kernel::filesystem::ext2
{
return data.block.at(inode_block_index);
}
- inode_block_index -= constants::direct_block_count;
-
- if (inode_block_index < block_numbers_per_singly_indirect_block())
- {
- auto const singly_indirect_block_number = data.block.at(constants::singly_indirect_block_index);
- return read_singly_indirect_block_number(singly_indirect_block_number, inode_block_index);
- }
- inode_block_index -= block_numbers_per_singly_indirect_block();
-
- if (inode_block_index < block_numbers_per_doubly_indirect_block())
- {
- auto const doubly_indirect_block_number = data.block.at(constants::doubly_indirect_block_index);
- return read_doubly_indirect_block_number(doubly_indirect_block_number, inode_block_index);
- }
- inode_block_index -= block_numbers_per_doubly_indirect_block();
- if (inode_block_index < block_numbers_per_triply_indirect_block())
- {
- auto const triply_indirect_block_number = data.block.at(constants::triply_indirect_block_index);
- return read_triply_indirect_block_number(triply_indirect_block_number, inode_block_index);
- }
-
- return -1;
- }
+ inode_block_index -= constants::direct_block_count;
- auto filesystem::read_singly_indirect_block_number(uint32_t singly_indirect_block_number,
- size_t block_index_in_singly_indirect_block) const -> size_t
- {
- if (singly_indirect_block_number == 0)
+ for (auto const & level : indirect_levels())
{
- return 0;
- }
-
- return read_block_number_at_index(singly_indirect_block_number, block_index_in_singly_indirect_block);
- }
+ if (inode_block_index >= level.capacity)
+ {
+ inode_block_index -= level.capacity;
+ continue;
+ }
- auto filesystem::read_doubly_indirect_block_number(uint32_t doubly_indirect_block_number,
- size_t block_index_in_doubly_indirect_block) const -> size_t
- {
- if (doubly_indirect_block_number == 0)
- {
- return 0;
- }
+ auto block_number = data.block[level.slot_index];
+ if (block_number == 0)
+ {
+ return 0;
+ }
- auto const singly_indirect_block_index_in_doubly_indirect_block =
- block_index_in_doubly_indirect_block / block_numbers_per_singly_indirect_block();
- auto const block_index_in_singly_indirect_block =
- block_index_in_doubly_indirect_block % block_numbers_per_singly_indirect_block();
+ for (auto stride = level.capacity / block_numbers_per_block();; stride /= block_numbers_per_block())
+ {
+ auto const idx = inode_block_index / stride;
+ inode_block_index %= stride;
- auto const singly_indirect_block_number =
- read_block_number_at_index(doubly_indirect_block_number, singly_indirect_block_index_in_doubly_indirect_block);
+ block_number = read_block_number_at_index(block_number, idx);
+ if (block_number == 0)
+ {
+ return 0;
+ }
- return read_singly_indirect_block_number(singly_indirect_block_number, block_index_in_singly_indirect_block);
- }
+ if (stride == 1)
+ {
+ break;
+ }
+ }
- auto filesystem::read_triply_indirect_block_number(uint32_t triply_indirect_block_number,
- size_t block_index_in_triply_indirect_block) const -> size_t
- {
- if (triply_indirect_block_number == 0)
- {
- return 0;
+ return block_number;
}
- auto const doubly_indirect_block_index_in_triply_indirect_block =
- block_index_in_triply_indirect_block / block_numbers_per_doubly_indirect_block();
- auto const block_index_in_doubly_indirect_block =
- block_index_in_triply_indirect_block % block_numbers_per_doubly_indirect_block();
-
- auto const doubly_indirect_block_number =
- read_block_number_at_index(triply_indirect_block_number, doubly_indirect_block_index_in_triply_indirect_block);
-
- return read_doubly_indirect_block_number(doubly_indirect_block_number, block_index_in_doubly_indirect_block);
+ return -1;
}
auto filesystem::read_block_number_at_index(uint32_t block_number, size_t index) const -> uint32_t