@@ -3932,7 +3932,9 @@ static int lfs_remove_(lfs_t *lfs, const char *path) {
39323932 }
39333933
39343934 lfs -> mlist = dir .next ;
3935- if (lfs_tag_type3 (tag ) == LFS_TYPE_DIR ) {
3935+ if (lfs_gstate_hasorphans (& lfs -> gstate )) {
3936+ LFS_ASSERT (lfs_tag_type3 (tag ) == LFS_TYPE_DIR );
3937+
39363938 // fix orphan
39373939 err = lfs_fs_preporphans (lfs , -1 );
39383940 if (err ) {
@@ -4076,8 +4078,10 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
40764078 }
40774079
40784080 lfs -> mlist = prevdir .next ;
4079- if (prevtag != LFS_ERR_NOENT
4080- && lfs_tag_type3 (prevtag ) == LFS_TYPE_DIR ) {
4081+ if (lfs_gstate_hasorphans (& lfs -> gstate )) {
4082+ LFS_ASSERT (prevtag != LFS_ERR_NOENT
4083+ && lfs_tag_type3 (prevtag ) == LFS_TYPE_DIR );
4084+
40814085 // fix orphan
40824086 err = lfs_fs_preporphans (lfs , -1 );
40834087 if (err ) {
@@ -5233,40 +5237,64 @@ static int lfs_fs_gc_(lfs_t *lfs) {
52335237#endif
52345238
52355239#ifndef LFS_READONLY
5240+ #ifdef LFS_SHRINKNONRELOCATING
5241+ static int lfs_shrink_checkblock (void * data , lfs_block_t block ) {
5242+ lfs_size_t threshold = * ((lfs_size_t * )data );
5243+ if (block >= threshold ) {
5244+ return LFS_ERR_NOTEMPTY ;
5245+ }
5246+ return 0 ;
5247+ }
5248+ #endif
5249+
52365250static int lfs_fs_grow_ (lfs_t * lfs , lfs_size_t block_count ) {
5237- // shrinking is not supported
5238- LFS_ASSERT (block_count >= lfs -> block_count );
5251+ int err ;
52395252
5240- if (block_count > lfs -> block_count ) {
5241- lfs -> block_count = block_count ;
5253+ if (block_count == lfs -> block_count ) {
5254+ return 0 ;
5255+ }
52425256
5243- // fetch the root
5244- lfs_mdir_t root ;
5245- int err = lfs_dir_fetch (lfs , & root , lfs -> root );
5257+
5258+ #ifndef LFS_SHRINKNONRELOCATING
5259+ // shrinking is not supported
5260+ LFS_ASSERT (block_count >= lfs -> block_count );
5261+ #endif
5262+ #ifdef LFS_SHRINKNONRELOCATING
5263+ if (block_count < lfs -> block_count ) {
5264+ err = lfs_fs_traverse_ (lfs , lfs_shrink_checkblock , & block_count , true);
52465265 if (err ) {
52475266 return err ;
52485267 }
5268+ }
5269+ #endif
52495270
5250- // update the superblock
5251- lfs_superblock_t superblock ;
5252- lfs_stag_t tag = lfs_dir_get (lfs , & root , LFS_MKTAG (0x7ff , 0x3ff , 0 ),
5253- LFS_MKTAG (LFS_TYPE_INLINESTRUCT , 0 , sizeof (superblock )),
5254- & superblock );
5255- if (tag < 0 ) {
5256- return tag ;
5257- }
5258- lfs_superblock_fromle32 (& superblock );
5271+ lfs -> block_count = block_count ;
52595272
5260- superblock .block_count = lfs -> block_count ;
5273+ // fetch the root
5274+ lfs_mdir_t root ;
5275+ err = lfs_dir_fetch (lfs , & root , lfs -> root );
5276+ if (err ) {
5277+ return err ;
5278+ }
52615279
5262- lfs_superblock_tole32 (& superblock );
5263- err = lfs_dir_commit (lfs , & root , LFS_MKATTRS (
5264- {tag , & superblock }));
5265- if (err ) {
5266- return err ;
5267- }
5280+ // update the superblock
5281+ lfs_superblock_t superblock ;
5282+ lfs_stag_t tag = lfs_dir_get (lfs , & root , LFS_MKTAG (0x7ff , 0x3ff , 0 ),
5283+ LFS_MKTAG (LFS_TYPE_INLINESTRUCT , 0 , sizeof (superblock )),
5284+ & superblock );
5285+ if (tag < 0 ) {
5286+ return tag ;
52685287 }
5288+ lfs_superblock_fromle32 (& superblock );
5289+
5290+ superblock .block_count = lfs -> block_count ;
52695291
5292+ lfs_superblock_tole32 (& superblock );
5293+ err = lfs_dir_commit (lfs , & root , LFS_MKATTRS (
5294+ {tag , & superblock }));
5295+ if (err ) {
5296+ return err ;
5297+ }
52705298 return 0 ;
52715299}
52725300#endif
0 commit comments