@@ -3932,7 +3932,9 @@ static int lfs2_remove_(lfs2_t *lfs2, const char *path) {
3932
3932
}
3933
3933
3934
3934
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
+
3936
3938
// fix orphan
3937
3939
err = lfs2_fs_preporphans (lfs2 , -1 );
3938
3940
if (err ) {
@@ -4076,8 +4078,10 @@ static int lfs2_rename_(lfs2_t *lfs2, const char *oldpath, const char *newpath)
4076
4078
}
4077
4079
4078
4080
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
+
4081
4085
// fix orphan
4082
4086
err = lfs2_fs_preporphans (lfs2 , -1 );
4083
4087
if (err ) {
@@ -5233,40 +5237,64 @@ static int lfs2_fs_gc_(lfs2_t *lfs2) {
5233
5237
#endif
5234
5238
5235
5239
#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
+
5236
5250
static 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 ;
5239
5252
5240
- if (block_count > lfs2 -> block_count ) {
5241
- lfs2 -> block_count = block_count ;
5253
+ if (block_count == lfs2 -> block_count ) {
5254
+ return 0 ;
5255
+ }
5242
5256
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);
5246
5265
if (err ) {
5247
5266
return err ;
5248
5267
}
5268
+ }
5269
+ #endif
5249
5270
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 ;
5259
5272
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
+ }
5261
5279
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 ;
5268
5287
}
5288
+ lfs2_superblock_fromle32 (& superblock );
5289
+
5290
+ superblock .block_count = lfs2 -> block_count ;
5269
5291
5292
+ lfs2_superblock_tole32 (& superblock );
5293
+ err = lfs2_dir_commit (lfs2 , & root , LFS2_MKATTRS (
5294
+ {tag , & superblock }));
5295
+ if (err ) {
5296
+ return err ;
5297
+ }
5270
5298
return 0 ;
5271
5299
}
5272
5300
#endif
0 commit comments