@@ -3932,7 +3932,9 @@ static int lfs2_remove_(lfs2_t *lfs2, const char *path) {
39323932 }
39333933
39343934 lfs2 -> mlist = dir .next ;
3935- if (lfs2_tag_type3 (tag ) == LFS2_TYPE_DIR ) {
3935+ if (lfs2_gstate_hasorphans (& lfs2 -> gstate )) {
3936+ LFS2_ASSERT (lfs2_tag_type3 (tag ) == LFS2_TYPE_DIR );
3937+
39363938 // fix orphan
39373939 err = lfs2_fs_preporphans (lfs2 , -1 );
39383940 if (err ) {
@@ -4076,8 +4078,10 @@ static int lfs2_rename_(lfs2_t *lfs2, const char *oldpath, const char *newpath)
40764078 }
40774079
40784080 lfs2 -> mlist = prevdir .next ;
4079- if (prevtag != LFS2_ERR_NOENT
4080- && lfs2_tag_type3 (prevtag ) == LFS2_TYPE_DIR ) {
4081+ if (lfs2_gstate_hasorphans (& lfs2 -> gstate )) {
4082+ LFS2_ASSERT (prevtag != LFS2_ERR_NOENT
4083+ && lfs2_tag_type3 (prevtag ) == LFS2_TYPE_DIR );
4084+
40814085 // fix orphan
40824086 err = lfs2_fs_preporphans (lfs2 , -1 );
40834087 if (err ) {
@@ -5233,40 +5237,64 @@ static int lfs2_fs_gc_(lfs2_t *lfs2) {
52335237#endif
52345238
52355239#ifndef LFS2_READONLY
5240+ #ifdef LFS2_SHRINKNONRELOCATING
5241+ static int lfs2_shrink_checkblock (void * data , lfs2_block_t block ) {
5242+ lfs2_size_t threshold = * ((lfs2_size_t * )data );
5243+ if (block >= threshold ) {
5244+ return LFS2_ERR_NOTEMPTY ;
5245+ }
5246+ return 0 ;
5247+ }
5248+ #endif
5249+
52365250static int lfs2_fs_grow_ (lfs2_t * lfs2 , lfs2_size_t block_count ) {
5237- // shrinking is not supported
5238- LFS2_ASSERT (block_count >= lfs2 -> block_count );
5251+ int err ;
52395252
5240- if (block_count > lfs2 -> block_count ) {
5241- lfs2 -> block_count = block_count ;
5253+ if (block_count == lfs2 -> block_count ) {
5254+ return 0 ;
5255+ }
52425256
5243- // fetch the root
5244- lfs2_mdir_t root ;
5245- int err = lfs2_dir_fetch (lfs2 , & root , lfs2 -> root );
5257+
5258+ #ifndef LFS2_SHRINKNONRELOCATING
5259+ // shrinking is not supported
5260+ LFS2_ASSERT (block_count >= lfs2 -> block_count );
5261+ #endif
5262+ #ifdef LFS2_SHRINKNONRELOCATING
5263+ if (block_count < lfs2 -> block_count ) {
5264+ err = lfs2_fs_traverse_ (lfs2 , lfs2_shrink_checkblock , & block_count , true);
52465265 if (err ) {
52475266 return err ;
52485267 }
5268+ }
5269+ #endif
52495270
5250- // update the superblock
5251- lfs2_superblock_t superblock ;
5252- lfs2_stag_t tag = lfs2_dir_get (lfs2 , & root , LFS2_MKTAG (0x7ff , 0x3ff , 0 ),
5253- LFS2_MKTAG (LFS2_TYPE_INLINESTRUCT , 0 , sizeof (superblock )),
5254- & superblock );
5255- if (tag < 0 ) {
5256- return tag ;
5257- }
5258- lfs2_superblock_fromle32 (& superblock );
5271+ lfs2 -> block_count = block_count ;
52595272
5260- superblock .block_count = lfs2 -> block_count ;
5273+ // fetch the root
5274+ lfs2_mdir_t root ;
5275+ err = lfs2_dir_fetch (lfs2 , & root , lfs2 -> root );
5276+ if (err ) {
5277+ return err ;
5278+ }
52615279
5262- lfs2_superblock_tole32 (& superblock );
5263- err = lfs2_dir_commit (lfs2 , & root , LFS2_MKATTRS (
5264- {tag , & superblock }));
5265- if (err ) {
5266- return err ;
5267- }
5280+ // update the superblock
5281+ lfs2_superblock_t superblock ;
5282+ lfs2_stag_t tag = lfs2_dir_get (lfs2 , & root , LFS2_MKTAG (0x7ff , 0x3ff , 0 ),
5283+ LFS2_MKTAG (LFS2_TYPE_INLINESTRUCT , 0 , sizeof (superblock )),
5284+ & superblock );
5285+ if (tag < 0 ) {
5286+ return tag ;
52685287 }
5288+ lfs2_superblock_fromle32 (& superblock );
5289+
5290+ superblock .block_count = lfs2 -> block_count ;
52695291
5292+ lfs2_superblock_tole32 (& superblock );
5293+ err = lfs2_dir_commit (lfs2 , & root , LFS2_MKATTRS (
5294+ {tag , & superblock }));
5295+ if (err ) {
5296+ return err ;
5297+ }
52705298 return 0 ;
52715299}
52725300#endif
0 commit comments