@@ -39,9 +39,9 @@ static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
39
39
lfs_off_t off , lfs_size_t size , const void * buffer ) {
40
40
const uint8_t * data = buffer ;
41
41
42
- while ( off < size ) {
42
+ for ( lfs_off_t i = 0 ; i < size ; i ++ ) {
43
43
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 );
45
45
if (err ) {
46
46
return err ;
47
47
}
@@ -51,7 +51,6 @@ static int lfs_bd_cmp(lfs_t *lfs, lfs_block_t block,
51
51
}
52
52
53
53
data += 1 ;
54
- off += 1 ;
55
54
}
56
55
57
56
return true;
@@ -329,29 +328,35 @@ static int lfs_dir_create(lfs_t *lfs, lfs_dir_t *dir, lfs_block_t parent[2]) {
329
328
dir -> d .rev += 1 ;
330
329
331
330
// 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 );
336
333
337
334
// Other defaults
338
- dir -> off = dir -> d .size ;
339
335
dir -> d .tail [0 ] = 0 ;
340
336
dir -> d .tail [1 ] = 0 ;
341
337
dir -> d .free = lfs -> free ;
342
338
343
339
// Write out to memory
344
340
return lfs_pair_commit (lfs , dir -> pair ,
345
- 1 + ( parent ? 2 : 0 ) , (struct lfs_commit_region []){
341
+ 5 , (struct lfs_commit_region []){
346
342
{0 , sizeof (dir -> d ), & dir -> d },
347
343
{sizeof (dir -> d ), sizeof (struct lfs_disk_entry ),
348
344
& (struct lfs_disk_entry ){
349
345
.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 ],
353
358
}},
354
- {sizeof (dir -> d )+ sizeof (struct lfs_disk_entry ), 2 , ".." },
359
+ {sizeof (dir -> d )+ 2 * sizeof (struct lfs_disk_entry )+1 , 2 , ".." },
355
360
});
356
361
}
357
362
@@ -473,9 +478,19 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
473
478
}
474
479
475
480
int 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 );
477
490
if (err ) {
478
491
return err ;
492
+ } else if (strcmp (path , "/" ) == 0 ) {
493
+ return 0 ;
479
494
}
480
495
481
496
lfs_entry_t entry ;
@@ -494,6 +509,29 @@ int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) {
494
509
return 0 ;
495
510
}
496
511
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
+
497
535
498
536
/// File operations ///
499
537
@@ -548,6 +586,8 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
548
586
file -> entry .d .len - sizeof (file -> entry .d ),
549
587
path }
550
588
});
589
+ } else if (file -> entry .d .type == LFS_TYPE_DIR ) {
590
+ return LFS_ERROR_IS_DIR ;
551
591
} else {
552
592
file -> head = file -> entry .d .u .file .head ;
553
593
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,
675
715
676
716
677
717
/// 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 ;
681
721
682
722
struct lfs_bd_info info ;
683
723
int err = lfs_bd_info (lfs , & info );
684
724
if (err ) {
685
725
return err ;
686
726
}
687
727
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
+ }
693
789
694
790
// Create free list
695
791
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) {
701
797
if (err ) {
702
798
return err ;
703
799
}
800
+ lfs -> root [0 ] = root .pair [0 ];
801
+ lfs -> root [1 ] = root .pair [1 ];
704
802
lfs -> cwd [0 ] = root .pair [0 ];
705
803
lfs -> cwd [1 ] = root .pair [1 ];
706
804
@@ -736,22 +834,12 @@ int lfs_format(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
736
834
return 0 ;
737
835
}
738
836
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 );
745
839
if (err ) {
746
840
return err ;
747
841
}
748
842
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
-
755
843
lfs_superblock_t superblock = {
756
844
.pair = {0 , 1 },
757
845
};
@@ -767,9 +855,21 @@ int lfs_mount(lfs_t *lfs, lfs_bd_t *bd, const struct lfs_bd_ops *bd_ops) {
767
855
return LFS_ERROR_CORRUPT ;
768
856
}
769
857
858
+ lfs -> root [0 ] = superblock .d .root [0 ];
859
+ lfs -> root [1 ] = superblock .d .root [1 ];
770
860
lfs -> cwd [0 ] = superblock .d .root [0 ];
771
861
lfs -> cwd [1 ] = superblock .d .root [1 ];
772
862
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
+
773
873
return err ;
774
874
}
775
875
0 commit comments