[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