[openfirmware] r1400 - ofw/fs/ext2fs

svn at openfirmware.info svn at openfirmware.info
Wed Oct 7 10:52:49 CEST 2009


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




More information about the openfirmware mailing list