@@ -569,7 +569,18 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir,
569569 // update references if we relocated
570570 LFS_DEBUG ("Relocating %d %d to %d %d" ,
571571 oldpair [0 ], oldpair [1 ], dir -> pair [0 ], dir -> pair [1 ]);
572- return lfs_relocate (lfs , oldpair , dir -> pair );
572+ int err = lfs_relocate (lfs , oldpair , dir -> pair );
573+ if (err ) {
574+ return err ;
575+ }
576+ }
577+
578+ // shift over any directories that are affected
579+ for (lfs_dir_t * d = lfs -> dirs ; d ; d = d -> next ) {
580+ if (lfs_paircmp (d -> pair , dir -> pair ) == 0 ) {
581+ d -> pair [0 ] = dir -> pair [0 ];
582+ d -> pair [1 ] = dir -> pair [1 ];
583+ }
573584 }
574585
575586 return 0 ;
@@ -628,7 +639,7 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
628639}
629640
630641static int lfs_dir_remove (lfs_t * lfs , lfs_dir_t * dir , lfs_entry_t * entry ) {
631- // either shift out the one entry or remove the whole dir block
642+ // check if we should just drop the directory block
632643 if ((dir -> d .size & 0x7fffffff ) == sizeof (dir -> d )+ 4
633644 + lfs_entry_size (entry )) {
634645 lfs_dir_t pdir ;
@@ -637,38 +648,44 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
637648 return res ;
638649 }
639650
640- if (!(pdir .d .size & 0x80000000 )) {
641- return lfs_dir_commit (lfs , dir , (struct lfs_region []){
642- {entry -> off , lfs_entry_size (entry ), NULL , 0 },
643- }, 1 );
644- } else {
651+ if (pdir .d .size & 0x80000000 ) {
645652 pdir .d .size &= dir -> d .size | 0x7fffffff ;
646653 pdir .d .tail [0 ] = dir -> d .tail [0 ];
647654 pdir .d .tail [1 ] = dir -> d .tail [1 ];
648655 return lfs_dir_commit (lfs , & pdir , NULL , 0 );
649656 }
650- } else {
651- int err = lfs_dir_commit (lfs , dir , (struct lfs_region []){
652- {entry -> off , lfs_entry_size (entry ), NULL , 0 },
653- }, 1 );
654- if (err ) {
655- return err ;
656- }
657+ }
657658
658- // shift over any files that are affected
659- for (lfs_file_t * f = lfs -> files ; f ; f = f -> next ) {
660- if (lfs_paircmp (f -> pair , dir -> pair ) == 0 ) {
661- if (f -> poff == entry -> off ) {
662- f -> pair [0 ] = 0xffffffff ;
663- f -> pair [1 ] = 0xffffffff ;
664- } else if (f -> poff > entry -> off ) {
665- f -> poff -= lfs_entry_size (entry );
666- }
659+ // shift out the entry
660+ int err = lfs_dir_commit (lfs , dir , (struct lfs_region []){
661+ {entry -> off , lfs_entry_size (entry ), NULL , 0 },
662+ }, 1 );
663+ if (err ) {
664+ return err ;
665+ }
666+
667+ // shift over any files/directories that are affected
668+ for (lfs_file_t * f = lfs -> files ; f ; f = f -> next ) {
669+ if (lfs_paircmp (f -> pair , dir -> pair ) == 0 ) {
670+ if (f -> poff == entry -> off ) {
671+ f -> pair [0 ] = 0xffffffff ;
672+ f -> pair [1 ] = 0xffffffff ;
673+ } else if (f -> poff > entry -> off ) {
674+ f -> poff -= lfs_entry_size (entry );
667675 }
668676 }
677+ }
669678
670- return 0 ;
679+ for (lfs_dir_t * d = lfs -> dirs ; d ; d = d -> next ) {
680+ if (lfs_paircmp (d -> pair , dir -> pair ) == 0 ) {
681+ if (d -> off > entry -> off ) {
682+ d -> off -= lfs_entry_size (entry );
683+ d -> pos -= lfs_entry_size (entry );
684+ }
685+ }
671686 }
687+
688+ return 0 ;
672689}
673690
674691static int lfs_dir_next (lfs_t * lfs , lfs_dir_t * dir , lfs_entry_t * entry ) {
@@ -894,11 +911,23 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
894911 dir -> head [1 ] = dir -> pair [1 ];
895912 dir -> pos = sizeof (dir -> d ) - 2 ;
896913 dir -> off = sizeof (dir -> d );
914+
915+ // add to list of directories
916+ dir -> next = lfs -> dirs ;
917+ lfs -> dirs = dir ;
918+
897919 return 0 ;
898920}
899921
900922int lfs_dir_close (lfs_t * lfs , lfs_dir_t * dir ) {
901- // do nothing, dir is always synchronized
923+ // remove from list of directories
924+ for (lfs_dir_t * * p = & lfs -> dirs ; * p ; p = & (* p )-> next ) {
925+ if (* p == dir ) {
926+ * p = dir -> next ;
927+ break ;
928+ }
929+ }
930+
902931 return 0 ;
903932}
904933
@@ -1902,6 +1931,7 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
19021931 lfs -> root [0 ] = 0xffffffff ;
19031932 lfs -> root [1 ] = 0xffffffff ;
19041933 lfs -> files = NULL ;
1934+ lfs -> dirs = NULL ;
19051935 lfs -> deorphaned = false;
19061936
19071937 return 0 ;
0 commit comments