@@ -721,16 +721,18 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit,
721
721
722
722
static int lfs_commit_globals (lfs_t * lfs , struct lfs_commit * commit ,
723
723
const lfs_globals_t * source , const lfs_globals_t * diff ) {
724
- lfs_globals_t res = lfs_globals_xor (source , diff );
724
+ if (lfs_globals_iszero (diff )) {
725
+ return 0 ;
726
+ }
725
727
726
- if (! lfs_globals_iszero ( & res )) {
727
- int err = lfs_commit_commit ( lfs , commit , ( lfs_mattr_t ){
728
- lfs_mktag ( LFS_TYPE_IDELETE ,
729
- res . move . id , sizeof ( res . move . pair )) ,
730
- . u . buffer = res .move .pair });
731
- if ( err ) {
732
- return err ;
733
- }
728
+ // TODO check performance/complexity of different strategies here
729
+ lfs_globals_t res = lfs_globals_xor ( source , diff );
730
+ int err = lfs_commit_commit ( lfs , commit , ( lfs_mattr_t ){
731
+ lfs_mktag ( LFS_TYPE_IDELETE ,
732
+ res . move . id , sizeof ( res .move .pair )),
733
+ . u . buffer = res . move . pair });
734
+ if ( err ) {
735
+ return err ;
734
736
}
735
737
736
738
return 0 ;
@@ -878,6 +880,17 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
878
880
temp .etag = tag ;
879
881
crc = 0xffffffff ;
880
882
* dir = temp ;
883
+
884
+ // TODO simplify this?
885
+ if (cb ) {
886
+ err = cb (lfs , data , (lfs_mattr_t ){
887
+ (tag | 0x80000000 ),
888
+ .u .d .block = temp .pair [0 ],
889
+ .u .d .off = off + sizeof (tag )});
890
+ if (err ) {
891
+ return err ;
892
+ }
893
+ }
881
894
} else {
882
895
// TODO crc before callback???
883
896
err = lfs_bd_crc (lfs , temp .pair [0 ],
@@ -1008,6 +1021,11 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list,
1008
1021
const lfs_block_t oldpair [2 ] = {dir -> pair [1 ], dir -> pair [0 ]};
1009
1022
bool relocated = false;
1010
1023
1024
+ // There's nothing special about our global delta, so feed it back
1025
+ // into the global global delta
1026
+ lfs -> diff = lfs_globals_xor (& lfs -> diff , & dir -> globals );
1027
+ dir -> globals = (lfs_globals_t ){0 };
1028
+
1011
1029
// increment revision count
1012
1030
dir -> rev += 1 ;
1013
1031
@@ -1207,14 +1225,12 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list) {
1207
1225
return err ;
1208
1226
}
1209
1227
1210
- if (!lfs_globals_iszero (& lfs -> diff )) {
1211
- err = lfs_commit_globals (lfs , & commit , & dir -> globals , & lfs -> diff );
1212
- if (err ) {
1213
- if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT ) {
1214
- goto compact ;
1215
- }
1216
- return err ;
1228
+ err = lfs_commit_globals (lfs , & commit , & dir -> globals , & lfs -> diff );
1229
+ if (err ) {
1230
+ if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT ) {
1231
+ goto compact ;
1217
1232
}
1233
+ return err ;
1218
1234
}
1219
1235
1220
1236
err = lfs_commit_crc (lfs , & commit );
@@ -1242,6 +1258,7 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list) {
1242
1258
}
1243
1259
1244
1260
// update any directories that are affected
1261
+ // TODO what about pairs? what if we're splitting??
1245
1262
for (lfs_dir_t * d = lfs -> dirs ; d ; d = d -> next ) {
1246
1263
if (lfs_paircmp (d -> m .pair , dir -> pair ) == 0 ) {
1247
1264
d -> m = * dir ;
@@ -1441,6 +1458,7 @@ struct lfs_dir_find {
1441
1458
const char * name ;
1442
1459
uint16_t len ;
1443
1460
int16_t id ;
1461
+ int16_t tempid ;
1444
1462
};
1445
1463
1446
1464
static int lfs_dir_findscan (lfs_t * lfs , void * p , lfs_mattr_t attr ) {
@@ -1456,14 +1474,16 @@ static int lfs_dir_findscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
1456
1474
1457
1475
if (res ) {
1458
1476
// found a match
1459
- find -> id = lfs_tag_id (attr .tag );
1477
+ find -> tempid = lfs_tag_id (attr .tag );
1460
1478
}
1461
1479
} else if (lfs_tag_type (attr .tag ) == LFS_STRUCT_DELETE ) {
1462
- if (lfs_tag_id (attr .tag ) == find -> id ) {
1463
- find -> id = -1 ;
1464
- } else if (lfs_tag_id (attr .tag ) < find -> id ) {
1465
- find -> id -= 1 ;
1480
+ if (lfs_tag_id (attr .tag ) == find -> tempid ) {
1481
+ find -> tempid = -1 ;
1482
+ } else if (lfs_tag_id (attr .tag ) < find -> tempid ) {
1483
+ find -> tempid -= 1 ;
1466
1484
}
1485
+ } else if (lfs_tag_type (attr .tag ) == LFS_TYPE_CRC ) {
1486
+ find -> id = find -> tempid ;
1467
1487
}
1468
1488
1469
1489
return 0 ;
@@ -1531,6 +1551,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
1531
1551
while (true) {
1532
1552
//printf("checking %d %d for %s\n", attr.u.pair[0], attr.u.pair[1], *path);
1533
1553
find .id = -1 ;
1554
+ find .tempid = -1 ;
1534
1555
int err = lfs_dir_fetchwith (lfs , dir , attr .u .pair ,
1535
1556
lfs_dir_findscan , & find );
1536
1557
if (err ) {
@@ -3451,9 +3472,11 @@ static int lfs_pred(lfs_t *lfs, const lfs_block_t dir[2], lfs_mdir_t *pdir) {
3451
3472
*/
3452
3473
3453
3474
3475
+ // TODO combine parentscan and findscan?
3454
3476
struct lfs_dir_parentscan {
3455
3477
lfs_block_t pair [2 ];
3456
3478
int16_t id ;
3479
+ int16_t tempid ;
3457
3480
};
3458
3481
3459
3482
static int lfs_parentscan (lfs_t * lfs , void * p , lfs_mattr_t attr ) {
@@ -3468,14 +3491,16 @@ static int lfs_parentscan(lfs_t *lfs, void *p, lfs_mattr_t attr) {
3468
3491
3469
3492
if (lfs_paircmp (attr .u .pair , parentscan -> pair ) == 0 ) {
3470
3493
// found a match
3471
- parentscan -> id = lfs_tag_id (attr .tag );
3494
+ parentscan -> tempid = lfs_tag_id (attr .tag );
3472
3495
}
3473
3496
} else if (lfs_tag_struct (attr .tag ) == LFS_STRUCT_DELETE ) {
3474
- if (lfs_tag_id (attr .tag ) == parentscan -> id ) {
3475
- parentscan -> id = -1 ;
3476
- } else if (lfs_tag_id (attr .tag ) < parentscan -> id ) {
3477
- parentscan -> id -= 1 ;
3497
+ if (lfs_tag_id (attr .tag ) == parentscan -> tempid ) {
3498
+ parentscan -> tempid = -1 ;
3499
+ } else if (lfs_tag_id (attr .tag ) < parentscan -> tempid ) {
3500
+ parentscan -> tempid -= 1 ;
3478
3501
}
3502
+ } else if (lfs_tag_type (attr .tag ) == LFS_TYPE_CRC ) {
3503
+ parentscan -> id = parentscan -> tempid ;
3479
3504
}
3480
3505
3481
3506
return 0 ;
@@ -3490,7 +3515,8 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2],
3490
3515
struct lfs_dir_parentscan parentscan = {
3491
3516
.pair [0 ] = pair [0 ],
3492
3517
.pair [1 ] = pair [1 ],
3493
- .id = -1
3518
+ .id = -1 ,
3519
+ .tempid = -1 ,
3494
3520
};
3495
3521
3496
3522
int err = lfs_dir_fetchwith (lfs , parent , parent -> tail ,
0 commit comments