[SLOF] [PATCH slof 08/10] ext2/4: Add basic extent tree support

Alexey Kardashevskiy aik at ozlabs.ru
Tue Dec 31 14:04:55 AEDT 2019


This allows booting from ext4 filesystems when EXT4_EXTENTS_FL is set in
inode.

Based on:
https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout

Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
---
 slof/fs/packages/ext2-files.fs | 56 ++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/slof/fs/packages/ext2-files.fs b/slof/fs/packages/ext2-files.fs
index 75cd01e23705..672f0b482157 100644
--- a/slof/fs/packages/ext2-files.fs
+++ b/slof/fs/packages/ext2-files.fs
@@ -75,6 +75,61 @@ INSTANCE VARIABLE #blocks-left
 ;
 
 : inode-i-block ( inode -- block ) 28 + ;
+80000 CONSTANT EXT4_EXTENTS_FL
+: inode-i-flags ( inode -- i_flags ) 20 + l at -le ;
+F30A CONSTANT EXT4_EH_MAGIC
+: extent-tree-entries ( iblock -- entries ) C + ;
+
+STRUCT
+   2 field ext4_eh>magic
+   2 field ext4_eh>entries
+   2 field ext4_eh>max
+   2 field ext4_eh>depth
+   4 field ext4_eh>generation
+CONSTANT /ext4_eh
+
+STRUCT
+   4 field ext4-ee>block
+   2 field ext4-ee>len
+   2 field ext4-ee>start_hi
+   4 field ext4-ee>start_lo
+CONSTANT /ext4-ee
+
+: ext4-ee-start ( entries -- ee-start )
+    dup ext4-ee>start_hi w at -le 32 lshift
+    swap
+    ext4-ee>start_lo l at -le or
+;
+
+: expand-blocks ( start len -- )
+    bounds
+    ?DO
+        i ^blocks @ l!-le
+        1 blocks-read
+    1 +LOOP
+;
+
+\ [0x28..0x34] ext4_extent_header
+\ [0x34..0x64] ext4_extent_idx[eh_entries if eh_depth > 0] (not supported)
+\              ext4_extent[eh_entries if eh_depth == 0]
+: read-extent-tree ( inode -- )
+    inode-i-block
+    dup ext4_eh>magic w at -le EXT4_EH_MAGIC <> IF ." BAD extent tree magic" cr EXIT THEN
+    dup ext4_eh>depth w at -le 0 <> IF ." Root inode is not lead, not supported" cr EXIT THEN
+    \ depth=0 means it is a leaf and entries are ext4_extent[eh_entries]
+    dup ext4_eh>entries w at -le
+    >r
+    /ext4_eh +
+    r>
+    0
+    DO
+        dup ext4-ee-start
+        over ext4-ee>len w at -le ( ext4_extent^ start len )
+        expand-blocks
+        /ext4-ee +
+    LOOP
+    drop
+;
 
 \ Reads block numbers into blocks
 : read-block#s ( -- )
@@ -83,6 +138,7 @@ INSTANCE VARIABLE #blocks-left
   file-len @ block-size @ // #blocks !         \ *#blocks = roundup(file-len/block-size)
   #blocks @ 4 * alloc-mem blocks !             \ *blocks = allocmem(*#blocks)
   blocks @ ^blocks !  #blocks @ #blocks-left !
+  inode @ inode-i-flags EXT4_EXTENTS_FL and IF inode @ read-extent-tree EXIT THEN
   #blocks-left @ c min \ # direct blocks
   inode @ inode-i-block over 4 * ^blocks @ swap move blocks-read
   #blocks-left @ IF inode @ 58 + l at -le read-indirect-blocks THEN
-- 
2.17.1



More information about the SLOF mailing list