[openfirmware] [commit] r2798 - ofw/fs/ext2fs
repository service
svn at openfirmware.info
Wed Jan 4 09:51:42 CET 2012
Author: wmb
Date: Wed Jan 4 09:51:42 2012
New Revision: 2798
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2798
Log:
EXT4 extents support. OFW can now read, but not write, EXT4 filesystems.
Added:
ofw/fs/ext2fs/extent.fth
Modified:
ofw/fs/ext2fs/dir.fth
ofw/fs/ext2fs/ext2fs.fth
ofw/fs/ext2fs/layout.fth
ofw/fs/ext2fs/recovery.fth
Modified: ofw/fs/ext2fs/dir.fth
==============================================================================
--- ofw/fs/ext2fs/dir.fth Tue Jan 3 03:01:40 2012 (r2797)
+++ ofw/fs/ext2fs/dir.fth Wed Jan 4 09:51:42 2012 (r2798)
@@ -4,7 +4,7 @@
decimal
2 constant root-dir#
-0 instance value dir-block#
+0. instance 2value d.dir-block#
0 instance value lblk#
instance variable diroff
@@ -17,14 +17,17 @@
0 instance value wf-inum \ Inumber of file or directory found
0 instance value wf-type \ Type - 4 for directory, d# 10 for symlink, etc
+: find-dirblk ( -- )
+ lblk# >d.pblk# 0= abort" EXT2 - missing directory block" to d.dir-block#
+;
: get-dirblk ( -- end? )
lblk# bsize um* dfile-size d< 0= if true exit then
- lblk# >pblk# to dir-block#
+ find-dirblk
false
;
\ **** Return the address of the current directory entry
-: dirent ( -- adr ) dir-block# block diroff @ + ;
+: dirent ( -- adr ) d.dir-block# d.block diroff @ + ;
\ Dirent fields:
\ 00.l inode
\ 04.w offset to next dirent
@@ -87,10 +90,10 @@
\ On entry:
\ inode# refers to the directory block's inode
-\ dir-block# is the physical block number of the first directory block
+\ d.dir-block# is the physical block number of the first directory block
\ diroff @ is 0
\ On successful exit:
-\ dir-block# is the physical block number of the current directory block
+\ d.dir-block# is the physical block number of the current directory block
\ diroff @ is the within-block offset of the new dirent
: no-dir-space? ( #needed -- true | offset-to-next false )
begin ( #needed )
@@ -131,7 +134,7 @@
;
: last-dirent ( -- free-bytes )
dfile-size bsize um/mod nip swap 0= if 1- then to lblk# ( )
- lblk# >pblk# to dir-block#
+ find-dirblk
(last-dirent) drop
dirent-len@ dirent-reclen -
;
@@ -293,10 +296,10 @@
\ On entry:
\ inode# is the inode of the directory file
-\ dir-block# is the physical block number of the first directory block
+\ d.dir-block# is the physical block number of the first directory block
\ diroff @ and totoff @ are 0
\ On successful exit:
-\ dir-block# is the physical block number of the current directory block
+\ d.dir-block# is the physical block number of the current directory block
\ diroff @ is the within-block offset of the directory entry that matches name$
\ totoff @ is the overall offset of the directory entry that matches name$
Modified: ofw/fs/ext2fs/ext2fs.fth
==============================================================================
--- ofw/fs/ext2fs/ext2fs.fth Tue Jan 3 03:01:40 2012 (r2797)
+++ ofw/fs/ext2fs/ext2fs.fth Wed Jan 4 09:51:42 2012 (r2798)
@@ -8,6 +8,7 @@
fload ${BP}/ofw/fs/ext2fs/blocks.fth
fload ${BP}/ofw/fs/ext2fs/inode.fth
fload ${BP}/ofw/fs/ext2fs/bitmap.fth
+fload ${BP}/ofw/fs/ext2fs/extent.fth
fload ${BP}/ofw/fs/ext2fs/layout.fth
fload ${BP}/ofw/fs/ext2fs/dir.fth
fload ${BP}/ofw/fs/ext2fs/recovery.fth
Added: ofw/fs/ext2fs/extent.fth
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ ofw/fs/ext2fs/extent.fth Wed Jan 4 09:51:42 2012 (r2798)
@@ -0,0 +1,87 @@
+\ EXT4 extents
+d# 12 constant /extent-header
+d# 12 constant /extent-record
+
+struct
+ /w field >eh_magic
+ /w field >eh_entries
+ /w field >eh_max
+ /w field >eh_depth
+ /l field >eh_generation
+constant /extent-header
+
+: ext-magic? ( 'eh -- flag ) >eh_magic short@ h# f30a = ;
+: extent? ( -- flag ) direct0 ext-magic? ;
+
+struct
+ /l field >ee_block
+ /w field >ee_len
+ /w field >ee_start_hi
+ /l field >ee_start_lo
+constant /extent
+
+struct
+ /l field >ei_block \ Same offset and size as >ee_block
+ /l field >ei_leaf_lo
+ /w field >ei_leaf_hi
+ /w + ( >ei_unused )
+constant /extent-index \ Same length as /extent
+
+: index-block@ ( 'extent-index -- d.block# )
+ dup >ei_leaf_lo int@ swap >ei_leaf_hi short@
+;
+: extent-block@ ( 'extent -- d.block# )
+ dup >ee_start_lo int@ swap >ee_start_hi short@
+;
+
+: >extent ( index 'eh -- 'extent )
+ /extent-header + swap /extent * +
+;
+
+\ Works for both extents and extent-index's because they are the
+\ same length and their block fields are in the same place.
+: ext-binsearch ( block# 'eh -- block# 'extent )
+ >r ( block# r: 'eh )
+ 1 ( block# left r: 'eh )
+ r@ >eh_entries short@ 1- ( block# left right r: 'eh )
+ begin 2dup <= while ( block# left right r: 'eh )
+ 2dup + 2/ ( block# left right middle r: 'eh )
+ dup r@ >extent ( block# left right middle 'extent r: 'eh )
+ >ei_block int@ ( block# left right middle extent-block r: 'eh )
+ 4 pick > if ( block# left right middle r: 'eh )
+ nip 1- ( block# left right' r: 'eh )
+ else ( block# left right middle r: 'eh )
+ rot drop ( block# right middle r: 'eh )
+ 1+ swap ( block# left' right r: 'eh )
+ then ( block# left right r: 'eh )
+ repeat ( block# left right r: 'eh )
+ drop 1- ( block# left r: 'eh)
+ r> >extent ( block# 'extent )
+;
+
+: extent->pblk# ( logical-block# -- d.physical-block# )
+ direct0 ( logical-block# 'eh )
+ dup >eh_depth short@ 0 ?do ( logical-block# 'eh )
+ ext-binsearch ( logical-block# 'extent-index )
+ index-block@ ( logical-block# d.block# )
+ d.block ( logical-block# 'eh' )
+
+ \ Error check
+ dup ext-magic? 0= if ( logical-block# 'eh' )
+ ." EXT4 bad index block" cr
+ debug-me
+ then ( logical-block# 'eh' )
+
+ loop ( logical-block# 'eh )
+
+ ext-binsearch >r ( logical-block# r: 'extent )
+ \ At this point the extent should contain the logical block
+ r@ >ee_block int@ - ( block-offset r: 'extent )
+
+ \ Error check
+ dup r@ >ee_len short@ >= if ( block-offset r: 'extent )
+ ." EXT4 block not in extent" cr
+ debug-me
+ then ( block-offset r: 'extent )
+ u>d r> extent-block@ d+ ( d.block# )
+;
Modified: ofw/fs/ext2fs/layout.fth
==============================================================================
--- ofw/fs/ext2fs/layout.fth Tue Jan 3 03:01:40 2012 (r2797)
+++ ofw/fs/ext2fs/layout.fth Wed Jan 4 09:51:42 2012 (r2798)
@@ -42,36 +42,42 @@
swap la+ int@ ( index-low block# )
>ind2 ( adr )
;
-: >pblk ( logical-block# -- 0 | physical-block-adr )
+: >pblk-adr ( logical-block# -- 0 | physical-block-adr )
dup #direct-blocks < if ( lblk# )
- >direct exit
+ >direct exit ( -- adr )
then ( lblk# )
#direct-blocks - ( lblk#' )
dup #ind-blocks1 < if ( lblk# )
- #direct-blocks get-direct >ind1 exit
+ #direct-blocks get-direct >ind1 exit ( -- adr )
then
#ind-blocks1 - ( lblk#' )
- dup #ind-blocks2 < if
- #direct-blocks 1+ get-direct >ind2 exit
- then
+ dup #ind-blocks2 < if ( lblk# )
+ #direct-blocks 1+ get-direct >ind2 exit ( -- adr )
+ then ( lblk# )
#ind-blocks2 - ( lblk#' )
- dup #ind-blocks3 < if
- #direct-blocks 2+ get-direct >ind3 exit
- then
-
- drop 0
-;
-: >pblk# ( logical-block# -- physical-block# )
- >pblk dup 0= if exit then int@
+ dup #ind-blocks3 < if ( lblk# )
+ #direct-blocks 2+ get-direct >ind3 exit ( -- adr )
+ then ( lblk# )
+
+ drop 0 ( 0 )
+;
+: >d.pblk# ( logical-block# -- false | d.physical-block# true )
+ extent? if ( logical-block# )
+ extent->pblk# true exit ( -- d.physical-block# true )
+ then ( logical-block# )
+ >pblk-adr dup 0= if ( 0 )
+ exit ( -- false )
+ then ( adr )
+ int@ u>d true ( d.physical-block# true )
;
\ writes: if any indir block is 0, allocate and return it.
-: get-ind1 ( index block# -- adr )
+: get-ind1 ( index ind1-block# -- block# )
>r ( index ) ( r: ind3-block# )
r@ block over la+ int@ ( index block# )
dup if ( index block# )
@@ -80,7 +86,7 @@
drop u.add-block ( index new-block# )
dup rot r@ block swap la+ int! update ( new-block# )
then ( block# )
- r> drop
+ r> drop ( block# )
;
: get-ind2 ( index ind2-block# -- block# )
>r ( index ) ( r: ind3-block# )
@@ -92,8 +98,8 @@
drop u.add-block ( index-low index-high new-block# )
dup rot r@ block swap la+ int! update ( index-low new-block# )
then ( index-low block# )
- get-ind1 ( adr )
- r> drop
+ get-ind1 ( block# )
+ r> drop ( block# )
;
: get-ind3 ( index ind3-block# -- block# )
>r ( index ) ( r: ind3-block# )
@@ -105,43 +111,50 @@
drop u.add-block ( index-low index-high new-block# )
dup rot r@ block swap la+ int! update ( index-low new-block# )
then ( index-low block# )
- get-ind2 ( adr )
- r> drop
+ get-ind2 ( block# )
+ r> drop ( block# )
;
\ get-pblk# will allocate the block if necessary, used for writes
: get-pblk# ( logical-block# -- 0 | physical-block# )
dup #direct-blocks < if ( lblk# )
- dup get-direct ?dup if nip exit then ( lblk# )
+ dup get-direct ?dup if ( lblk# pblk# )
+ nip exit ( -- pblk# )
+ then ( lblk# )
- u.add-block dup rot >direct int! update exit
+ u.add-block ( lblk# pblk# )
+ dup rot >direct int! update ( pblk# )
+ exit ( -- pblk# )
then ( lblk# )
#direct-blocks - ( lblk#' )
dup #ind-blocks1 < if ( lblk# )
#direct-blocks get-direct ?dup 0= if ( lblk# )
- u.add-block dup #direct-blocks put-direct
- then ( lblk# block )
- get-ind1 exit
- then
+ u.add-block ( lblk# ind1-pblk# )
+ dup #direct-blocks put-direct ( lblk# ind1-pblk# )
+ then ( lblk# ind1-pblk# )
+ get-ind1 exit ( -- pblk# )
+ then ( lblk# )
#ind-blocks1 - ( lblk#' )
dup #ind-blocks2 < if
- #direct-blocks 1+ get-direct ?dup 0= if
- u.add-block dup #direct-blocks 1+ put-direct
- then ( lblk# block )
- get-ind2 exit
- then
- #ind-blocks2 - ( lblk#' )
+ #direct-blocks 1+ get-direct ?dup 0= if ( lblk# )
+ u.add-block ( lblk# ind2-pblk# )
+ dup #direct-blocks 1+ put-direct ( lblk# ind2-pblk# )
+ then ( lblk# ind2-pblk# )
+ get-ind2 exit ( -- pblk# )
+ then ( lblk# )
+ #ind-blocks2 - ( lblk#' )
- dup #ind-blocks3 < if
- #direct-blocks 2+ get-direct ?dup 0= if
- u.add-block dup #direct-blocks 2+ put-direct
- then ( lblk# block )
- get-ind3 exit
- then
+ dup #ind-blocks3 < if ( lblk#' )
+ #direct-blocks 2+ get-direct ?dup 0= if ( lblk# )
+ u.add-block ( lblk# ind3-pblk# )
+ dup #direct-blocks 2+ put-direct ( lblk# ind3-pblk# )
+ then ( lblk# ind3-pblk# )
+ get-ind3 exit ( -- pblk# )
+ then ( lblk# )
- drop 0
+ drop 0 ( 0 )
;
\ deletes
@@ -189,14 +202,14 @@
;
: append-block ( -- )
- u.add-block ( block )
- dfile-size bsize um/mod nip dup bsize um* dfile-size! ( block #blocks )
- 1+ >pblk int! update
+ u.add-block ( pblk# )
+ dfile-size bsize um/mod nip dup bsize um* dfile-size! ( pblk# #blocks )
+ 1+ >pblk-adr int! update
;
: read-file-block ( adr lblk# -- )
- >pblk# ?dup if ( adr pblk# )
- block swap bsize move
+ >d.pblk# if ( adr d.pblk# )
+ d.block swap bsize move
else ( adr )
bsize erase ( )
then
@@ -206,10 +219,13 @@
0 swap bsize bounds do i l@ or 4 +loop 0=
;
: write-file-block ( adr lblk# -- )
- over zeroed? if \ see if it is already allocated (XXX later: deallocate it)
- >pblk# dup 0= if 2drop exit then
- else \ find or allocate physical block
- get-pblk# ( adr pblk# )
+ \ see if it is already allocated (XXX later: deallocate it)
+ over zeroed? if ( adr lblk# )
+ >d.pblk# 0= if ( adr )
+ drop exit ( -- )
+ then ( d.pblk# )
+ else ( adr lblk# ) \ find or allocate physical block
+ get-pblk# u>d ( adr d.pblk# )
then
\ This interferes with journal recovery
\ dup h# f8 < if dup . ." attempt to destroy file system" cr abort then
Modified: ofw/fs/ext2fs/recovery.fth
==============================================================================
--- ofw/fs/ext2fs/recovery.fth Tue Jan 3 03:01:40 2012 (r2797)
+++ ofw/fs/ext2fs/recovery.fth Wed Jan 4 09:51:42 2012 (r2798)
@@ -209,7 +209,7 @@
listnode
/n 2* field >o_block#
- /n field >o_pblock#
+ /n 2* field >o_pblock#
/n field >o_escaped?
nodetype: overlay-node
@@ -229,19 +229,19 @@
;
: j-read-file-block ( adr lblk# -- )
- >pblk# ?dup if ( adr pblk# )
- u>d find-overlay? if ( adr d.pblk# node )
+ >d.pblk# if ( adr d.pblk# )
+ find-overlay? if ( adr d.pblk# node )
nip nip ( adr node )
- tuck >o_pblock# l@ ( node adr pblk# )
- block over bsize move ( node adr )
+ tuck >o_pblock# 2@ ( node adr d.pblk# )
+ d.block over bsize move ( node adr )
swap >o_escaped? l@ if ( adr )
jbd_magic swap be-l! ( )
else ( adr )
drop ( )
then ( )
else ( adr d.pblk# node )
- 2drop ( adr pblk# )
- block swap bsize move ( )
+ drop ( adr d.pblk# )
+ d.block swap bsize move ( )
then ( )
else ( adr )
bsize erase ( )
@@ -252,7 +252,9 @@
: set-overlay-node ( escaped? log-blk# d.block# node -- )
>r ( escaped? log-blk# d.block# r: node )
r@ >o_block# 2! ( escaped? log-blk# r: node )
- >pblk# r@ >o_pblock# l! ( escaped? r: node )
+ >d.pblk# 0= abort" EXT3/4 bad block number in journal"
+ ( escaped? d.pblk# r: node )
+ r@ >o_pblock# 2! ( escaped? r: node )
r> >o_escaped? l! ( )
;
: note-jblock ( d.block# escaped? log-blk# -- )
More information about the openfirmware
mailing list