@@ -721,16 +721,18 @@ static int lfs_commit_move(lfs_t *lfs, struct lfs_commit *commit,
721721
722722static int lfs_commit_globals (lfs_t * lfs , struct lfs_commit * commit ,
723723 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+ }
725727
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 ;
734736 }
735737
736738 return 0 ;
@@ -878,6 +880,17 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
878880 temp .etag = tag ;
879881 crc = 0xffffffff ;
880882 * 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+ }
881894 } else {
882895 // TODO crc before callback???
883896 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,
10081021 const lfs_block_t oldpair [2 ] = {dir -> pair [1 ], dir -> pair [0 ]};
10091022 bool relocated = false;
10101023
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+
10111029 // increment revision count
10121030 dir -> rev += 1 ;
10131031
@@ -1207,14 +1225,12 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list) {
12071225 return err ;
12081226 }
12091227
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 ;
12171232 }
1233+ return err ;
12181234 }
12191235
12201236 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) {
12421258 }
12431259
12441260 // update any directories that are affected
1261+ // TODO what about pairs? what if we're splitting??
12451262 for (lfs_dir_t * d = lfs -> dirs ; d ; d = d -> next ) {
12461263 if (lfs_paircmp (d -> m .pair , dir -> pair ) == 0 ) {
12471264 d -> m = * dir ;
@@ -1441,6 +1458,7 @@ struct lfs_dir_find {
14411458 const char * name ;
14421459 uint16_t len ;
14431460 int16_t id ;
1461+ int16_t tempid ;
14441462};
14451463
14461464static 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) {
14561474
14571475 if (res ) {
14581476 // found a match
1459- find -> id = lfs_tag_id (attr .tag );
1477+ find -> tempid = lfs_tag_id (attr .tag );
14601478 }
14611479 } 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 ;
14661484 }
1485+ } else if (lfs_tag_type (attr .tag ) == LFS_TYPE_CRC ) {
1486+ find -> id = find -> tempid ;
14671487 }
14681488
14691489 return 0 ;
@@ -1531,6 +1551,7 @@ static int lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir,
15311551 while (true) {
15321552 //printf("checking %d %d for %s\n", attr.u.pair[0], attr.u.pair[1], *path);
15331553 find .id = -1 ;
1554+ find .tempid = -1 ;
15341555 int err = lfs_dir_fetchwith (lfs , dir , attr .u .pair ,
15351556 lfs_dir_findscan , & find );
15361557 if (err ) {
@@ -3451,9 +3472,11 @@ static int lfs_pred(lfs_t *lfs, const lfs_block_t dir[2], lfs_mdir_t *pdir) {
34513472*/
34523473
34533474
3475+ // TODO combine parentscan and findscan?
34543476struct lfs_dir_parentscan {
34553477 lfs_block_t pair [2 ];
34563478 int16_t id ;
3479+ int16_t tempid ;
34573480};
34583481
34593482static 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) {
34683491
34693492 if (lfs_paircmp (attr .u .pair , parentscan -> pair ) == 0 ) {
34703493 // found a match
3471- parentscan -> id = lfs_tag_id (attr .tag );
3494+ parentscan -> tempid = lfs_tag_id (attr .tag );
34723495 }
34733496 } 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 ;
34783501 }
3502+ } else if (lfs_tag_type (attr .tag ) == LFS_TYPE_CRC ) {
3503+ parentscan -> id = parentscan -> tempid ;
34793504 }
34803505
34813506 return 0 ;
@@ -3490,7 +3515,8 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t pair[2],
34903515 struct lfs_dir_parentscan parentscan = {
34913516 .pair [0 ] = pair [0 ],
34923517 .pair [1 ] = pair [1 ],
3493- .id = -1
3518+ .id = -1 ,
3519+ .tempid = -1 ,
34943520 };
34953521
34963522 int err = lfs_dir_fetchwith (lfs , parent , parent -> tail ,
0 commit comments