@@ -676,6 +676,59 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir,
676676 return err ;
677677}
678678
679+ static int lfs_dir_append_ (lfs_t * lfs , lfs_dir_t * dir ,
680+ lfs_entry_t * entry , struct lfs_region * region ) {
681+ // check if we fit, if top bit is set we do not and move on
682+ while (true) {
683+ if (dir -> d .size + lfs_entry_size (entry ) <= lfs -> cfg -> block_size ) {
684+ entry -> off = dir -> d .size - 4 ;
685+ for (struct lfs_region * r = region ; r ; r = r -> next ) {
686+ r -> oldoff += entry -> off ;
687+ }
688+
689+ lfs_entry_tole32 (& entry -> d );
690+ int err = lfs_dir_commit (lfs , dir ,
691+ & (struct lfs_region ){
692+ LFS_FROM_MEM , entry -> off , 0 ,
693+ {.m .data = & entry -> d }, 4 , region });
694+ lfs_entry_fromle32 (& entry -> d );
695+ return err ;
696+ }
697+
698+ // we need to allocate a new dir block
699+ if (!(0x80000000 & dir -> d .size )) {
700+ lfs_dir_t olddir = * dir ;
701+ int err = lfs_dir_alloc (lfs , dir );
702+ if (err ) {
703+ return err ;
704+ }
705+
706+ dir -> d .tail [0 ] = olddir .d .tail [0 ];
707+ dir -> d .tail [1 ] = olddir .d .tail [1 ];
708+ entry -> off = dir -> d .size - 4 ;
709+ lfs_entry_tole32 (& entry -> d );
710+ err = lfs_dir_commit (lfs , dir ,
711+ & (struct lfs_region ){
712+ LFS_FROM_MEM , entry -> off , 0 ,
713+ {.m .data = & entry -> d }, 4 , region });
714+ lfs_entry_fromle32 (& entry -> d );
715+ if (err ) {
716+ return err ;
717+ }
718+
719+ olddir .d .size |= 0x80000000 ;
720+ olddir .d .tail [0 ] = dir -> pair [0 ];
721+ olddir .d .tail [1 ] = dir -> pair [1 ];
722+ return lfs_dir_commit (lfs , & olddir , NULL );
723+ }
724+
725+ int err = lfs_dir_fetch (lfs , dir , dir -> d .tail );
726+ if (err ) {
727+ return err ;
728+ }
729+ }
730+ }
731+
679732static int lfs_dir_append (lfs_t * lfs , lfs_dir_t * dir ,
680733 lfs_entry_t * entry , const void * data ) {
681734 // check if we fit, if top bit is set we do not and move on
@@ -973,7 +1026,13 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
9731026 cwd .d .tail [0 ] = dir .pair [0 ];
9741027 cwd .d .tail [1 ] = dir .pair [1 ];
9751028
976- err = lfs_dir_append (lfs , & cwd , & entry , path );
1029+ err = lfs_dir_append_ (lfs , & cwd , & entry ,
1030+ & (struct lfs_region ){
1031+ LFS_FROM_MEM , 0 , 0 ,
1032+ {.m .data = (uint8_t * )& entry .d + 4 }, sizeof (entry .d ) - 4 ,
1033+ & (struct lfs_region ){
1034+ LFS_FROM_MEM , 0 , 0 ,
1035+ {.m .data = path }, entry .d .nlen }});
9771036 if (err ) {
9781037 return err ;
9791038 }
@@ -1357,7 +1416,13 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
13571416 entry .d .nlen = strlen (path );
13581417 entry .d .u .file .head = 0xffffffff ;
13591418 entry .d .u .file .size = 0 ;
1360- err = lfs_dir_append (lfs , & cwd , & entry , path );
1419+ err = lfs_dir_append_ (lfs , & cwd , & entry ,
1420+ & (struct lfs_region ){
1421+ LFS_FROM_MEM , 0 , 0 ,
1422+ {.m .data = (uint8_t * )& entry .d + 4 }, sizeof (entry .d ) - 4 ,
1423+ & (struct lfs_region ){
1424+ LFS_FROM_MEM , 0 , 0 ,
1425+ {.m .data = path }, entry .d .nlen }});
13611426 if (err ) {
13621427 return err ;
13631428 }
@@ -2017,7 +2082,13 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
20172082 return err ;
20182083 }
20192084 } else {
2020- err = lfs_dir_append (lfs , & newcwd , & newentry , newpath );
2085+ err = lfs_dir_append_ (lfs , & newcwd , & newentry ,
2086+ & (struct lfs_region ){
2087+ LFS_FROM_MEM , 0 , 0 ,
2088+ {.m .data = (uint8_t * )& newentry .d + 4 }, sizeof (newentry .d ) - 4 ,
2089+ & (struct lfs_region ){
2090+ LFS_FROM_MEM , 0 , 0 ,
2091+ {.m .data = newpath }, newentry .d .nlen }});
20212092 if (err ) {
20222093 return err ;
20232094 }
0 commit comments