@@ -407,18 +407,15 @@ struct lfs_diskoff {
407
407
408
408
// operations on global state
409
409
static inline void lfs_gstate_xor (lfs_gstate_t * a , const lfs_gstate_t * b ) {
410
- for ( int i = 0 ; i < 3 ; i ++ ) {
411
- (( uint32_t * ) a )[ i ] ^= (( const uint32_t * ) b )[ i ];
412
- }
410
+ a -> tag ^= b -> tag ;
411
+ a -> pair [ 0 ] ^= b -> pair [ 0 ];
412
+ a -> pair [ 1 ] ^= b -> pair [ 1 ];
413
413
}
414
414
415
415
static inline bool lfs_gstate_iszero (const lfs_gstate_t * a ) {
416
- for (int i = 0 ; i < 3 ; i ++ ) {
417
- if (((uint32_t * )a )[i ] != 0 ) {
418
- return false;
419
- }
420
- }
421
- return true;
416
+ return a -> tag == 0
417
+ && a -> pair [0 ] == 0
418
+ && a -> pair [1 ] == 0 ;
422
419
}
423
420
424
421
#ifndef LFS_READONLY
@@ -2374,7 +2371,8 @@ fixmlist:;
2374
2371
if (d -> m .pair != pair ) {
2375
2372
for (int i = 0 ; i < attrcount ; i ++ ) {
2376
2373
if (lfs_tag_type3 (attrs [i ].tag ) == LFS_TYPE_DELETE &&
2377
- d -> id == lfs_tag_id (attrs [i ].tag )) {
2374
+ d -> id == lfs_tag_id (attrs [i ].tag ) &&
2375
+ d -> type != LFS_TYPE_DIR ) {
2378
2376
d -> m .pair [0 ] = LFS_BLOCK_NULL ;
2379
2377
d -> m .pair [1 ] = LFS_BLOCK_NULL ;
2380
2378
} else if (lfs_tag_type3 (attrs [i ].tag ) == LFS_TYPE_DELETE &&
@@ -2563,7 +2561,7 @@ static int lfs_dir_orphaningcommit(lfs_t *lfs, lfs_mdir_t *dir,
2563
2561
if (err != LFS_ERR_NOENT ) {
2564
2562
if (lfs_gstate_hasorphans (& lfs -> gstate )) {
2565
2563
// next step, clean up orphans
2566
- err = lfs_fs_preporphans (lfs , - hasparent );
2564
+ err = lfs_fs_preporphans (lfs , - ( int8_t ) hasparent );
2567
2565
if (err ) {
2568
2566
return err ;
2569
2567
}
@@ -3939,7 +3937,9 @@ static int lfs_remove_(lfs_t *lfs, const char *path) {
3939
3937
}
3940
3938
3941
3939
lfs -> mlist = dir .next ;
3942
- if (lfs_tag_type3 (tag ) == LFS_TYPE_DIR ) {
3940
+ if (lfs_gstate_hasorphans (& lfs -> gstate )) {
3941
+ LFS_ASSERT (lfs_tag_type3 (tag ) == LFS_TYPE_DIR );
3942
+
3943
3943
// fix orphan
3944
3944
err = lfs_fs_preporphans (lfs , -1 );
3945
3945
if (err ) {
@@ -4083,8 +4083,10 @@ static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) {
4083
4083
}
4084
4084
4085
4085
lfs -> mlist = prevdir .next ;
4086
- if (prevtag != LFS_ERR_NOENT
4087
- && lfs_tag_type3 (prevtag ) == LFS_TYPE_DIR ) {
4086
+ if (lfs_gstate_hasorphans (& lfs -> gstate )) {
4087
+ LFS_ASSERT (prevtag != LFS_ERR_NOENT
4088
+ && lfs_tag_type3 (prevtag ) == LFS_TYPE_DIR );
4089
+
4088
4090
// fix orphan
4089
4091
err = lfs_fs_preporphans (lfs , -1 );
4090
4092
if (err ) {
@@ -5240,40 +5242,64 @@ static int lfs_fs_gc_(lfs_t *lfs) {
5240
5242
#endif
5241
5243
5242
5244
#ifndef LFS_READONLY
5245
+ #ifdef LFS_SHRINKNONRELOCATING
5246
+ static int lfs_shrink_checkblock (void * data , lfs_block_t block ) {
5247
+ lfs_size_t threshold = * ((lfs_size_t * )data );
5248
+ if (block >= threshold ) {
5249
+ return LFS_ERR_NOTEMPTY ;
5250
+ }
5251
+ return 0 ;
5252
+ }
5253
+ #endif
5254
+
5243
5255
static int lfs_fs_grow_ (lfs_t * lfs , lfs_size_t block_count ) {
5244
- // shrinking is not supported
5245
- LFS_ASSERT (block_count >= lfs -> block_count );
5256
+ int err ;
5246
5257
5247
- if (block_count > lfs -> block_count ) {
5248
- lfs -> block_count = block_count ;
5258
+ if (block_count == lfs -> block_count ) {
5259
+ return 0 ;
5260
+ }
5249
5261
5250
- // fetch the root
5251
- lfs_mdir_t root ;
5252
- int err = lfs_dir_fetch (lfs , & root , lfs -> root );
5262
+
5263
+ #ifndef LFS_SHRINKNONRELOCATING
5264
+ // shrinking is not supported
5265
+ LFS_ASSERT (block_count >= lfs -> block_count );
5266
+ #endif
5267
+ #ifdef LFS_SHRINKNONRELOCATING
5268
+ if (block_count < lfs -> block_count ) {
5269
+ err = lfs_fs_traverse_ (lfs , lfs_shrink_checkblock , & block_count , true);
5253
5270
if (err ) {
5254
5271
return err ;
5255
5272
}
5273
+ }
5274
+ #endif
5256
5275
5257
- // update the superblock
5258
- lfs_superblock_t superblock ;
5259
- lfs_stag_t tag = lfs_dir_get (lfs , & root , LFS_MKTAG (0x7ff , 0x3ff , 0 ),
5260
- LFS_MKTAG (LFS_TYPE_INLINESTRUCT , 0 , sizeof (superblock )),
5261
- & superblock );
5262
- if (tag < 0 ) {
5263
- return tag ;
5264
- }
5265
- lfs_superblock_fromle32 (& superblock );
5276
+ lfs -> block_count = block_count ;
5266
5277
5267
- superblock .block_count = lfs -> block_count ;
5278
+ // fetch the root
5279
+ lfs_mdir_t root ;
5280
+ err = lfs_dir_fetch (lfs , & root , lfs -> root );
5281
+ if (err ) {
5282
+ return err ;
5283
+ }
5268
5284
5269
- lfs_superblock_tole32 (& superblock );
5270
- err = lfs_dir_commit (lfs , & root , LFS_MKATTRS (
5271
- {tag , & superblock }));
5272
- if (err ) {
5273
- return err ;
5274
- }
5285
+ // update the superblock
5286
+ lfs_superblock_t superblock ;
5287
+ lfs_stag_t tag = lfs_dir_get (lfs , & root , LFS_MKTAG (0x7ff , 0x3ff , 0 ),
5288
+ LFS_MKTAG (LFS_TYPE_INLINESTRUCT , 0 , sizeof (superblock )),
5289
+ & superblock );
5290
+ if (tag < 0 ) {
5291
+ return tag ;
5275
5292
}
5293
+ lfs_superblock_fromle32 (& superblock );
5294
+
5295
+ superblock .block_count = lfs -> block_count ;
5276
5296
5297
+ lfs_superblock_tole32 (& superblock );
5298
+ err = lfs_dir_commit (lfs , & root , LFS_MKATTRS (
5299
+ {tag , & superblock }));
5300
+ if (err ) {
5301
+ return err ;
5302
+ }
5277
5303
return 0 ;
5278
5304
}
5279
5305
#endif
@@ -6293,7 +6319,7 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
6293
6319
6294
6320
lfs_soff_t res = lfs_file_size_ (lfs , file );
6295
6321
6296
- LFS_TRACE ("lfs_file_size -> %" PRId32 , res );
6322
+ LFS_TRACE ("lfs_file_size -> %" PRIu32 , res );
6297
6323
LFS_UNLOCK (lfs -> cfg );
6298
6324
return res ;
6299
6325
}
0 commit comments