@@ -451,31 +451,32 @@ static inline void lfs_global_zero(lfs_global_t *a) {
451
451
}
452
452
453
453
static inline void lfs_global_fromle32 (lfs_global_t * a ) {
454
- lfs_pair_fromle32 (a -> s .movepair );
455
- a -> s .moveid = lfs_fromle16 (a -> s .moveid );
454
+ lfs_pair_fromle32 (a -> l .movepair );
455
+ a -> l .moveid = lfs_fromle16 (a -> l .moveid );
456
456
}
457
457
458
458
static inline void lfs_global_tole32 (lfs_global_t * a ) {
459
- lfs_pair_tole32 (a -> s .movepair );
460
- a -> s .moveid = lfs_tole16 (a -> s .moveid );
459
+ lfs_pair_tole32 (a -> l .movepair );
460
+ a -> l .moveid = lfs_tole16 (a -> l .moveid );
461
461
}
462
462
463
463
static inline void lfs_global_move (lfs_t * lfs ,
464
464
const lfs_block_t pair [2 ], uint16_t id ) {
465
465
lfs_global_t diff ;
466
466
lfs_global_zero (& diff );
467
- diff .s .movepair [0 ] ^= lfs -> globals .s .movepair [0 ] ^ pair [0 ];
468
- diff .s .movepair [1 ] ^= lfs -> globals .s .movepair [1 ] ^ pair [1 ];
469
- diff .s .moveid ^= lfs -> globals .s .moveid ^ id ;
467
+ diff .l .movepair [0 ] ^= lfs -> globals .g .movepair [0 ] ^ pair [0 ];
468
+ diff .l .movepair [1 ] ^= lfs -> globals .g .movepair [1 ] ^ pair [1 ];
469
+ diff .l .moveid ^= lfs -> globals .g .moveid ^ id ;
470
470
lfs_global_fromle32 (& lfs -> locals );
471
471
lfs_global_xor (& lfs -> locals , & diff );
472
472
lfs_global_tole32 (& lfs -> locals );
473
473
lfs_global_xor (& lfs -> globals , & diff );
474
474
}
475
475
476
- static inline void lfs_global_deorphaned (lfs_t * lfs , bool deorphaned ) {
477
- lfs -> locals .s .deorphaned ^= lfs -> globals .s .deorphaned ^ deorphaned ;
478
- lfs -> globals .s .deorphaned ^= lfs -> globals .s .deorphaned ^ deorphaned ;
476
+ static inline void lfs_global_orphans (lfs_t * lfs , int8_t orphans ) {
477
+ lfs -> locals .l .deorphaned ^= (lfs -> globals .g .orphans == 0 );
478
+ lfs -> locals .l .deorphaned ^= (lfs -> globals .g .orphans + orphans == 0 );
479
+ lfs -> globals .g .orphans += orphans ;
479
480
}
480
481
481
482
@@ -688,7 +689,7 @@ static int lfs_commit_globals(lfs_t *lfs, struct lfs_commit *commit,
688
689
689
690
lfs_global_xor (locals , & lfs -> locals );
690
691
int err = lfs_commit_attr (lfs , commit ,
691
- LFS_MKTAG (LFS_TYPE_GLOBALS + locals -> s .deorphaned , 0x3ff , 10 ),
692
+ LFS_MKTAG (LFS_TYPE_GLOBALS + locals -> l .deorphaned , 0x3ff , 10 ),
692
693
locals );
693
694
lfs_global_xor (locals , & lfs -> locals );
694
695
return err ;
@@ -907,7 +908,7 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
907
908
}
908
909
lfs_pair_fromle32 (temptail );
909
910
} else if (lfs_tag_subtype (tag ) == LFS_TYPE_GLOBALS ) {
910
- templocals .s .deorphaned = (lfs_tag_type (tag ) & 1 );
911
+ templocals .l .deorphaned = (lfs_tag_type (tag ) & 1 );
911
912
err = lfs_bd_read (lfs , dir -> pair [0 ], off + sizeof (tag ),
912
913
& templocals , 10 );
913
914
if (err ) {
@@ -973,11 +974,11 @@ static int32_t lfs_dir_fetchmatch(lfs_t *lfs,
973
974
// consider what we have good enough
974
975
if (dir -> off > 0 ) {
975
976
// synthetic move
976
- if (lfs_pair_cmp (dir -> pair , lfs -> globals .s .movepair ) == 0 ) {
977
- if (lfs -> globals .s .moveid == lfs_tag_id (foundtag )) {
977
+ if (lfs_pair_cmp (dir -> pair , lfs -> globals .g .movepair ) == 0 ) {
978
+ if (lfs -> globals .g .moveid == lfs_tag_id (foundtag )) {
978
979
foundtag = LFS_ERR_NOENT ;
979
980
} else if (lfs_tag_isvalid (foundtag ) &&
980
- lfs -> globals .s .moveid < lfs_tag_id (foundtag )) {
981
+ lfs -> globals .g .moveid < lfs_tag_id (foundtag )) {
981
982
foundtag -= LFS_MKTAG (0 , 1 , 0 );
982
983
}
983
984
}
@@ -1026,8 +1027,8 @@ static int32_t lfs_dir_find(lfs_t *lfs,
1026
1027
static int32_t lfs_dir_get (lfs_t * lfs , lfs_mdir_t * dir ,
1027
1028
uint32_t getmask , uint32_t gettag , void * buffer ) {
1028
1029
int32_t getdiff = 0 ;
1029
- if (lfs_pair_cmp (dir -> pair , lfs -> globals .s .movepair ) == 0 &&
1030
- lfs_tag_id (gettag ) <= lfs -> globals .s .moveid ) {
1030
+ if (lfs_pair_cmp (dir -> pair , lfs -> globals .g .movepair ) == 0 &&
1031
+ lfs_tag_id (gettag ) <= lfs -> globals .g .moveid ) {
1031
1032
// synthetic moves
1032
1033
getdiff = LFS_MKTAG (0 , 1 , 0 );
1033
1034
}
@@ -1270,17 +1271,17 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir,
1270
1271
lfs_mattr_t cancelattr ;
1271
1272
lfs_global_t canceldiff ;
1272
1273
lfs_global_zero (& canceldiff );
1273
- if (lfs_pair_cmp (dir -> pair , lfs -> globals .s .movepair ) == 0 ) {
1274
+ if (lfs_pair_cmp (dir -> pair , lfs -> globals .g .movepair ) == 0 ) {
1274
1275
// Wait, we have the move? Just cancel this out here
1275
1276
// We need to, or else the move can become outdated
1276
- canceldiff .s .movepair [0 ] ^= lfs -> globals .s .movepair [0 ] ^ 0xffffffff ;
1277
- canceldiff .s .movepair [1 ] ^= lfs -> globals .s .movepair [1 ] ^ 0xffffffff ;
1278
- canceldiff .s .moveid ^= lfs -> globals .s .moveid ^ 0x3ff ;
1277
+ canceldiff .l .movepair [0 ] ^= lfs -> globals .g .movepair [0 ] ^ 0xffffffff ;
1278
+ canceldiff .l .movepair [1 ] ^= lfs -> globals .g .movepair [1 ] ^ 0xffffffff ;
1279
+ canceldiff .l .moveid ^= lfs -> globals .g .moveid ^ 0x3ff ;
1279
1280
lfs_global_fromle32 (& lfs -> locals );
1280
1281
lfs_global_xor (& lfs -> locals , & canceldiff );
1281
1282
lfs_global_tole32 (& lfs -> locals );
1282
1283
1283
- cancelattr .tag = LFS_MKTAG (LFS_TYPE_DELETE , lfs -> globals .s .moveid , 0 );
1284
+ cancelattr .tag = LFS_MKTAG (LFS_TYPE_DELETE , lfs -> globals .l .moveid , 0 );
1284
1285
cancelattr .next = attrs ;
1285
1286
attrs = & cancelattr ;
1286
1287
}
@@ -2636,7 +2637,7 @@ int lfs_remove(lfs_t *lfs, const char *path) {
2636
2637
}
2637
2638
2638
2639
// mark fs as orphaned
2639
- lfs_global_deorphaned (lfs , false );
2640
+ lfs_global_orphans (lfs , +1 );
2640
2641
}
2641
2642
2642
2643
// delete the entry
@@ -2648,14 +2649,14 @@ int lfs_remove(lfs_t *lfs, const char *path) {
2648
2649
}
2649
2650
2650
2651
if (lfs_tag_type (tag ) == LFS_TYPE_DIR ) {
2652
+ // fix orphan
2653
+ lfs_global_orphans (lfs , -1 );
2654
+
2651
2655
err = lfs_fs_pred (lfs , dir .pair , & cwd );
2652
2656
if (err ) {
2653
2657
return err ;
2654
2658
}
2655
2659
2656
- // fix orphan
2657
- lfs_global_deorphaned (lfs , true);
2658
-
2659
2660
// steal state
2660
2661
cwd .tail [0 ] = dir .tail [0 ];
2661
2662
cwd .tail [1 ] = dir .tail [1 ];
@@ -2696,36 +2697,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
2696
2697
uint16_t newid = lfs_tag_id (prevtag );
2697
2698
2698
2699
lfs_mdir_t prevdir ;
2699
- if (prevtag != LFS_ERR_NOENT ) {
2700
- // check that we have same type
2701
- if (lfs_tag_type (prevtag ) != lfs_tag_type (oldtag )) {
2702
- return LFS_ERR_ISDIR ;
2703
- }
2704
-
2705
- if (lfs_tag_type (prevtag ) == LFS_TYPE_DIR ) {
2706
- // must be empty before removal
2707
- lfs_block_t prevpair [2 ];
2708
- int32_t res = lfs_dir_get (lfs , & newcwd , 0x7c3ff000 ,
2709
- LFS_MKTAG (LFS_TYPE_STRUCT , newid , 8 ), prevpair );
2710
- if (res < 0 ) {
2711
- return res ;
2712
- }
2713
- lfs_pair_fromle32 (prevpair );
2714
-
2715
- // must be empty before removal
2716
- err = lfs_dir_fetch (lfs , & prevdir , prevpair );
2717
- if (err ) {
2718
- return err ;
2719
- }
2720
-
2721
- if (prevdir .count > 0 || prevdir .split ) {
2722
- return LFS_ERR_NOTEMPTY ;
2723
- }
2724
-
2725
- // mark fs as orphaned
2726
- lfs_global_deorphaned (lfs , false);
2727
- }
2728
- } else {
2700
+ if (prevtag == LFS_ERR_NOENT ) {
2729
2701
// check that name fits
2730
2702
lfs_size_t nlen = strlen (newpath );
2731
2703
if (nlen > lfs -> name_max ) {
@@ -2734,6 +2706,30 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
2734
2706
2735
2707
// get next id
2736
2708
newid = newcwd .count ;
2709
+ } else if (lfs_tag_type (prevtag ) != lfs_tag_type (oldtag )) {
2710
+ return LFS_ERR_ISDIR ;
2711
+ } else if (lfs_tag_type (prevtag ) == LFS_TYPE_DIR ) {
2712
+ // must be empty before removal
2713
+ lfs_block_t prevpair [2 ];
2714
+ int32_t res = lfs_dir_get (lfs , & newcwd , 0x7c3ff000 ,
2715
+ LFS_MKTAG (LFS_TYPE_STRUCT , newid , 8 ), prevpair );
2716
+ if (res < 0 ) {
2717
+ return res ;
2718
+ }
2719
+ lfs_pair_fromle32 (prevpair );
2720
+
2721
+ // must be empty before removal
2722
+ err = lfs_dir_fetch (lfs , & prevdir , prevpair );
2723
+ if (err ) {
2724
+ return err ;
2725
+ }
2726
+
2727
+ if (prevdir .count > 0 || prevdir .split ) {
2728
+ return LFS_ERR_NOTEMPTY ;
2729
+ }
2730
+
2731
+ // mark fs as orphaned
2732
+ lfs_global_orphans (lfs , +1 );
2737
2733
}
2738
2734
2739
2735
// create move to fix later
@@ -2758,14 +2754,14 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
2758
2754
}
2759
2755
2760
2756
if (prevtag != LFS_ERR_NOENT && lfs_tag_type (prevtag ) == LFS_TYPE_DIR ) {
2757
+ // fix orphan
2758
+ lfs_global_orphans (lfs , -1 );
2759
+
2761
2760
err = lfs_fs_pred (lfs , prevdir .pair , & newcwd );
2762
2761
if (err ) {
2763
2762
return err ;
2764
2763
}
2765
2764
2766
- // fix orphan
2767
- lfs_global_deorphaned (lfs , true);
2768
-
2769
2765
// steal state
2770
2766
newcwd .tail [0 ] = prevdir .tail [0 ];
2771
2767
newcwd .tail [1 ] = prevdir .tail [1 ];
@@ -2917,10 +2913,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
2917
2913
lfs -> root [1 ] = 0xffffffff ;
2918
2914
lfs -> mlist = NULL ;
2919
2915
lfs -> seed = 0 ;
2920
- lfs -> globals .s .movepair [0 ] = 0xffffffff ;
2921
- lfs -> globals .s .movepair [1 ] = 0xffffffff ;
2922
- lfs -> globals .s .moveid = 0x3ff ;
2923
- lfs -> globals .s . deorphaned = true ;
2916
+ lfs -> globals .g .movepair [0 ] = 0xffffffff ;
2917
+ lfs -> globals .g .movepair [1 ] = 0xffffffff ;
2918
+ lfs -> globals .g .moveid = 0x3ff ;
2919
+ lfs -> globals .g . orphans = 0 ;
2924
2920
lfs_global_zero (& lfs -> locals );
2925
2921
2926
2922
return 0 ;
@@ -3089,11 +3085,11 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
3089
3085
lfs_global_fromle32 (& lfs -> locals );
3090
3086
lfs_global_xor (& lfs -> globals , & lfs -> locals );
3091
3087
lfs_global_zero (& lfs -> locals );
3092
- if (!lfs_pair_isnull (lfs -> globals .s .movepair )) {
3088
+ if (!lfs_pair_isnull (lfs -> globals .g .movepair )) {
3093
3089
LFS_DEBUG ("Found move %" PRIu32 " %" PRIu32 " %" PRIu32 ,
3094
- lfs -> globals .s .movepair [0 ],
3095
- lfs -> globals .s .movepair [1 ],
3096
- lfs -> globals .s .moveid );
3090
+ lfs -> globals .g .movepair [0 ],
3091
+ lfs -> globals .g .movepair [1 ],
3092
+ lfs -> globals .g .moveid );
3097
3093
}
3098
3094
3099
3095
// setup free lookahead
@@ -3254,7 +3250,8 @@ static int lfs_fs_relocate(lfs_t *lfs,
3254
3250
3255
3251
if (tag != LFS_ERR_NOENT ) {
3256
3252
// update disk, this creates a desync
3257
- lfs_global_deorphaned (lfs , false);
3253
+ lfs_global_orphans (lfs , +1 );
3254
+
3258
3255
lfs_pair_tole32 (newpair );
3259
3256
int err = lfs_dir_commit (lfs , & parent ,
3260
3257
& (lfs_mattr_t ){.tag = tag , .buffer = newpair });
@@ -3263,8 +3260,8 @@ static int lfs_fs_relocate(lfs_t *lfs,
3263
3260
return err ;
3264
3261
}
3265
3262
3266
- // clean up bad block, which should now be a desync
3267
- return lfs_fs_deorphan (lfs );
3263
+ // next step, clean up orphans
3264
+ lfs_global_orphans (lfs , -1 );
3268
3265
}
3269
3266
3270
3267
// find pred
@@ -3275,7 +3272,7 @@ static int lfs_fs_relocate(lfs_t *lfs,
3275
3272
3276
3273
// if we can't find dir, it must be new
3277
3274
if (err != LFS_ERR_NOENT ) {
3278
- // just replace bad pair, no desync can occur
3275
+ // replace bad pair, either we clean up desync, or no desync occured
3279
3276
parent .tail [0 ] = newpair [0 ];
3280
3277
parent .tail [1 ] = newpair [1 ];
3281
3278
err = lfs_dir_commit (lfs , & parent ,
@@ -3359,20 +3356,20 @@ static int lfs_fs_deorphan(lfs_t *lfs) {
3359
3356
}
3360
3357
3361
3358
// mark orphans as fixed
3362
- lfs_global_deorphaned (lfs , true );
3359
+ lfs_global_orphans (lfs , - lfs -> globals . g . orphans );
3363
3360
return 0 ;
3364
3361
}
3365
3362
3366
3363
static int lfs_fs_demove (lfs_t * lfs ) {
3367
3364
// Fix bad moves
3368
3365
LFS_DEBUG ("Fixing move %" PRIu32 " %" PRIu32 " %" PRIu32 ,
3369
- lfs -> globals .s .movepair [0 ],
3370
- lfs -> globals .s .movepair [1 ],
3371
- lfs -> globals .s .moveid );
3366
+ lfs -> globals .g .movepair [0 ],
3367
+ lfs -> globals .g .movepair [1 ],
3368
+ lfs -> globals .g .moveid );
3372
3369
3373
3370
// fetch and delete the moved entry
3374
3371
lfs_mdir_t movedir ;
3375
- int err = lfs_dir_fetch (lfs , & movedir , lfs -> globals .s .movepair );
3372
+ int err = lfs_dir_fetch (lfs , & movedir , lfs -> globals .g .movepair );
3376
3373
if (err ) {
3377
3374
return err ;
3378
3375
}
@@ -3387,14 +3384,14 @@ static int lfs_fs_demove(lfs_t *lfs) {
3387
3384
}
3388
3385
3389
3386
static int lfs_fs_forceconsistency (lfs_t * lfs ) {
3390
- if (! lfs -> globals .s . deorphaned ) {
3387
+ if (lfs -> globals .g . orphans ) {
3391
3388
int err = lfs_fs_deorphan (lfs );
3392
3389
if (err ) {
3393
3390
return err ;
3394
3391
}
3395
3392
}
3396
3393
3397
- if (lfs -> globals .s .moveid != 0x3ff ) {
3394
+ if (lfs -> globals .g .moveid != 0x3ff ) {
3398
3395
int err = lfs_fs_demove (lfs );
3399
3396
if (err ) {
3400
3397
return err ;
0 commit comments