Author: wmb Date: Wed Jan 11 01:42:44 2012 New Revision: 2815 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2815
Log: EXT2/3/4 filesystem - OLPC trac #11184 - fixed problem with group descriptor checksums, which caused fsck errors when deleting files on ext4.
Added: forth/lib/crc16.fth Modified: cpu/arm/olpc/prefw.fth ofw/fs/ext2fs/bitmap.fth ofw/fs/ext2fs/sb.fth
Modified: cpu/arm/olpc/prefw.fth ============================================================================== --- cpu/arm/olpc/prefw.fth Tue Jan 10 06:19:38 2012 (r2814) +++ cpu/arm/olpc/prefw.fth Wed Jan 11 01:42:44 2012 (r2815) @@ -89,6 +89,7 @@ [ifdef] resident-packages
\needs unix-seconds> fload ${BP}/ofw/fs/unixtime.fth \ Unix time calculation +\needs ($crc16) fload ${BP}/forth/lib/crc16.fth support-package: ext2-file-system fload ${BP}/ofw/fs/ext2fs/ext2fs.fth \ Linux file system end-support-package
Added: forth/lib/crc16.fth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ forth/lib/crc16.fth Wed Jan 11 01:42:44 2012 (r2815) @@ -0,0 +1,48 @@ +purpose: CRC16 with polynomial x^16 + x^15 + x^2 + 1 (0x8005) as used by Linux kernel + +base @ hex +create crc16tab + 0000 w, C0C1 w, C181 w, 0140 w, C301 w, 03C0 w, 0280 w, C241 w, + C601 w, 06C0 w, 0780 w, C741 w, 0500 w, C5C1 w, C481 w, 0440 w, + CC01 w, 0CC0 w, 0D80 w, CD41 w, 0F00 w, CFC1 w, CE81 w, 0E40 w, + 0A00 w, CAC1 w, CB81 w, 0B40 w, C901 w, 09C0 w, 0880 w, C841 w, + D801 w, 18C0 w, 1980 w, D941 w, 1B00 w, DBC1 w, DA81 w, 1A40 w, + 1E00 w, DEC1 w, DF81 w, 1F40 w, DD01 w, 1DC0 w, 1C80 w, DC41 w, + 1400 w, D4C1 w, D581 w, 1540 w, D701 w, 17C0 w, 1680 w, D641 w, + D201 w, 12C0 w, 1380 w, D341 w, 1100 w, D1C1 w, D081 w, 1040 w, + F001 w, 30C0 w, 3180 w, F141 w, 3300 w, F3C1 w, F281 w, 3240 w, + 3600 w, F6C1 w, F781 w, 3740 w, F501 w, 35C0 w, 3480 w, F441 w, + 3C00 w, FCC1 w, FD81 w, 3D40 w, FF01 w, 3FC0 w, 3E80 w, FE41 w, + FA01 w, 3AC0 w, 3B80 w, FB41 w, 3900 w, F9C1 w, F881 w, 3840 w, + 2800 w, E8C1 w, E981 w, 2940 w, EB01 w, 2BC0 w, 2A80 w, EA41 w, + EE01 w, 2EC0 w, 2F80 w, EF41 w, 2D00 w, EDC1 w, EC81 w, 2C40 w, + E401 w, 24C0 w, 2580 w, E541 w, 2700 w, E7C1 w, E681 w, 2640 w, + 2200 w, E2C1 w, E381 w, 2340 w, E101 w, 21C0 w, 2080 w, E041 w, + A001 w, 60C0 w, 6180 w, A141 w, 6300 w, A3C1 w, A281 w, 6240 w, + 6600 w, A6C1 w, A781 w, 6740 w, A501 w, 65C0 w, 6480 w, A441 w, + 6C00 w, ACC1 w, AD81 w, 6D40 w, AF01 w, 6FC0 w, 6E80 w, AE41 w, + AA01 w, 6AC0 w, 6B80 w, AB41 w, 6900 w, A9C1 w, A881 w, 6840 w, + 7800 w, B8C1 w, B981 w, 7940 w, BB01 w, 7BC0 w, 7A80 w, BA41 w, + BE01 w, 7EC0 w, 7F80 w, BF41 w, 7D00 w, BDC1 w, BC81 w, 7C40 w, + B401 w, 74C0 w, 7580 w, B541 w, 7700 w, B7C1 w, B681 w, 7640 w, + 7200 w, B2C1 w, B381 w, 7340 w, B101 w, 71C0 w, 7080 w, B041 w, + 5000 w, 90C1 w, 9181 w, 5140 w, 9301 w, 53C0 w, 5280 w, 9241 w, + 9601 w, 56C0 w, 5780 w, 9741 w, 5500 w, 95C1 w, 9481 w, 5440 w, + 9C01 w, 5CC0 w, 5D80 w, 9D41 w, 5F00 w, 9FC1 w, 9E81 w, 5E40 w, + 5A00 w, 9AC1 w, 9B81 w, 5B40 w, 9901 w, 59C0 w, 5880 w, 9841 w, + 8801 w, 48C0 w, 4980 w, 8941 w, 4B00 w, 8BC1 w, 8A81 w, 4A40 w, + 4E00 w, 8EC1 w, 8F81 w, 4F40 w, 8D01 w, 4DC0 w, 4C80 w, 8C41 w, + 4400 w, 84C1 w, 8581 w, 4540 w, 8701 w, 47C0 w, 4680 w, 8641 w, + 8201 w, 42C0 w, 4380 w, 8341 w, 4100 w, 81C1 w, 8081 w, 4040 w, +base ! + + +: ($crc16) ( crc adr len -- crc' ) + bounds ?do ( crc ) + wbsplit swap ( b.high b.low ) + i c@ ( b.high b.low c ) + xor ( b.high b.low^c ) + crc16tab swap wa+ w@ ( b.high w.tabval ) + xor ( crc' ) + loop +;
Modified: ofw/fs/ext2fs/bitmap.fth ============================================================================== --- ofw/fs/ext2fs/bitmap.fth Tue Jan 10 06:19:38 2012 (r2814) +++ ofw/fs/ext2fs/bitmap.fth Wed Jan 11 01:42:44 2012 (r2815) @@ -7,7 +7,10 @@
0 instance value gd-modified?
-: gd-update ( -- ) true to gd-modified? ; +: gd-update ( block# -- ) + dup group-desc set-gd-csum ( ) + true to gd-modified? ( ) +; : d.block-bitmap ( group# -- d.block# ) group-desc dup le-l@ ( adr n ) desc64? if ( adr n ) @@ -53,7 +56,7 @@
: free-blocks+! ( n group# -- ) tuck free-blocks@ + 0 max ( group# n' ) - swap free-blocks! ( ) + over free-blocks! ( group# 'gd ) gd-update ( ) ; : free-inodes@ ( group# -- n ) @@ -74,7 +77,7 @@ ; : free-inodes+! ( n inode# -- ) tuck free-inodes@ + ( group# n' ) - swap free-inodes! ( ) + over free-inodes! ( group# ) gd-update ( ) ;
@@ -256,7 +259,8 @@ 2dup i d.block-bitmap d< if ( d.possible-gn ) d.block ( gdn-adr ) 0 group-desc ( gdn-adr gd0-adr ) - swap bsize move update ( ) + swap bsize move ( ) + update ( ) else ( d.possible-gn ) 2drop ( ) then ( )
Modified: ofw/fs/ext2fs/sb.fth ============================================================================== --- ofw/fs/ext2fs/sb.fth Tue Jan 10 06:19:38 2012 (r2814) +++ ofw/fs/ext2fs/sb.fth Wed Jan 11 01:42:44 2012 (r2815) @@ -50,11 +50,51 @@
: recover? ( -- flag ) 24 +sbl 4 and 0<> ;
+: compat-flags ( -- mask ) 23 +sbl ; +: incompat-flags ( -- mask ) 24 +sbl ; +: ro-flags ( -- mask ) 25 +sbl ; + +: sb-64bit? ( -- flag ) incompat-flags h# 80 and 0<> ; +: sb-extents? ( -- flag ) incompat-flags h# 40 and 0<> ; +: sb-gd-csum? ( -- flag ) ro-flags h# 10 and 0<> ; + \ Don't write to a disk that uses extensions we don't understand : unknown-extensions? ( -- unsafe? ) - 23 +sbl h# ffffffff invert and \ Accept all compat extensions - 24 +sbl h# 00000002 invert and or \ Incompatible - accept FILETYPE - 25 +sbl h# 00000003 invert and or \ RO - accept SPARSE_SUPER and LARGE_FILE + compat-flags h# ffffffff invert and \ Accept all compat extensions + incompat-flags h# 00000002 invert and or \ Incompatible - accept FILETYPE + ro-flags h# 00000003 invert and or \ RO - accept SPARSE_SUPER and LARGE_FILE +; +: 'sb-uuid ( -- adr ) super-block h# 68 + ; +variable le-group +: sb-desc-size ( -- ) d# 127 +sbw ; + +: sb-gd-csum ( 'gd -- w ) h# 1e + le-w@ ; +: sum-gd ( group# 'gd -- sum ) + h# ffff 'sb-uuid d# 16 ($crc16) ( group# 'gd sum ) + rot le-group le-l! le-group /l ($crc16) ( 'gd sum' ) + over h# 1e ($crc16) ( 'gd sum' ) + sb-64bit? h# 20 sb-desc-size < and if ( 'gd sum' ) + swap sb-desc-size h# 20 /string ( sum adr len ) + ($crc16) ( sum' ) + else ( 'gd sum' ) + nip ( sum' ) + then ( sum' ) +; +: gd-csum-ok? ( group# 'gd -- ok? ) + sb-gd-csum? if ( group# 'gd ) + tuck sum-gd ( 'gd sum ) + swap h# 1e + le-w@ <> ( flag ) + else ( group# 'gd ) + 2drop true ( flag ) + then ( flag ) +; +: set-gd-csum ( group# 'gd -- ) + sb-gd-csum? if ( group# 'gd ) + tuck sum-gd ( 'gd sum ) + swap h# 1e + le-w! ( ) + else ( group# 'gd ) + 2drop ( ) + then ( ) ;
: do-alloc ( adr len -- ) " dma-alloc" $call-parent ; @@ -95,8 +135,8 @@ : d.gds-block# ( -- d.dev-block# ) d.gds-fs-block# bsize ublock / du* ( dev-block# ) ; -: desc64? ( -- flag ) h# 7f +sbw 0<> ; -: /gd ( -- n ) h# 7f +sbw ?dup 0= if h# 20 then ; +: desc64? ( -- flag ) sb-desc-size 0<> ; +: /gd ( -- n ) sb-desc-size ?dup 0= if h# 20 then ; : /gds ( -- size ) #groups /gd * ublock round-up ; : group-desc ( group# -- adr ) /gd * gds + ; : d.gpimin ( group -- d.block# )
openfirmware@openfirmware.info