@@ -39,9 +39,9 @@ static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
3939 lfs_off_t off , lfs_size_t size , const void * buffer ) {
4040 const uint8_t * data = buffer ;
4141
42- while ( off < size ) {
42+ for ( lfs_off_t i = 0 ; i < size ; i ++ ) {
4343 uint8_t c ;
44- int err = lfs_bd_read (lfs , block , off , 1 , & c );
44+ int err = lfs_bd_read (lfs , block , off + i , 1 , & c );
4545 if (err ) {
4646 return err ;
4747 }
@@ -51,7 +51,6 @@ static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
5151 }
5252
5353 data += 1 ;
54- off += 1 ;
5554 }
5655
5756 return true;
@@ -329,29 +328,35 @@ static int lfs_dir_create(lfs_t *lfs, lfs_dir_t *dir, lfs_block_t parent[2]) {
329328 dir -> d .rev += 1 ;
330329
331330 // Calculate total size
332- dir -> d .size = sizeof (dir -> d );
333- if (parent ) {
334- dir -> d .size += sizeof (struct lfs_disk_entry );
335- }
331+ dir -> d .size = sizeof (dir -> d ) + 2 * sizeof (struct lfs_disk_entry ) + 3 ;
332+ dir -> off = sizeof (dir -> d );
336333
337334 // Other defaults
338- dir -> off = dir -> d .size ;
339335 dir -> d .tail [0 ] = 0 ;
340336 dir -> d .tail [1 ] = 0 ;
341337 dir -> d .free = lfs -> free ;
342338
343339 // Write out to memory
344340 return lfs_pair_commit (lfs , dir -> pair ,
345- 1 + ( parent ? 2 : 0 ) , (struct lfs_commit_region []){
341+ 5 , (struct lfs_commit_region []){
346342 {0 , sizeof (dir -> d ), & dir -> d },
347343 {sizeof (dir -> d ), sizeof (struct lfs_disk_entry ),
348344 & (struct lfs_disk_entry ){
349345 .type = LFS_TYPE_DIR ,
350- .len = 12 + 2 ,
351- .u .dir [0 ] = parent ? parent [0 ] : 0 ,
352- .u .dir [1 ] = parent ? parent [1 ] : 0 ,
346+ .len = sizeof (struct lfs_disk_entry )+1 ,
347+ .u .dir [0 ] = dir -> pair [0 ],
348+ .u .dir [1 ] = dir -> pair [1 ],
349+ }},
350+ {sizeof (dir -> d )+ sizeof (struct lfs_disk_entry ), 1 , "." },
351+ {sizeof (dir -> d )+ sizeof (struct lfs_disk_entry )+1 ,
352+ sizeof (struct lfs_disk_entry ),
353+ & (struct lfs_disk_entry ){
354+ .type = LFS_TYPE_DIR ,
355+ .len = sizeof (struct lfs_disk_entry )+2 ,
356+ .u .dir [0 ] = parent ? parent [0 ] : dir -> pair [0 ],
357+ .u .dir [1 ] = parent ? parent [1 ] : dir -> pair [1 ],
353358 }},
354- {sizeof (dir -> d )+ sizeof (struct lfs_disk_entry ), 2 , ".." },
359+ {sizeof (dir -> d )+ 2 * sizeof (struct lfs_disk_entry )+1 , 2 , ".." },
355360 });
356361}
357362
@@ -473,9 +478,19 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
473478}
474479
475480int lfs_dir_open (lfs_t * lfs , lfs_dir_t * dir , const char * path ) {
476- int err = lfs_dir_fetch (lfs , dir , lfs -> cwd );
481+ if (path [0 ] == '/' ) {
482+ dir -> pair [0 ] = lfs -> root [0 ];
483+ dir -> pair [1 ] = lfs -> root [1 ];
484+ } else {
485+ dir -> pair [0 ] = lfs -> cwd [0 ];
486+ dir -> pair [1 ] = lfs -> cwd [1 ];
487+ }
488+
489+ int err = lfs_dir_fetch (lfs , dir , dir -> pair );
477490 if (err ) {
478491 return err ;
492+ } else if (strcmp (path , "/" ) == 0 ) {
493+ return 0 ;
479494 }
480495
481496 lfs_entry_t entry ;
@@ -494,6 +509,29 @@ int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) {
494509 return 0 ;
495510}
496511
512+ int lfs_dir_read (lfs_t * lfs , lfs_dir_t * dir , struct lfs_info * info ) {
513+ memset (info , 0 , sizeof (* info ));
514+
515+ lfs_entry_t entry ;
516+ int err = lfs_dir_next (lfs , dir , & entry );
517+ if (err ) {
518+ return (err == LFS_ERROR_NO_ENTRY ) ? 0 : err ;
519+ }
520+
521+ info -> type = entry .d .type & 0xff ;
522+ if (info -> type == LFS_TYPE_REG ) {
523+ info -> size = entry .d .u .file .size ;
524+ }
525+
526+ err = lfs_bd_read (lfs , entry .dir [0 ], entry .off + sizeof (entry .d ),
527+ entry .d .len - sizeof (entry .d ), info -> name );
528+ if (err ) {
529+ return err ;
530+ }
531+
532+ return 1 ;
533+ }
534+
497535
498536/// File operations ///
499537
@@ -548,6 +586,8 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
548586 file -> entry .d .len - sizeof (file -> entry .d ),
549587 path }
550588 });
589+ } else if (file -> entry .d .type == LFS_TYPE_DIR ) {
590+ return LFS_ERROR_IS_DIR ;
551591 } else {
552592 file -> head = file -> entry .d .u .file .head ;
553593 file -> size = file -> entry .d .u .file .size ;
@@ -675,21 +715,77 @@ lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
675715
676716
677717/// Generic filesystem operations ///
678- int lfs_format (lfs_t * lfs , lfs_bd_t * bd , const struct lfs_bd_ops * bd_ops ) {
679- lfs -> bd = bd ;
680- lfs -> bd_ops = bd_ops ;
718+ static int lfs_configure (lfs_t * lfs , const struct lfs_config * config ) {
719+ lfs -> bd = config -> bd ;
720+ lfs -> bd_ops = config -> bd_ops ;
681721
682722 struct lfs_bd_info info ;
683723 int err = lfs_bd_info (lfs , & info );
684724 if (err ) {
685725 return err ;
686726 }
687727
688- lfs -> read_size = info .read_size ;
689- lfs -> prog_size = info .prog_size ;
690- lfs -> block_size = info .erase_size ;
691- lfs -> block_count = info .total_size / info .erase_size ;
692- lfs -> words = info .erase_size / sizeof (uint32_t );
728+ if (config -> read_size ) {
729+ if (config -> read_size < info .read_size ||
730+ config -> read_size % info .read_size != 0 ) {
731+ LFS_ERROR ("Invalid read size %u, device has %u\n" ,
732+ config -> read_size , info .read_size );
733+ return LFS_ERROR_INVALID ;
734+ }
735+
736+ lfs -> read_size = config -> read_size ;
737+ } else {
738+ lfs -> read_size = info .read_size ;
739+ }
740+
741+ if (config -> prog_size ) {
742+ if (config -> prog_size < info .prog_size ||
743+ config -> prog_size % info .prog_size != 0 ) {
744+ LFS_ERROR ("Invalid prog size %u, device has %u\n" ,
745+ config -> prog_size , info .prog_size );
746+ return LFS_ERROR_INVALID ;
747+ }
748+
749+ lfs -> prog_size = config -> prog_size ;
750+ } else {
751+ lfs -> prog_size = info .prog_size ;
752+ }
753+
754+ if (config -> block_size ) {
755+ if (config -> block_size < info .erase_size ||
756+ config -> block_size % info .erase_size != 0 ) {
757+ LFS_ERROR ("Invalid block size %u, device has %u\n" ,
758+ config -> prog_size , info .prog_size );
759+ return LFS_ERROR_INVALID ;
760+ }
761+
762+ lfs -> block_size = config -> block_size ;
763+ } else {
764+ lfs -> block_size = lfs_min (512 , info .erase_size );
765+ }
766+
767+ if (config -> block_count ) {
768+ if (config -> block_count > info .total_size /info .erase_size ) {
769+ LFS_ERROR ("Invalid block size %u, device has %u\n" ,
770+ config -> block_size ,
771+ (uint32_t )(info .total_size /info .erase_size ));
772+ return LFS_ERROR_INVALID ;
773+ }
774+
775+ lfs -> block_count = config -> block_count ;
776+ } else {
777+ lfs -> block_count = info .total_size / info .erase_size ;
778+ }
779+
780+ lfs -> words = lfs -> block_size / sizeof (uint32_t );
781+ return 0 ;
782+ }
783+
784+ int lfs_format (lfs_t * lfs , const struct lfs_config * config ) {
785+ int err = lfs_configure (lfs , config );
786+ if (err ) {
787+ return err ;
788+ }
693789
694790 // Create free list
695791 lfs -> free .begin = 2 ;
@@ -701,6 +797,8 @@ int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
701797 if (err ) {
702798 return err ;
703799 }
800+ lfs -> root [0 ] = root .pair [0 ];
801+ lfs -> root [1 ] = root .pair [1 ];
704802 lfs -> cwd [0 ] = root .pair [0 ];
705803 lfs -> cwd [1 ] = root .pair [1 ];
706804
@@ -736,22 +834,12 @@ int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
736834 return 0 ;
737835}
738836
739- int lfs_mount (lfs_t * lfs , lfs_bd_t * bd , const struct lfs_bd_ops * bd_ops ) {
740- lfs -> bd = bd ;
741- lfs -> bd_ops = bd_ops ;
742-
743- struct lfs_bd_info info ;
744- int err = lfs_bd_info (lfs , & info );
837+ int lfs_mount (lfs_t * lfs , const struct lfs_config * config ) {
838+ int err = lfs_configure (lfs , config );
745839 if (err ) {
746840 return err ;
747841 }
748842
749- lfs -> read_size = info .read_size ;
750- lfs -> prog_size = info .prog_size ;
751- lfs -> block_size = info .erase_size ;
752- lfs -> block_count = info .total_size / info .erase_size ;
753- lfs -> words = info .erase_size / sizeof (uint32_t );
754-
755843 lfs_superblock_t superblock = {
756844 .pair = {0 , 1 },
757845 };
@@ -767,9 +855,21 @@ int lfs_mount(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
767855 return LFS_ERROR_CORRUPT ;
768856 }
769857
858+ lfs -> root [0 ] = superblock .d .root [0 ];
859+ lfs -> root [1 ] = superblock .d .root [1 ];
770860 lfs -> cwd [0 ] = superblock .d .root [0 ];
771861 lfs -> cwd [1 ] = superblock .d .root [1 ];
772862
863+ // TODO this is wrong, needs to check all dirs
864+ lfs_dir_t dir ;
865+ err = lfs_dir_fetch (lfs , & dir , lfs -> cwd );
866+ if (err ) {
867+ return err ;
868+ }
869+
870+ lfs -> free .begin = dir .d .free .begin ;
871+ lfs -> free .end = dir .d .free .end ;
872+
773873 return err ;
774874}
775875
0 commit comments