[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