[OpenBIOS] r730 - ofw/fs/jffs2

svn at openbios.org svn at openbios.org
Wed Nov 14 10:53:14 CET 2007


Author: wmb
Date: 2007-11-14 10:53:14 +0100 (Wed, 14 Nov 2007)
New Revision: 730

Modified:
   ofw/fs/jffs2/jffs2.fth
Log:
OLPC trac 4898 - fixed handling of deleted files.  The problem occured
when a deletion entry occurred at a lower NAND block number than a
non-deletion entry, with a lower version number, for the same file .
The scanning code was too aggressive in discarding RAM record for
deleted files, so the file reappeared when the lower-version-number
entry was later scanned.  The fix is to keep such entries, so the
highest version number record is kept regardless of the order in
which the nodes are encountered.  Deletions are then noticed at a
later time, when you search for a file or enumerate a directory.
I also added the $readlink method so that "dir" will display the
referent of symlinks.


Modified: ofw/fs/jffs2/jffs2.fth
===================================================================
--- ofw/fs/jffs2/jffs2.fth	2007-11-14 07:58:39 UTC (rev 729)
+++ ofw/fs/jffs2/jffs2.fth	2007-11-14 09:53:14 UTC (rev 730)
@@ -781,12 +781,8 @@
 : scan-node  ( adr -- adr' )
    dup wa1+ w@  case   ( adr nodetype )
       dirent-type  of  ( adr )
-         dup rdinode@  if  ( adr )  \ Ignore deleted entries
-            debug-scan?  if  ." d"  then
-            scan-raw-dirent             ( adr )
-         else
-            debug-scan?  if  ." D"  then
-         then                              ( adr )
+         debug-scan?  if  ." d"  then
+         scan-raw-dirent    ( adr )
 \          false to cleanmark?             ( adr )
       endof                 ( adr nodetype )
 
@@ -1214,7 +1210,8 @@
       2over  ?update-dirent                ( name$ adr )
    repeat                                  ( name$ )
    2drop                                   ( )
-   my-vers 0<   if  true exit  then        ( )
+   my-vers 0<   if  true exit  then        ( )  \ Name not found
+   wf-inum 0=   if  true exit  then        ( )  \ Name was deleted
    wf-type 4  =  if
       wd-inum wf-inum remember-parent
       wf-inum to wd-inum
@@ -1222,7 +1219,6 @@
    false
 ;
 
-
 \ The work file is a symlink.  Resolve it to a new dirent
 : dir-link  ( -- error? )
    delimiter >r  [char] / to delimiter
@@ -1315,17 +1311,13 @@
    next-minode  minodes  ?do                    ( rdirent )
       dup rdname$  i tdname$  $=  if            ( rdirent )  \ Same name
          dup rdversion@  i tdversion@  >  if    ( rdirent )  \ New version
-            dup rdinode@  if                    ( rdirent )
-               dup i replace-tdirent            ( rdirent )  \ Not unlinked
-            else                                ( rdirent )
-               i remove-tdirent                 ( rdirent )  \ Unlinked
-            then                                ( rdirent )
+            dup i replace-tdirent               ( rdirent )
          then                                   ( rdirent )
          drop unloop exit
       then                                      ( rdirent )
       i tdlen                                   ( rdirent )
    +loop                                        ( rdirent )
-   dup rdinode@  if  place-tdirent  else  drop  then   ( )
+   place-tdirent
 ;
 
 : prep-dirents  ( -- )
@@ -1509,16 +1501,33 @@
    file-size
 ;
 
+0 instance value last-tdirent
+0 instance value last-rinode
+: $readlink  ( name$ -- true | expansion$ false )
+   last-tdirent tdname$ $=  0=  if  true exit  then   ( )
+   last-rinode >ridata  last-rinode ridsize@ false    ( expansion$ false )
+;
+
 : next-file-info  ( id -- false | id' s m h d m y len attributes name$ true )
    dup 0=  if  drop prep-dirents  minodes  then   ( tdirent )
-   dup next-minode =  if  drop false exit  then   ( tdirent )
-   dup >r  dup tdlen +                            ( id' r: tdirent )
-   r@ tdinum@ latest-node  if                     ( id' r: tdirent )
-." Can't find data node" cr
+
+   \ Skip deleted nodes
+   begin
+      dup next-minode =  if  drop false exit  then   ( tdirent )
+      dup tdinum@  0=                                ( tdirent deleted? )
+   while                                             ( tdirent )
+      dup tdlen +                                    ( tdirent' )
+   repeat                                            ( tdirent )
+
+   dup to last-tdirent                               ( tdirent )
+   dup >r  dup tdlen +                               ( id' r: tdirent )
+   r@ tdinum@  latest-node  if                       ( id' r: tdirent )
+      ." Can't find data node" cr
       0 0 0  0 0 0           ( id' s m h  d m y  r: tdirent )
       0                                ( ... len r: tdirent )
       0                         ( ... attributes r: tdirent )
    else                           ( id' rinode r: tdirent )
+      dup to last-rinode
       >r                          ( id'  r: tdirent rinode )
       r@ rimtime@  unix-seconds>  ( id' s m h  d m y  r: tdirent rinode )
       r@ riisize@                 ( id' s m h  d m y  len r: tdirent rinode )




More information about the OpenBIOS mailing list