@@ -677,15 +677,14 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir,
677
677
return 0 ;
678
678
}
679
679
680
- static int lfs_dir_append (lfs_t * lfs , lfs_dir_t * dir ,
681
- lfs_entry_t * entry , struct lfs_region * regions ) {
680
+ static int lfs_dir_append_ (lfs_t * lfs , lfs_dir_t * dir ,
681
+ lfs_off_t * off , lfs_size_t size , struct lfs_region * regions ) {
682
682
// check if we fit, if top bit is set we do not and move on
683
683
while (true) {
684
- if ((0x7fffffff & dir -> d .size ) + lfs_entry_size (entry )
685
- <= lfs -> cfg -> block_size ) {
686
- entry -> off = dir -> d .size - 4 ;
684
+ if ((0x7fffffff & dir -> d .size ) + size <= lfs -> cfg -> block_size ) {
685
+ * off = dir -> d .size - 4 ;
687
686
for (struct lfs_region * r = regions ; r ; r = r -> next ) {
688
- r -> off += entry -> off ;
687
+ r -> off += * off ;
689
688
}
690
689
691
690
return lfs_dir_commit (lfs , dir , regions );
@@ -701,9 +700,9 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
701
700
702
701
dir -> d .tail [0 ] = olddir .d .tail [0 ];
703
702
dir -> d .tail [1 ] = olddir .d .tail [1 ];
704
- entry -> off = dir -> d .size - 4 ;
703
+ * off = dir -> d .size - 4 ;
705
704
for (struct lfs_region * r = regions ; r ; r = r -> next ) {
706
- r -> off += entry -> off ;
705
+ r -> off += * off ;
707
706
}
708
707
709
708
err = lfs_dir_commit (lfs , dir , regions );
@@ -724,9 +723,70 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
724
723
}
725
724
}
726
725
726
+ static int lfs_dir_remove_ (lfs_t * lfs , lfs_dir_t * dir ,
727
+ lfs_off_t off , lfs_size_t size ) {
728
+ // check if we should just drop the directory block
729
+ if ((dir -> d .size & 0x7fffffff ) == sizeof (dir -> d )+ 4 + size ) {
730
+ lfs_dir_t pdir ;
731
+ int res = lfs_pred (lfs , dir -> pair , & pdir );
732
+ if (res < 0 ) {
733
+ return res ;
734
+ }
735
+
736
+ if (pdir .d .size & 0x80000000 ) {
737
+ pdir .d .size &= dir -> d .size | 0x7fffffff ;
738
+ pdir .d .tail [0 ] = dir -> d .tail [0 ];
739
+ pdir .d .tail [1 ] = dir -> d .tail [1 ];
740
+ return lfs_dir_commit (lfs , & pdir , NULL );
741
+ }
742
+ }
743
+
744
+ // shift out the entry
745
+ int err = lfs_dir_commit (lfs , dir ,
746
+ & (struct lfs_region ){
747
+ off , - size ,
748
+ lfs_commit_mem , NULL , 0 });
749
+ if (err ) {
750
+ return err ;
751
+ }
752
+
753
+ // shift over any files/directories that are affected
754
+ for (lfs_file_t * f = lfs -> files ; f ; f = f -> next ) {
755
+ if (lfs_paircmp (f -> pair , dir -> pair ) == 0 ) {
756
+ if (f -> poff == off ) {
757
+ f -> pair [0 ] = 0xffffffff ;
758
+ f -> pair [1 ] = 0xffffffff ;
759
+ } else if (f -> poff > off ) {
760
+ f -> poff -= size ;
761
+ }
762
+ }
763
+ }
764
+
765
+ for (lfs_dir_t * d = lfs -> dirs ; d ; d = d -> next ) {
766
+ if (lfs_paircmp (d -> pair , dir -> pair ) == 0 ) {
767
+ if (d -> off > off ) {
768
+ d -> off -= size ;
769
+ d -> pos -= size ;
770
+ }
771
+ }
772
+ }
773
+
774
+ return 0 ;
775
+ }
776
+
777
+ static int lfs_dir_append (lfs_t * lfs , lfs_dir_t * dir ,
778
+ lfs_entry_t * entry , struct lfs_region * regions ) {
779
+ return lfs_dir_append_ (lfs , dir ,
780
+ & entry -> off , lfs_entry_size (entry ), regions );
781
+ }
782
+
783
+ static int lfs_dir_remove (lfs_t * lfs , lfs_dir_t * dir , lfs_entry_t * entry ) {
784
+ return lfs_dir_remove_ (lfs , dir ,
785
+ entry -> off , lfs_entry_size (entry ));
786
+ }
787
+
727
788
static int lfs_dir_update (lfs_t * lfs , lfs_dir_t * dir ,
728
789
lfs_entry_t * entry , struct lfs_region * regions ) {
729
- lfs_off_t oldoff = entry -> off ; // <- TODO rm me?
730
790
lfs_ssize_t diff = 0 ;
731
791
for (struct lfs_region * r = regions ; r ; r = r -> next ) {
732
792
diff += r -> diff ;
@@ -742,6 +802,24 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir,
742
802
if (err ) {
743
803
return err ;
744
804
}
805
+
806
+ // shift over any files/directories that are affected
807
+ for (lfs_file_t * f = lfs -> files ; f ; f = f -> next ) {
808
+ if (lfs_paircmp (f -> pair , dir -> pair ) == 0 ) {
809
+ if (f -> poff > entry -> off ) {
810
+ f -> poff += diff ;
811
+ }
812
+ }
813
+ }
814
+
815
+ for (lfs_dir_t * d = lfs -> dirs ; d ; d = d -> next ) {
816
+ if (lfs_paircmp (d -> pair , dir -> pair ) == 0 ) {
817
+ if (d -> off > entry -> off ) {
818
+ d -> off += diff ;
819
+ d -> pos += diff ;
820
+ }
821
+ }
822
+ }
745
823
} else {
746
824
lfs_dir_t olddir = * dir ;
747
825
lfs_off_t oldoff = entry -> off ;
@@ -756,9 +834,9 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir,
756
834
if (err ) {
757
835
return err ;
758
836
}
837
+ entry -> d .type &= LFS_STRUCT_MOVED ;
759
838
760
839
// append updated entry
761
- entry -> d .type &= LFS_STRUCT_MOVED ;
762
840
err = lfs_dir_append (lfs , dir , entry ,
763
841
& (struct lfs_region ){
764
842
0 , + lfs_entry_size (entry ),
@@ -769,86 +847,13 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir,
769
847
}
770
848
771
849
// remove old entry
772
- err = lfs_dir_commit (lfs , & olddir ,
773
- & (struct lfs_region ){
774
- oldoff , - oldsize ,
775
- lfs_commit_mem , NULL , 0 });
850
+ err = lfs_dir_remove_ (lfs , dir , oldoff , oldsize );
776
851
if (err ) {
777
852
return err ;
778
853
}
779
- }
780
854
781
- // TODO move to dir_commit?
782
- // TODO this doesn't work...
783
- // shift over any files/directories that are affected
784
- for (lfs_file_t * f = lfs -> files ; f ; f = f -> next ) {
785
- if (lfs_paircmp (f -> pair , dir -> pair ) == 0 ) {
786
- if (f -> poff == oldoff ) {
787
- f -> poff = entry -> off ;
788
- } else if (f -> poff > entry -> off ) {
789
- f -> poff += diff ;
790
- }
791
- }
792
- }
793
-
794
- for (lfs_dir_t * d = lfs -> dirs ; d ; d = d -> next ) {
795
- if (lfs_paircmp (d -> pair , dir -> pair ) == 0 ) {
796
- if (d -> off > entry -> off ) {
797
- d -> off += diff ;
798
- d -> pos += diff ;
799
- }
800
- }
801
- }
802
-
803
- return 0 ;
804
- }
805
-
806
- static int lfs_dir_remove (lfs_t * lfs , lfs_dir_t * dir , lfs_entry_t * entry ) {
807
- // check if we should just drop the directory block
808
- if ((dir -> d .size & 0x7fffffff ) == sizeof (dir -> d )+ 4
809
- + lfs_entry_size (entry )) {
810
- lfs_dir_t pdir ;
811
- int res = lfs_pred (lfs , dir -> pair , & pdir );
812
- if (res < 0 ) {
813
- return res ;
814
- }
815
-
816
- if (pdir .d .size & 0x80000000 ) {
817
- pdir .d .size &= dir -> d .size | 0x7fffffff ;
818
- pdir .d .tail [0 ] = dir -> d .tail [0 ];
819
- pdir .d .tail [1 ] = dir -> d .tail [1 ];
820
- return lfs_dir_commit (lfs , & pdir , NULL );
821
- }
822
- }
823
-
824
- // shift out the entry
825
- int err = lfs_dir_commit (lfs , dir ,
826
- & (struct lfs_region ){
827
- entry -> off , - lfs_entry_size (entry ),
828
- lfs_commit_mem , NULL , 0 });
829
- if (err ) {
830
- return err ;
831
- }
832
-
833
- // shift over any files/directories that are affected
834
- for (lfs_file_t * f = lfs -> files ; f ; f = f -> next ) {
835
- if (lfs_paircmp (f -> pair , dir -> pair ) == 0 ) {
836
- if (f -> poff == entry -> off ) {
837
- f -> pair [0 ] = 0xffffffff ;
838
- f -> pair [1 ] = 0xffffffff ;
839
- } else if (f -> poff > entry -> off ) {
840
- f -> poff -= lfs_entry_size (entry );
841
- }
842
- }
843
- }
844
-
845
- for (lfs_dir_t * d = lfs -> dirs ; d ; d = d -> next ) {
846
- if (lfs_paircmp (d -> pair , dir -> pair ) == 0 ) {
847
- if (d -> off > entry -> off ) {
848
- d -> off -= lfs_entry_size (entry );
849
- d -> pos -= lfs_entry_size (entry );
850
- }
851
- }
855
+ // TODO remove file under file?
856
+ // TODO need to shift entries?
852
857
}
853
858
854
859
return 0 ;
0 commit comments