@@ -593,19 +593,6 @@ static int lfs_rawunmount(lfs_t *lfs);
593593
594594
595595/// Block allocator /// 
596- #ifndef  LFS_READONLY 
597- static  int  lfs_alloc_lookahead (void  * p , lfs_block_t  block ) {
598-     lfs_t  * lfs  =  (lfs_t * )p ;
599-     lfs_block_t  off  =  ((block  -  lfs -> lookahead .start )
600-             +  lfs -> block_count ) % lfs -> block_count ;
601- 
602-     if  (off  <  lfs -> lookahead .size ) {
603-         lfs -> lookahead .buffer [off  / 8 ] |= 1U  << (off  % 8 );
604-     }
605- 
606-     return  0 ;
607- }
608- #endif 
609596
610597// allocations should call this when all allocated blocks are committed to 
611598// the filesystem 
@@ -624,7 +611,21 @@ static void lfs_alloc_drop(lfs_t *lfs) {
624611}
625612
626613#ifndef  LFS_READONLY 
627- static  int  lfs_fs_rawgc (lfs_t  * lfs ) {
614+ static  int  lfs_alloc_lookahead (void  * p , lfs_block_t  block ) {
615+     lfs_t  * lfs  =  (lfs_t * )p ;
616+     lfs_block_t  off  =  ((block  -  lfs -> lookahead .start )
617+             +  lfs -> block_count ) % lfs -> block_count ;
618+ 
619+     if  (off  <  lfs -> lookahead .size ) {
620+         lfs -> lookahead .buffer [off  / 8 ] |= 1U  << (off  % 8 );
621+     }
622+ 
623+     return  0 ;
624+ }
625+ #endif 
626+ 
627+ #ifndef  LFS_READONLY 
628+ static  int  lfs_alloc_scan (lfs_t  * lfs ) {
628629    // move lookahead buffer to the first unused block 
629630    // 
630631    // note we limit the lookahead buffer to at most the amount of blocks 
@@ -693,7 +694,7 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
693694
694695        // No blocks in our lookahead buffer, we need to scan the filesystem for 
695696        // unused blocks in the next lookahead window. 
696-         int  err  =  lfs_fs_rawgc (lfs );
697+         int  err  =  lfs_alloc_scan (lfs );
697698        if (err ) {
698699            return  err ;
699700        }
@@ -4189,6 +4190,14 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
41894190    // wear-leveling. 
41904191    LFS_ASSERT (lfs -> cfg -> block_cycles  !=  0 );
41914192
4193+     // check that compact_thresh makes sense 
4194+     // 
4195+     // metadata can't be compacted below block_size/2, and metadata can't 
4196+     // exceed a block_size 
4197+     LFS_ASSERT (lfs -> cfg -> compact_thresh  ==  0 
4198+             ||  lfs -> cfg -> compact_thresh  >= lfs -> cfg -> block_size /2 );
4199+     LFS_ASSERT (lfs -> cfg -> compact_thresh  ==  (lfs_size_t )- 1 
4200+             ||  lfs -> cfg -> compact_thresh  <= lfs -> cfg -> block_size );
41924201
41934202    // setup read cache 
41944203    if  (lfs -> cfg -> read_buffer ) {
@@ -5080,6 +5089,57 @@ static lfs_ssize_t lfs_fs_rawsize(lfs_t *lfs) {
50805089    return  size ;
50815090}
50825091
5092+ // explicit garbage collection 
5093+ #ifndef  LFS_READONLY 
5094+ static  int  lfs_fs_rawgc (lfs_t  * lfs ) {
5095+     // force consistency, even if we're not necessarily going to write, 
5096+     // because this function is supposed to take care of janitorial work 
5097+     // isn't it? 
5098+     int  err  =  lfs_fs_forceconsistency (lfs );
5099+     if  (err ) {
5100+         return  err ;
5101+     }
5102+ 
5103+     // try to compact metadata pairs, note we can't really accomplish 
5104+     // anything if compact_thresh doesn't at least leave a prog_size 
5105+     // available 
5106+     if  (lfs -> cfg -> compact_thresh 
5107+             <  lfs -> cfg -> block_size  -  lfs -> cfg -> prog_size ) {
5108+         // iterate over all mdirs 
5109+         lfs_mdir_t  mdir  =  {.tail  =  {0 , 1 }};
5110+         while  (!lfs_pair_isnull (mdir .tail )) {
5111+             err  =  lfs_dir_fetch (lfs , & mdir , mdir .tail );
5112+             if  (err ) {
5113+                 return  err ;
5114+             }
5115+ 
5116+             // not erased? exceeds our compaction threshold? 
5117+             if  (!mdir .erased  ||  ((lfs -> cfg -> compact_thresh  ==  0 )
5118+                     ? mdir .off  >  lfs -> cfg -> block_size  -  lfs -> cfg -> block_size /8 
5119+                     : mdir .off  >  lfs -> cfg -> compact_thresh )) {
5120+                 // the easiest way to trigger a compaction is to mark 
5121+                 // the mdir as unerased and add an empty commit 
5122+                 mdir .erased  =  false;
5123+                 err  =  lfs_dir_commit (lfs , & mdir , NULL , 0 );
5124+                 if  (err ) {
5125+                     return  err ;
5126+                 }
5127+             }
5128+         }
5129+     }
5130+ 
5131+     // try to populate the lookahead buffer, unless it's already full 
5132+     if  (lfs -> lookahead .size  <  8 * lfs -> cfg -> lookahead_size ) {
5133+         err  =  lfs_alloc_scan (lfs );
5134+         if  (err ) {
5135+             return  err ;
5136+         }
5137+     }
5138+ 
5139+     return  0 ;
5140+ }
5141+ #endif 
5142+ 
50835143#ifndef  LFS_READONLY 
50845144static  int  lfs_fs_rawgrow (lfs_t  * lfs , lfs_size_t  block_count ) {
50855145    // shrinking is not supported 
@@ -6286,32 +6346,32 @@ int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void *, lfs_block_t), void *data) {
62866346}
62876347
62886348#ifndef  LFS_READONLY 
6289- int  lfs_fs_gc (lfs_t  * lfs ) {
6349+ int  lfs_fs_mkconsistent (lfs_t  * lfs ) {
62906350    int  err  =  LFS_LOCK (lfs -> cfg );
62916351    if  (err ) {
62926352        return  err ;
62936353    }
6294-     LFS_TRACE ("lfs_fs_gc (%p)" , (void * )lfs );
6354+     LFS_TRACE ("lfs_fs_mkconsistent (%p)" , (void * )lfs );
62956355
6296-     err  =  lfs_fs_rawgc (lfs );
6356+     err  =  lfs_fs_rawmkconsistent (lfs );
62976357
6298-     LFS_TRACE ("lfs_fs_gc  -> %d" , err );
6358+     LFS_TRACE ("lfs_fs_mkconsistent  -> %d" , err );
62996359    LFS_UNLOCK (lfs -> cfg );
63006360    return  err ;
63016361}
63026362#endif 
63036363
63046364#ifndef  LFS_READONLY 
6305- int  lfs_fs_mkconsistent (lfs_t  * lfs ) {
6365+ int  lfs_fs_gc (lfs_t  * lfs ) {
63066366    int  err  =  LFS_LOCK (lfs -> cfg );
63076367    if  (err ) {
63086368        return  err ;
63096369    }
6310-     LFS_TRACE ("lfs_fs_mkconsistent (%p)" , (void * )lfs );
6370+     LFS_TRACE ("lfs_fs_gc (%p)" , (void * )lfs );
63116371
6312-     err  =  lfs_fs_rawmkconsistent (lfs );
6372+     err  =  lfs_fs_rawgc (lfs );
63136373
6314-     LFS_TRACE ("lfs_fs_mkconsistent  -> %d" , err );
6374+     LFS_TRACE ("lfs_fs_gc  -> %d" , err );
63156375    LFS_UNLOCK (lfs -> cfg );
63166376    return  err ;
63176377}
0 commit comments