Author: wmb Date: 2009-10-07 10:52:49 +0200 (Wed, 07 Oct 2009) New Revision: 1400
Modified: ofw/fs/ext2fs/dir.fth ofw/fs/ext2fs/layout.fth ofw/fs/ext2fs/methods.fth Log: OLPC trac 6210 - fixed rmdir and mkdir for ext2 file systems.
Modified: ofw/fs/ext2fs/dir.fth =================================================================== --- ofw/fs/ext2fs/dir.fth 2009-10-06 23:56:37 UTC (rev 1399) +++ ofw/fs/ext2fs/dir.fth 2009-10-07 08:52:49 UTC (rev 1400) @@ -3,8 +3,9 @@
decimal
-2 constant root-dir# +2 constant root-dir# 0 instance value dir-block# +0 instance value lblk#
variable diroff variable totoff @@ -74,16 +75,16 @@ \ After this point, the code should be independent of the disk format!
: init-inode ( mode inode# -- ) - inode >r ( mode ) - r@ /inode erase ( mode ) - r@ short! ( ) - time&date >unix-seconds ( time ) - dup r@ 2 la+ int! ( time ) \ set access time - dup r@ 3 la+ int! ( time ) \ set creation time - r@ 4 la+ int! ( ) \ set modification time - 1 r@ d# 13 wa+ short! \ set links_count to 1 - update - r> drop + inode >r ( mode r: inode-adr ) + r@ /inode erase ( mode r: inode-adr ) + r@ short! ( r: inode-adr ) + time&date >unix-seconds ( time r: inode-adr ) + dup r@ 2 la+ int! ( time r: inode-adr ) \ set access time + dup r@ 3 la+ int! ( time r: inode-adr ) \ set creation time + r@ 4 la+ int! ( r: inode-adr ) \ set modification time + 1 r@ d# 13 wa+ short! ( r: inode-adr ) \ set links_count to 1 + update ( r: inode-adr ) + r> drop ( ) ;
\ On entry: @@ -147,7 +148,7 @@
: to-previous-dirent ( -- ) diroff @ ( this ) - 0 diroff ! ( this ) + diroff off ( this ) begin ( this ) dup diroff @ dirent-len@ + <> ( this not-found? ) while ( this ) @@ -178,17 +179,19 @@ 7 constant symlink-type
: ($create) ( name$ mode -- error? ) - >r ( name$ ) + >r ( name$ r: mode ) \ check for room in the directory, and expand it if necessary - dup >reclen no-dir-space? if ( name$ new-reclen ) + dup >reclen no-dir-space? if ( name$ new-reclen r: mode ) \ doesn't fit, allocate more room - bsize ( name$ bsize ) + bsize ( name$ bsize r: mode ) append-block lblk#++ get-dirblk drop - then ( name$ rec-len ) + then ( name$ rec-len r: mode )
\ At this point dirent points to the place for the new dirent - regular-type alloc-inode set-dirent false ( error? ) + \ XXX handle symlinks! + r@ h# f000 and h# 4000 = if dir-type else regular-type then ( name$ rec-len type r: mode ) + alloc-inode set-dirent false ( error? r: mode ) r> dirent-inode@ init-inode ;
@@ -236,7 +239,7 @@ : first-dirent ( dir-inode# -- end? ) \ Adapted from (init-dir) set-inode get-dirblk if true exit then - 0 diroff ! 0 totoff ! ( ) + diroff off totoff off ( ) false ( ) ;
@@ -347,6 +350,16 @@ wd-inum first-dirent ;
+\ Returns true if inode# refers to a directory that is empty +\ Side effect - changes dirent context +: empty-dir? ( -- empty-dir? ) + dir? 0= if false exit then + + file-handle first-dirent if false exit then \ Should be pointing to "." entry + next-dirent if false exit then \ Should be point to ".." entry + next-dirent ( end? ) \ The rest should be empty +; + \ Delete a file, given its inode. Does not affect the directory entry, if any. : idelete ( inode# -- ) to inode# @@ -366,7 +379,7 @@
inode# >r file-handle set-inode - file? 0= if r> drop true exit then \ XXX handle symlinks + file? 0= if r> drop true exit then \ XXX handle symlinks
\ is this the only link? link-count dup 2 u< if
Modified: ofw/fs/ext2fs/layout.fth =================================================================== --- ofw/fs/ext2fs/layout.fth 2009-10-06 23:56:37 UTC (rev 1399) +++ ofw/fs/ext2fs/layout.fth 2009-10-07 08:52:49 UTC (rev 1400) @@ -7,7 +7,6 @@ 0 instance value #ind-blocks1 0 instance value #ind-blocks2 0 instance value #ind-blocks3 -0 instance value lblk#
\ first number \ 0 12 direct
Modified: ofw/fs/ext2fs/methods.fth =================================================================== --- ofw/fs/ext2fs/methods.fth 2009-10-06 23:56:37 UTC (rev 1399) +++ ofw/fs/ext2fs/methods.fth 2009-10-07 08:52:49 UTC (rev 1400) @@ -12,11 +12,14 @@ : $create ( name$ -- error? ) o# 100666 ($create) ; -\ XXX note: increment link count in parent + : $mkdir ( name$ -- error? ) o# 40777 ($create) if true exit then - + link-count 1+ link-count! \ The ".." entry is another link to parent + file-handle to inode# + link-count 1+ link-count! \ The "." entry is another link to the new directory + add-block ( block# ) file-size h# 400 + file-size! dup direct0 int! update ( block# ) @@ -37,27 +40,26 @@ ; : $delete! $delete ; \ XXX should these be different?
-\ XXX note: decrement link count in parent -: $rmdir ( name$ -- error? ) \ XXX UNTESTED +: $rmdir ( name$ -- error? ) $find-file if true exit then ( ) wf-type dir-type <> if true exit then ( ) + \ Now the dirent is the one for the directory to delete and the + \ inode is for the parent directory
- inode# >r \ save parent directory - file-handle set-inode - dir? 0= if r> drop true exit then - - (delete-files) file-handle if r> drop true exit then \ still some left - - \ now empty, remove it. - delete-blocks + dirent-vars 2>r 2>r \ save lookup state in parent directory + file-handle set-inode \ Switch the inode to the directory to delete
- \ delete inode. clear or mark it? - file-handle free-inode + empty-dir? 0= if 2r> 2r> 4drop true exit then + + \ The directory is empty so it's okay to remove it + delete-blocks \ Release the data blocks used for dirent storage + inode# free-inode \ Release the inode number
- r> to inode# \ restore parent directory + 2r> 2r> restore-dirent \ restore lookup state in parent directory
- \ delete directory entry - del-dirent ( error? ) + del-dirent if true exit then \ Remove the dirent from the parent directory + link-count 1- link-count! \ Decrement parent link count + false ;
headers
openfirmware@openfirmware.info