@@ -507,8 +507,11 @@ static int lfs_commit_commit(lfs_t *lfs,
507
507
attr .u .dir , NULL );
508
508
}
509
509
510
- uint16_t id = lfs_tag_id (attr .tag ) - commit -> filter .begin ;
511
- attr .tag = lfs_mktag (0 , id , 0 ) | (attr .tag & 0xffc00fff );
510
+ if (lfs_tag_id (attr .tag ) != 0x3ff ) {
511
+ // TODO eh?
512
+ uint16_t id = lfs_tag_id (attr .tag ) - commit -> filter .begin ;
513
+ attr .tag = lfs_mktag (0 , id , 0 ) | (attr .tag & 0xffc00fff );
514
+ }
512
515
513
516
// check if we fit
514
517
lfs_size_t size = lfs_tag_size (attr .tag );
@@ -757,12 +760,14 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir,
757
760
return 0 ;
758
761
}
759
762
760
- static int lfs_dir_fetchwith (lfs_t * lfs ,
763
+ static int lfs_dir_find (lfs_t * lfs ,
761
764
lfs_mdir_t * dir , const lfs_block_t pair [2 ],
762
- int (* cb )(lfs_t * lfs , void * data , lfs_mattr_t attr ), void * data ) {
765
+ uint32_t findmask , lfs_tag_t findtag ,
766
+ const void * findbuffer , lfs_tag_t * foundtag ) {
763
767
dir -> pair [0 ] = pair [0 ];
764
768
dir -> pair [1 ] = pair [1 ];
765
769
dir -> stop_at_commit = false;
770
+ * foundtag = 0xffffffff ;
766
771
767
772
// find the block with the most recent revision
768
773
uint32_t rev [2 ];
@@ -794,12 +799,14 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
794
799
lfs_crc (& crc , & dir -> rev , sizeof (dir -> rev ));
795
800
dir -> rev = lfs_fromle32 (dir -> rev );
796
801
797
- lfs_mdir_t temp = * dir ;
802
+ lfs_mdir_t tempdir = * dir ;
803
+ lfs_tag_t tempfoundtag = * foundtag ;
798
804
799
805
while (true) {
800
806
// extract next tag
801
807
lfs_tag_t tag ;
802
- int err = lfs_bd_read (lfs , temp .pair [0 ], off , & tag , sizeof (tag ));
808
+ int err = lfs_bd_read (lfs , tempdir .pair [0 ],
809
+ off , & tag , sizeof (tag ));
803
810
if (err ) {
804
811
return err ;
805
812
}
@@ -809,113 +816,84 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
809
816
810
817
// next commit not yet programmed
811
818
if (lfs_tag_type (ptag ) == LFS_TYPE_CRC && !lfs_tag_isvalid (tag )) {
812
- // synthetic move
813
- if (lfs_paircmp (dir -> pair , lfs -> globals .move .pair ) == 0
814
- && cb ) {
815
- int err = cb (lfs , data , (lfs_mattr_t ){
816
- lfs_mktag (LFS_TYPE_DELETE ,
817
- lfs -> globals .move .id , 0 )});
818
- if (err ) {
819
- return err ;
820
- }
821
- }
822
-
823
819
dir -> erased = true;
824
- return 0 ;
820
+ goto done ;
825
821
}
826
822
827
823
// check we're in valid range
828
824
if (off + sizeof (tag )+ lfs_tag_size (tag ) > lfs -> cfg -> block_size ) {
829
825
break ;
830
826
}
831
827
832
- //printf("tag r %#010x (%x:%x %03x %03x %03x)\n", tag, temp.pair[0], off+sizeof(tag), lfs_tag_type(tag), lfs_tag_id(tag), lfs_tag_size(tag));
833
828
if (lfs_tag_type (tag ) == LFS_TYPE_CRC ) {
834
829
// check the crc attr
835
830
uint32_t dcrc ;
836
- int err = lfs_bd_read (lfs , temp .pair [0 ],
831
+ int err = lfs_bd_read (lfs , tempdir .pair [0 ],
837
832
off + sizeof (tag ), & dcrc , sizeof (dcrc ));
838
833
if (err ) {
839
834
return err ;
840
835
}
841
836
842
837
if (crc != lfs_fromle32 (dcrc )) {
843
- if (off == sizeof (temp .rev )) {
838
+ if (off == sizeof (tempdir .rev )) {
844
839
// try other block
845
840
break ;
846
841
} else {
847
- // snythetic move
848
- // TODO combine with above?
849
- if (lfs_paircmp (dir -> pair , lfs -> globals .move .pair ) == 0
850
- && cb ) {
851
- int err = cb (lfs , data , (lfs_mattr_t ){
852
- lfs_mktag (LFS_TYPE_DELETE ,
853
- lfs -> globals .move .id , 0 )});
854
- if (err ) {
855
- return err ;
856
- }
857
- }
858
-
859
842
// consider what we have good enough
860
843
dir -> erased = false;
861
- return 0 ;
844
+ goto done ;
862
845
}
863
846
}
864
847
865
- temp .off = off + sizeof (tag )+ lfs_tag_size (tag );
866
- temp .etag = tag ;
848
+ tempdir .off = off + sizeof (tag )+ lfs_tag_size (tag );
849
+ tempdir .etag = tag ;
867
850
crc = 0xffffffff ;
868
- * dir = temp ;
869
-
870
- // TODO simplify this?
871
- if (cb ) {
872
- err = cb (lfs , data , (lfs_mattr_t ){
873
- (tag | 0x80000000 ),
874
- .u .d .block = temp .pair [0 ],
875
- .u .d .off = off + sizeof (tag )});
876
- if (err ) {
877
- return err ;
878
- }
879
- }
851
+ * dir = tempdir ;
852
+ * foundtag = tempfoundtag ;
880
853
} else {
881
- // TODO crc before callback???
882
- err = lfs_bd_crc (lfs , temp .pair [0 ],
854
+ err = lfs_bd_crc (lfs , tempdir .pair [0 ],
883
855
off + sizeof (tag ), lfs_tag_size (tag ), & crc );
884
856
if (err ) {
885
857
return err ;
886
858
}
887
859
860
+ if (lfs_tag_id (tag ) < 0x3ff &&
861
+ lfs_tag_id (tag ) >= tempdir .count ) {
862
+ tempdir .count = lfs_tag_id (tag )+ 1 ;
863
+ }
864
+
888
865
if (lfs_tag_subtype (tag ) == LFS_TYPE_TAIL ) {
889
- temp .split = (lfs_tag_type (tag ) & 1 );
890
- err = lfs_bd_read (lfs , temp .pair [0 ], off + sizeof (tag ),
891
- temp .tail , sizeof (temp .tail ));
866
+ tempdir .split = (lfs_tag_type (tag ) & 1 );
867
+ err = lfs_bd_read (lfs , tempdir .pair [0 ], off + sizeof (tag ),
868
+ tempdir .tail , sizeof (tempdir .tail ));
892
869
if (err ) {
893
870
return err ;
894
871
}
895
872
} else if (lfs_tag_type (tag ) == LFS_TYPE_GLOBALS ) {
896
- err = lfs_bd_read (lfs , temp .pair [0 ], off + sizeof (tag ),
897
- & temp .globals , sizeof (temp .globals ));
873
+ err = lfs_bd_read (lfs , tempdir .pair [0 ], off + sizeof (tag ),
874
+ & tempdir .globals , sizeof (tempdir .globals ));
898
875
if (err ) {
899
876
return err ;
900
877
}
901
- } else {
902
- if (lfs_tag_id (tag ) < 0x3ff &&
903
- lfs_tag_id (tag ) >= temp .count ) {
904
- temp .count = lfs_tag_id (tag )+ 1 ;
878
+ } else if (lfs_tag_type (tag ) == LFS_TYPE_DELETE ) {
879
+ tempdir .count -= 1 ;
880
+
881
+ if (lfs_tag_id (tag ) == lfs_tag_id (tempfoundtag )) {
882
+ tempfoundtag = 0xffffffff ;
883
+ } else if (lfs_tag_id (tempfoundtag ) < 0x3ff &&
884
+ lfs_tag_id (tag ) < lfs_tag_id (tempfoundtag )) {
885
+ tempfoundtag -= lfs_mktag (0 , 1 , 0 );
905
886
}
906
-
907
- if (lfs_tag_type (tag ) == LFS_TYPE_DELETE ) {
908
- temp .count -= 1 ;
887
+ } else if ((tag & findmask ) == (findtag & findmask )) {
888
+ int res = lfs_bd_cmp (lfs , tempdir .pair [0 ], off + sizeof (tag ),
889
+ findbuffer , lfs_tag_size (tag ));
890
+ if (res < 0 ) {
891
+ return res ;
909
892
}
910
893
911
- if (cb ) {
912
- err = cb (lfs , data , (lfs_mattr_t ){
913
- (tag | 0x80000000 ),
914
- .u .d .block = temp .pair [0 ],
915
- .u .d .off = off + sizeof (tag )});
916
- if (err ) {
917
- return err ;
918
- }
894
+ if (res ) {
895
+ // found a match
896
+ tempfoundtag = tag ;
919
897
}
920
898
}
921
899
}
@@ -931,11 +909,34 @@ static int lfs_dir_fetchwith(lfs_t *lfs,
931
909
932
910
LFS_ERROR ("Corrupted dir pair at %d %d" , dir -> pair [0 ], dir -> pair [1 ]);
933
911
return LFS_ERR_CORRUPT ;
912
+
913
+ done :
914
+ // synthetic move
915
+ if (lfs_paircmp (dir -> pair , lfs -> globals .move .pair ) == 0 ) {
916
+ if (lfs -> globals .move .id == lfs_tag_id (* foundtag )) {
917
+ * foundtag = 0xffffffff ;
918
+ } else if (lfs_tag_id (* foundtag ) < 0x3ff &&
919
+ lfs -> globals .move .id < lfs_tag_id (* foundtag )) {
920
+ * foundtag -= lfs_mktag (0 , 1 , 0 );
921
+ }
922
+ }
923
+
924
+ if (* foundtag == 0xffffffff ) {
925
+ return LFS_ERR_NOENT ;
926
+ }
927
+
928
+ return 0 ;
934
929
}
935
930
936
931
static int lfs_dir_fetch (lfs_t * lfs ,
937
932
lfs_mdir_t * dir , const lfs_block_t pair [2 ]) {
938
- return lfs_dir_fetchwith (lfs , dir , pair , NULL , NULL );
933
+ int err = lfs_dir_find (lfs , dir , pair ,
934
+ 0xffffffff , 0xffffffff , NULL , & (lfs_tag_t ){0 });
935
+ if (err && err != LFS_ERR_NOENT ) {
936
+ return err ;
937
+ }
938
+
939
+ return 0 ;
939
940
}
940
941
941
942
static int lfs_dir_traverse (lfs_t * lfs , lfs_mdir_t * dir ,
@@ -1115,6 +1116,8 @@ static int lfs_dir_compact(lfs_t *lfs, lfs_mdir_t *dir, lfs_mattrlist_t *list,
1115
1116
break ;
1116
1117
1117
1118
split :
1119
+ // TODO update dirs that get split here?
1120
+
1118
1121
// commit no longer fits, need to split dir,
1119
1122
// drop caches and create tail
1120
1123
lfs -> pcache .block = 0xffffffff ;
@@ -1414,66 +1417,6 @@ static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir,
1414
1417
return 0 ;
1415
1418
}
1416
1419
1417
- struct lfs_dir_find {
1418
- uint32_t mask ;
1419
- lfs_tag_t tag ;
1420
- const void * buffer ;
1421
- lfs_tag_t foundtag ;
1422
- lfs_tag_t temptag ;
1423
- };
1424
-
1425
- static int lfs_dir_findscan (lfs_t * lfs , void * p , lfs_mattr_t attr ) {
1426
- struct lfs_dir_find * find = p ;
1427
-
1428
- if ((attr .tag & find -> mask ) == (find -> tag & find -> mask )) {
1429
- int res = lfs_bd_cmp (lfs , attr .u .d .block , attr .u .d .off ,
1430
- find -> buffer , lfs_tag_size (attr .tag ));
1431
- if (res < 0 ) {
1432
- return res ;
1433
- }
1434
-
1435
- if (res ) {
1436
- // found a match
1437
- find -> temptag = attr .tag ;
1438
- }
1439
- } else if (lfs_tag_type (attr .tag ) == LFS_TYPE_DELETE ) {
1440
- if (lfs_tag_id (attr .tag ) == lfs_tag_id (find -> temptag )) {
1441
- find -> temptag = 0xffffffff ;
1442
- } else if (lfs_tag_id (find -> temptag ) < 0x3ff &&
1443
- lfs_tag_id (attr .tag ) < lfs_tag_id (find -> temptag )) {
1444
- find -> temptag -= lfs_mktag (0 , 1 , 0 );
1445
- }
1446
- } else if (lfs_tag_type (attr .tag ) == LFS_TYPE_CRC ) {
1447
- find -> foundtag = find -> temptag ;
1448
- }
1449
-
1450
- return 0 ;
1451
- }
1452
-
1453
- static int lfs_dir_find (lfs_t * lfs , lfs_mdir_t * dir , const lfs_block_t * pair ,
1454
- uint32_t mask , lfs_tag_t tag ,
1455
- const void * buffer , lfs_tag_t * foundtag ) {
1456
- struct lfs_dir_find find = {
1457
- .mask = mask ,
1458
- .tag = tag ,
1459
- .buffer = buffer ,
1460
- .foundtag = 0xffffffff ,
1461
- .temptag = 0xffffffff ,
1462
- };
1463
-
1464
- int err = lfs_dir_fetchwith (lfs , dir , pair , lfs_dir_findscan , & find );
1465
- if (err ) {
1466
- return err ;
1467
- }
1468
-
1469
- if (find .foundtag == 0xffffffff ) {
1470
- return LFS_ERR_NOENT ;
1471
- }
1472
-
1473
- * foundtag = find .foundtag ;
1474
- return 0 ;
1475
- }
1476
-
1477
1420
1478
1421
// TODO drop others, make this only return id, also make get take in only entry to populate (with embedded tag)
1479
1422
static int lfs_dir_lookup (lfs_t * lfs , lfs_mdir_t * dir ,
0 commit comments