Changeset 2939


Ignore:
Timestamp:
Apr 7, 2012, 1:05:35 AM (2 years ago)
Author:
wmb
Message:

Ext2/3/4 file system journal recovery - OLPC trac 11762 - Fixed list management problem that could result in missing list nodes in the journal overlay and revocation lists.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • forth/lib/linklist.fth

    r1 r2939  
    4646\       returned "true", and also the preceding node.  See the comments 
    4747\       in the code for more information. 
     48\ 
     49\ find-node?  ( ??? list acf -- ??? false | ??? node true ) 
     50\       Searches the linked list "list", executing the procedure "acf" 
     51\       for each node in the list.  Returns the node and true if found, 
     52\       or false if not found. 
    4853 
    4954alias list: variable 
     
    5863 
    5964alias >next-node @     ( node-adr -- next-node-adr ) 
     65 
     66: list-end?  ( node-adr -- flag )  >next-node @ 0=  ; 
    6067 
    6168\ Inserts "new-node" into a linked list after "prev-node" (and before 
     
    111118   until                         ( ??? )              ( r: acf next this ) 
    112119   r> r> r> drop                 ( ??? prev-node this-node ) 
     120; 
     121 
     122: find-node?  ( ??? list acf -- ??? false | ??? node true ) 
     123   find-node ?dup  if   ( ??? prev-node this-node ) 
     124      nip true          ( ??? node true ) 
     125   else                 ( ??? prev-node ) 
     126      drop false        ( ??? false ) 
     127   then                 ( ??? false | ??? node true ) 
    113128; 
    114129 
  • ofw/fs/ext2fs/recovery.fth

    r2938 r2939  
    161161nodetype: revoke-node 
    162162 
    163 list: revoke-list 
     163instance variable revoke-list 
     164revoke-list off 
    164165 
    165166: free-revoke-list  ( -- ) 
     
    170171;  
    171172 
    172 : block#>  ( d.block# 'node -- d.block# flag ) 
    173    >r_block# 2@  2over d< 
     173\ Worker function for find-node? 
     174: block#=  ( d.block# 'node -- d.block# flag ) 
     175   >r_block# 2@  2over d= 
    174176; 
    175177 
    176178\ node is either the found one or the insertion point 
    177 : find-revoked  ( d.block# -- d.block# node found? ) 
    178    revoke-list ['] block#> find-node  if    ( d.block# node ) 
    179       3dup >r_block# 2@ d=                  ( d.block# node found? ) 
    180    else                                     ( d.block# node ) 
    181       false                                 ( d.block# node found? ) 
    182    then                                     ( d.block# node found? ) 
     179: find-revoked?  ( d.block# -- d.block# false | d.block# node found? ) 
     180   revoke-list ['] block#= find-node? 
    183181; 
    184182 
     
    186184 
    187185: revoked?  ( d.block# -- revoked? ) 
    188    find-revoked  if         ( d.block# node ) 
    189       nip nip               ( node ) 
    190       >r_sequence @         ( sequence# ) 
    191       next-commit-id =      ( revoked? ) 
    192    else                     ( d.block# node ) 
    193       3drop  false          ( revoked? ) 
    194    then                     ( revoked? ) 
     186   find-revoked?  if       ( d.block# node ) 
     187      nip nip              ( node ) 
     188      >r_sequence @        ( sequence# ) 
     189      next-commit-id =     ( revoked? ) 
     190   else                    ( d.block# ) 
     191      2drop  false         ( revoked? ) 
     192   then                    ( revoked? ) 
    195193; 
    196194 
    197195: set-revoke  ( d.block# -- ) 
    198    find-revoked  if                                  ( d.block# node ) 
     196   find-revoked?  if                                 ( d.block# node ) 
    199197      nip nip                                        ( node ) 
    200198      next-commit-id  over >r_sequence @  - 0>=  if  ( node ) 
     
    202200      then                                           ( node ) 
    203201      drop                                           ( ) 
    204    else                                              ( d.block# node ) 
    205       -rot                                           ( node d.block# ) 
    206       revoke-node allocate-node >r                   ( node d.block# r: newnode ) 
    207       r@ >r_block# 2!                                ( node r: newnode ) 
    208       next-commit-id  r@ >r_sequence  !              ( node r: newnode ) 
    209       r> swap insert-after                           ( ) 
     202   else                                              ( d.block# ) 
     203      revoke-node allocate-node >r                   ( d.block# r: newnode ) 
     204      r@ >r_block# 2!                                ( r: newnode ) 
     205      next-commit-id  r@ >r_sequence  !              ( r: newnode ) 
     206      r> revoke-list insert-after                    ( ) 
    210207   then                                              ( ) 
    211208; 
     
    217214nodetype: overlay-node 
    218215 
    219 list: overlay-list 
     216instance variable overlay-list 
     217overlay-list off 
    220218 
    221219: free-overlay-list  ( -- ) 
     
    226224;  
    227225 
    228 \ node is either the found one or the insertion point 
    229 : find-overlay?  ( d.block# -- d.block# node found? ) 
    230    overlay-list ['] block#> find-node  if    ( d.block# node ) 
    231       3dup >r_block# 2@ d=                   ( d.block# node found? ) 
    232    else                                      ( d.block# node ) 
    233       false                                  ( d.block# node found? ) 
    234    then                                      ( d.block# node found? ) 
     226: find-overlay?  ( d.block# -- d.block# false | d.block# node true ) 
     227   overlay-list ['] block#= find-node? 
    235228; 
    236229 
     
    246239            drop                  ( ) 
    247240         then                     ( ) 
    248       else                        ( adr d.pblk# node ) 
    249          drop                     ( adr d.pblk# ) 
     241      else                        ( adr d.pblk# ) 
    250242         d.block swap bsize move  ( ) 
    251243      then                        ( ) 
     
    267259   2swap find-overlay?  if          ( escaped? log-blk# d.block# node ) 
    268260      set-overlay-node              ( ) 
    269    else                             ( escaped? log-blk# d.block# node ) 
    270       >r                            ( escaped? log-blk# d.block# r: prev-node ) 
    271       >r overlay-node allocate-node ( d.block# escaped? log-blk# newnode r: prevnode ) 
    272       dup >r set-overlay-node       ( r: prevnode newnode ) 
    273       r> r> insert-after            ( ) 
     261   else                             ( escaped? log-blk# d.block# ) 
     262      overlay-node allocate-node >r ( d.block# escaped? log-blk# r: newnode ) 
     263      r@ set-overlay-node           ( r: newnode ) 
     264      r> overlay-list insert-after  ( ) 
    274265   then 
    275266; 
     
    409400; 
    410401: commit-journal  ( -- ) 
     402   j-read-only?  if  exit  then 
    411403   jsb >s_sequence dup be-l@ 1+ swap be-l! 
    412404   0 jsb >s_start be-l! 
     
    417409   read-journal  if  exit  then 
    418410 
    419 ." Recovering from journal ... " 
     411   ." Recovering from journal " 
     412   j-read-only?  if  ." (read-only)"  then 
     413   ." ... " 
     414 
    420415   0 to end-transaction 
    421416 
     
    444439cr 
    445440; 
    446 \ XXX need to do free-overlay-list in close 
Note: See TracChangeset for help on using the changeset viewer.