:: commit 9459207ab3e232a6c5053fc88a1ac192db4da06c

mintsuki <mintsuki@protonmail.com> — 2021-09-07 08:35

parents: 3dbd494f87

ext2: Implement triply indirect blocks

diff --git a/stage23/fs/ext2.s2.c b/stage23/fs/ext2.s2.c
index 7f429a74..8faa5a6d 100644
--- a/stage23/fs/ext2.s2.c
+++ b/stage23/fs/ext2.s2.c
@@ -178,16 +178,28 @@ static uint32_t *create_alloc_map(struct ext2_file_handle *fd,
                 // Double indirect block
                 block -= entries_per_block;
                 uint32_t index = block / entries_per_block;
+                uint32_t indirect_block;
                 if (index >= entries_per_block) {
-                    // Triple indirect block
-                    panic("ext2: triply indirect blocks unsupported");
+                    uint32_t first_index = index / entries_per_block;
+                    uint32_t first_indirect_block;
+                    volume_read(
+                        fd->part, &first_indirect_block,
+                        inode->i_blocks[14] * fd->block_size + first_index * sizeof(uint32_t),
+                        sizeof(uint32_t)
+                    );
+                    uint32_t second_index = index % entries_per_block;
+                    volume_read(
+                        fd->part, &indirect_block,
+                        first_indirect_block * fd->block_size + second_index * sizeof(uint32_t),
+                        sizeof(uint32_t)
+                    );
+                } else {
+                    volume_read(
+                        fd->part, &indirect_block,
+                        inode->i_blocks[13] * fd->block_size + index * sizeof(uint32_t),
+                        sizeof(uint32_t)
+                    );
                 }
-                uint32_t indirect_block;
-                volume_read(
-                    fd->part, &indirect_block,
-                    inode->i_blocks[13] * fd->block_size + index * sizeof(uint32_t),
-                    sizeof(uint32_t)
-                );
                 for (uint32_t j = 0; j < entries_per_block; j++) {
                     if (i + j >= inode->i_blocks_count)
                         return alloc_map;
tab: 248 wrap: offon