@@ -265,7 +265,6 @@ static int32_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t dir[2],
265265 lfs_mdir_t * parent );
266266static int lfs_fs_relocate (lfs_t * lfs ,
267267 const lfs_block_t oldpair [2 ], lfs_block_t newpair [2 ]);
268- static int lfs_fs_scan (lfs_t * lfs );
269268static int lfs_fs_forceconsistency (lfs_t * lfs );
270269
271270
@@ -410,80 +409,50 @@ static inline lfs_size_t lfs_tagsize(uint32_t tag) {
410409
411410// operations on set of globals
412411static inline void lfs_globalxor (lfs_global_t * a , const lfs_global_t * b ) {
413- for (int i = 0 ; i < sizeof (lfs_global_t )/2 ; i ++ ) {
414- a -> u16 [i ] ^= b -> u16 [i ];
412+ for (int i = 0 ; i < sizeof (lfs_global_t )/4 ; i ++ ) {
413+ a -> u32 [i ] ^= b -> u32 [i ];
415414 }
416415}
417416
418417static inline bool lfs_globaliszero (const lfs_global_t * a ) {
419- for (int i = 0 ; i < sizeof (lfs_global_t )/2 ; i ++ ) {
420- if (a -> u16 [i ] != 0 ) {
418+ for (int i = 0 ; i < sizeof (lfs_global_t )/4 ; i ++ ) {
419+ if (a -> u32 [i ] != 0 ) {
421420 return false;
422421 }
423422 }
424423 return true;
425424}
426425
427426static inline void lfs_globalzero (lfs_global_t * a ) {
428- memset (a -> u16 , 0x00 , sizeof (lfs_global_t ));
429- }
430-
431- static inline void lfs_globalones (lfs_global_t * a ) {
432- memset (a -> u16 , 0xff , sizeof (lfs_global_t ));
433- }
434-
435- static inline void lfs_globalxormove (lfs_global_t * a ,
436- const lfs_block_t pair [2 ], uint16_t id ) {
437- a -> u16 [0 ] ^= id ;
438- for (int i = 0 ; i < sizeof (lfs_block_t [2 ])/2 ; i ++ ) {
439- a -> u16 [1 + i ] ^= ((uint16_t * )pair )[i ];
440- }
441- }
442-
443- static inline void lfs_globalxordeorphaned (lfs_global_t * a , bool deorphaned ) {
444- a -> u16 [0 ] ^= deorphaned << 15 ;
427+ lfs_globalxor (a , a );
445428}
446429
447430static inline void lfs_globalfromle32 (lfs_global_t * a ) {
448- a -> u16 [ 0 ] = lfs_fromle16 (a -> u16 [ 0 ] );
449- lfs_pairfromle32 (( lfs_block_t * ) & a -> u16 [ 1 ] );
431+ lfs_pairfromle32 (a -> s . movepair );
432+ a -> s . moveid = lfs_fromle16 ( a -> s . moveid );
450433}
451434
452435static inline void lfs_globaltole32 (lfs_global_t * a ) {
453- a -> u16 [0 ] = lfs_tole16 (a -> u16 [0 ]);
454- lfs_pairtole32 ((lfs_block_t * )& a -> u16 [1 ]);
455- }
456-
457- static inline const lfs_block_t * lfs_globalmovepair (const lfs_t * lfs ) {
458- return (const lfs_block_t * )& lfs -> globals .u16 [1 ];
459- }
460-
461- static inline uint16_t lfs_globalmoveid (const lfs_t * lfs ) {
462- return 0x3ff & lfs -> globals .u16 [0 ];
463- }
464-
465- static inline bool lfs_globalisdeorphaned (const lfs_t * lfs ) {
466- return 0x8000 & lfs -> globals .u16 [0 ];
436+ lfs_pairtole32 (a -> s .movepair );
437+ a -> s .moveid = lfs_tole16 (a -> s .moveid );
467438}
468439
469440static inline void lfs_globalmove (lfs_t * lfs ,
470441 const lfs_block_t pair [2 ], uint16_t id ) {
471442 lfs_global_t diff ;
472443 lfs_globalzero (& diff );
473- lfs_globalxormove (& diff , lfs_globalmovepair (lfs ), lfs_globalmoveid (lfs ));
474- lfs_globalxormove (& diff , pair , id );
444+ diff .s .movepair [0 ] ^= lfs -> globals .s .movepair [0 ] ^ pair [0 ];
445+ diff .s .movepair [1 ] ^= lfs -> globals .s .movepair [1 ] ^ pair [1 ];
446+ diff .s .moveid ^= lfs -> globals .s .moveid ^ id ;
475447 lfs_globalfromle32 (& lfs -> locals );
476448 lfs_globalxor (& lfs -> locals , & diff );
477449 lfs_globaltole32 (& lfs -> locals );
478450 lfs_globalxor (& lfs -> globals , & diff );
479451}
480452
481453static inline void lfs_globaldeorphaned (lfs_t * lfs , bool deorphaned ) {
482- deorphaned ^= lfs_globalisdeorphaned (lfs );
483- lfs_globalfromle32 (& lfs -> locals );
484- lfs_globalxordeorphaned (& lfs -> locals , deorphaned );
485- lfs_globaltole32 (& lfs -> locals );
486- lfs_globalxordeorphaned (& lfs -> globals , deorphaned );
454+ lfs -> locals .s .deorphaned ^= lfs -> globals .s .deorphaned ^ deorphaned ;
455+ lfs -> globals .s .deorphaned ^= lfs -> globals .s .deorphaned ^ deorphaned ;
487456}
488457
489458
@@ -696,7 +665,8 @@ static int lfs_commitglobals(lfs_t *lfs, struct lfs_commit *commit,
696665
697666 lfs_globalxor (locals , & lfs -> locals );
698667 int err = lfs_commitattr (lfs , commit ,
699- LFS_MKTAG (LFS_TYPE_GLOBALS , 0x3ff , sizeof (lfs_global_t )), locals );
668+ LFS_MKTAG (LFS_TYPE_GLOBALS + locals -> s .deorphaned ,
669+ 0x3ff , sizeof (lfs_global_t )), locals );
700670 lfs_globalxor (locals , & lfs -> locals );
701671 return err ;
702672}
@@ -893,6 +863,7 @@ static int32_t lfs_dir_find(lfs_t *lfs,
893863 }
894864 lfs_pairfromle32 (temptail );
895865 } else if (lfs_tagsubtype (tag ) == LFS_TYPE_GLOBALS ) {
866+ templocals .s .deorphaned = (lfs_tagtype (tag ) & 1 );
896867 err = lfs_bd_read (lfs , dir -> pair [0 ], off + sizeof (tag ),
897868 & templocals , sizeof (templocals ));
898869 if (err ) {
@@ -929,11 +900,11 @@ static int32_t lfs_dir_find(lfs_t *lfs,
929900 // consider what we have good enough
930901 if (dir -> off > 0 ) {
931902 // synthetic move
932- if (lfs_paircmp (dir -> pair , lfs_globalmovepair ( lfs ) ) == 0 ) {
933- if (lfs_globalmoveid ( lfs ) == lfs_tagid (foundtag )) {
903+ if (lfs_paircmp (dir -> pair , lfs -> globals . s . movepair ) == 0 ) {
904+ if (lfs -> globals . s . moveid == lfs_tagid (foundtag )) {
934905 foundtag = LFS_ERR_NOENT ;
935906 } else if (lfs_tagisvalid (foundtag ) &&
936- lfs_globalmoveid ( lfs ) < lfs_tagid (foundtag )) {
907+ lfs -> globals . s . moveid < lfs_tagid (foundtag )) {
937908 foundtag -= LFS_MKTAG (0 , 1 , 0 );
938909 }
939910 }
@@ -963,8 +934,8 @@ static int lfs_dir_fetch(lfs_t *lfs,
963934static int32_t lfs_dir_get (lfs_t * lfs , lfs_mdir_t * dir ,
964935 uint32_t getmask , uint32_t gettag , void * buffer ) {
965936 int32_t getdiff = 0 ;
966- if (lfs_paircmp (dir -> pair , lfs_globalmovepair ( lfs ) ) == 0 &&
967- lfs_tagid (gettag ) <= lfs_globalmoveid ( lfs ) ) {
937+ if (lfs_paircmp (dir -> pair , lfs -> globals . s . movepair ) == 0 &&
938+ lfs_tagid (gettag ) <= lfs -> globals . s . moveid ) {
968939 // synthetic moves
969940 getdiff = LFS_MKTAG (0 , 1 , 0 );
970941 }
@@ -1166,18 +1137,17 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
11661137 lfs_mattr_t cancelattr ;
11671138 lfs_global_t canceldiff ;
11681139 lfs_globalzero (& canceldiff );
1169- if (lfs_paircmp (dir -> pair , lfs_globalmovepair ( lfs ) ) == 0 ) {
1140+ if (lfs_paircmp (dir -> pair , lfs -> globals . s . movepair ) == 0 ) {
11701141 // Wait, we have the move? Just cancel this out here
11711142 // We need to, or else the move can become outdated
1172- lfs_globalxormove (& canceldiff ,
1173- lfs_globalmovepair (lfs ), lfs_globalmoveid (lfs ));
1174- lfs_globalxormove (& canceldiff ,
1175- (lfs_block_t [2 ]){0xffffffff , 0xffffffff }, 0x3ff );
1143+ canceldiff .s .movepair [0 ] ^= lfs -> globals .s .movepair [0 ] ^ 0xffffffff ;
1144+ canceldiff .s .movepair [1 ] ^= lfs -> globals .s .movepair [1 ] ^ 0xffffffff ;
1145+ canceldiff .s .moveid ^= lfs -> globals .s .moveid ^ 0x3ff ;
11761146 lfs_globalfromle32 (& lfs -> locals );
11771147 lfs_globalxor (& lfs -> locals , & canceldiff );
11781148 lfs_globaltole32 (& lfs -> locals );
11791149
1180- cancelattr .tag = LFS_MKTAG (LFS_TYPE_DELETE , lfs_globalmoveid ( lfs ) , 0 );
1150+ cancelattr .tag = LFS_MKTAG (LFS_TYPE_DELETE , lfs -> globals . s . moveid , 0 );
11811151 cancelattr .next = attrs ;
11821152 attrs = & cancelattr ;
11831153 }
@@ -2814,7 +2784,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
28142784 lfs -> root [0 ] = 0xffffffff ;
28152785 lfs -> root [1 ] = 0xffffffff ;
28162786 lfs -> mlist = NULL ;
2817- lfs_globalones (& lfs -> globals );
2787+ lfs -> globals .s .movepair [0 ] = 0xffffffff ;
2788+ lfs -> globals .s .movepair [1 ] = 0xffffffff ;
2789+ lfs -> globals .s .moveid = 0x3ff ;
2790+ lfs -> globals .s .deorphaned = true;
28182791 lfs_globalzero (& lfs -> locals );
28192792
28202793 return 0 ;
@@ -2920,8 +2893,8 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
29202893 lfs_alloc_ack (lfs );
29212894
29222895 // load superblock
2923- lfs_mdir_t dir ;
2924- err = lfs_dir_fetch (lfs , & dir , (const lfs_block_t [2 ]){0 , 1 });
2896+ lfs_mdir_t superdir ;
2897+ err = lfs_dir_fetch (lfs , & superdir , (const lfs_block_t [2 ]){0 , 1 });
29252898 if (err ) {
29262899 if (err == LFS_ERR_CORRUPT ) {
29272900 LFS_ERROR ("Invalid superblock at %d %d" , 0 , 1 );
@@ -2930,7 +2903,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
29302903 }
29312904
29322905 lfs_superblock_t superblock ;
2933- int32_t res = lfs_dir_get (lfs , & dir , 0x7ffff000 ,
2906+ int32_t res = lfs_dir_get (lfs , & superdir , 0x7ffff000 ,
29342907 LFS_MKTAG (LFS_TYPE_SUPERBLOCK , 0 , sizeof (superblock )),
29352908 & superblock );
29362909 if (res < 0 ) {
@@ -2951,7 +2924,7 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
29512924 return LFS_ERR_INVAL ;
29522925 }
29532926
2954- res = lfs_dir_get (lfs , & dir , 0x7ffff000 ,
2927+ res = lfs_dir_get (lfs , & superdir , 0x7ffff000 ,
29552928 LFS_MKTAG (LFS_TYPE_DIRSTRUCT , 0 , sizeof (lfs -> root )),
29562929 & lfs -> root );
29572930 if (res < 0 ) {
@@ -2990,9 +2963,26 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
29902963 }
29912964
29922965 // scan for any global updates
2993- err = lfs_fs_scan (lfs );
2994- if (err ) {
2995- return err ;
2966+ lfs_mdir_t dir = {.tail = {0 , 1 }};
2967+ while (!lfs_pairisnull (dir .tail )) {
2968+ int err = lfs_dir_fetch (lfs , & dir , dir .tail );
2969+ if (err ) {
2970+ return err ;
2971+ }
2972+
2973+ // xor together indirect deletes
2974+ lfs_globalxor (& lfs -> locals , & dir .locals );
2975+ }
2976+
2977+ // update littlefs with globals
2978+ lfs_globalfromle32 (& lfs -> locals );
2979+ lfs_globalxor (& lfs -> globals , & lfs -> locals );
2980+ lfs_globalzero (& lfs -> locals );
2981+ if (!lfs_pairisnull (lfs -> globals .s .movepair )) {
2982+ LFS_DEBUG ("Found move %d %d %d" ,
2983+ lfs -> globals .s .movepair [0 ],
2984+ lfs -> globals .s .movepair [1 ],
2985+ lfs -> globals .s .moveid );
29962986 }
29972987
29982988 return 0 ;
@@ -3186,41 +3176,10 @@ static int lfs_fs_relocate(lfs_t *lfs,
31863176 return 0 ;
31873177}
31883178
3189- static int lfs_fs_scan (lfs_t * lfs ) {
3190- if (lfs_pairisnull (lfs -> root )) {
3191- return 0 ;
3192- }
3193-
3194- // iterate over all directory directory entries
3195- lfs_mdir_t dir = {.tail = {0 , 1 }};
3196- while (!lfs_pairisnull (dir .tail )) {
3197- int err = lfs_dir_fetch (lfs , & dir , dir .tail );
3198- if (err ) {
3199- return err ;
3200- }
3201-
3202- // xor together indirect deletes
3203- lfs_globalxor (& lfs -> locals , & dir .locals );
3204- }
3205-
3206- // update littlefs with globals
3207- lfs_globalfromle32 (& lfs -> locals );
3208- lfs_globalxor (& lfs -> globals , & lfs -> locals );
3209- lfs_globalzero (& lfs -> locals );
3210- if (!lfs_pairisnull (lfs_globalmovepair (lfs ))) {
3211- LFS_DEBUG ("Found move %d %d %d" ,
3212- lfs_globalmovepair (lfs )[0 ],
3213- lfs_globalmovepair (lfs )[1 ],
3214- lfs_globalmoveid (lfs ));
3215- }
3216-
3217- return 0 ;
3218- }
3219-
32203179static int lfs_fs_forceconsistency (lfs_t * lfs ) {
3221- if (!lfs_globalisdeorphaned ( lfs ) ) {
3180+ if (!lfs -> globals . s . deorphaned ) {
32223181 LFS_DEBUG ("Found orphans %d" ,
3223- lfs_globalisdeorphaned ( lfs ) );
3182+ lfs -> globals . s . deorphaned );
32243183
32253184 // Fix any orphans
32263185 lfs_mdir_t pdir = {.split = true};
@@ -3292,16 +3251,16 @@ static int lfs_fs_forceconsistency(lfs_t *lfs) {
32923251 lfs_globaldeorphaned (lfs , false);
32933252 }
32943253
3295- if (lfs_globalmoveid ( lfs ) != 0x3ff ) {
3254+ if (lfs -> globals . s . moveid != 0x3ff ) {
32963255 // Fix bad moves
32973256 LFS_DEBUG ("Fixing move %d %d %d" ,
3298- lfs_globalmovepair ( lfs ) [0 ],
3299- lfs_globalmovepair ( lfs ) [1 ],
3300- lfs_globalmoveid ( lfs ) );
3257+ lfs -> globals . s . movepair [0 ],
3258+ lfs -> globals . s . movepair [1 ],
3259+ lfs -> globals . s . moveid );
33013260
33023261 // fetch and delete the moved entry
33033262 lfs_mdir_t movedir ;
3304- int err = lfs_dir_fetch (lfs , & movedir , lfs_globalmovepair ( lfs ) );
3263+ int err = lfs_dir_fetch (lfs , & movedir , lfs -> globals . s . movepair );
33053264 if (err ) {
33063265 return err ;
33073266 }
0 commit comments