@@ -486,7 +486,18 @@ static int lfs_dir_fetch(lfs_t *lfs,
486
486
struct lfs_region {
487
487
lfs_off_t oldoff ;
488
488
lfs_size_t oldlen ;
489
- const void * newdata ;
489
+
490
+ enum lfs_region_source {
491
+ LFS_FROM_MEM ,
492
+ LFS_FROM_DISK ,
493
+ } source ;
494
+ union {
495
+ const void * mem ;
496
+ struct {
497
+ lfs_block_t block ;
498
+ lfs_off_t off ;
499
+ } disk ;
500
+ } u ;
490
501
lfs_size_t newlen ;
491
502
};
492
503
@@ -527,42 +538,49 @@ static int lfs_dir_commit(lfs_t *lfs, lfs_dir_t *dir,
527
538
}
528
539
529
540
int i = 0 ;
541
+ int j = 0 ;
530
542
lfs_off_t oldoff = sizeof (dir -> d );
531
543
lfs_off_t newoff = sizeof (dir -> d );
532
544
while (newoff < (0x7fffffff & dir -> d .size )- 4 ) {
545
+ while (i < count && oldoff == regions [i ].oldoff &&
546
+ j == regions [i ].newlen ) {
547
+ oldoff += regions [i ].oldlen ;
548
+ i += 1 ;
549
+ j = 0 ;
550
+ }
551
+
552
+ uint8_t data ;
533
553
if (i < count && regions [i ].oldoff == oldoff ) {
534
- lfs_crc (& crc , regions [i ].newdata , regions [i ].newlen );
535
- err = lfs_bd_prog (lfs , dir -> pair [0 ],
536
- newoff , regions [i ].newdata , regions [i ].newlen );
537
- if (err ) {
538
- if (err == LFS_ERR_CORRUPT ) {
539
- goto relocate ;
554
+ if (regions [i ].source == LFS_FROM_DISK ) {
555
+ err = lfs_bd_read (lfs , regions [i ].u .disk .block ,
556
+ regions [i ].u .disk .off + j , & data , 1 );
557
+ if (err ) {
558
+ return err ;
540
559
}
541
- return err ;
560
+ } else {
561
+ data = ((const uint8_t * )regions [i ].u .mem )[j ];
542
562
}
543
563
544
- oldoff += regions [i ].oldlen ;
545
- newoff += regions [i ].newlen ;
546
- i += 1 ;
564
+ j += 1 ;
547
565
} else {
548
- uint8_t data ;
549
566
err = lfs_bd_read (lfs , oldpair [1 ], oldoff , & data , 1 );
550
567
if (err ) {
551
568
return err ;
552
569
}
553
570
554
- lfs_crc (& crc , & data , 1 );
555
- err = lfs_bd_prog (lfs , dir -> pair [0 ], newoff , & data , 1 );
556
- if (err ) {
557
- if (err == LFS_ERR_CORRUPT ) {
558
- goto relocate ;
559
- }
560
- return err ;
561
- }
562
-
563
571
oldoff += 1 ;
564
- newoff += 1 ;
565
572
}
573
+
574
+ lfs_crc (& crc , & data , 1 );
575
+ err = lfs_bd_prog (lfs , dir -> pair [0 ], newoff , & data , 1 );
576
+ if (err ) {
577
+ if (err == LFS_ERR_CORRUPT ) {
578
+ goto relocate ;
579
+ }
580
+ return err ;
581
+ }
582
+
583
+ newoff += 1 ;
566
584
}
567
585
568
586
crc = lfs_tole32 (crc );
@@ -643,8 +661,10 @@ static int lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir,
643
661
lfs_entry_t * entry , const void * data ) {
644
662
lfs_entry_tole32 (& entry -> d );
645
663
int err = lfs_dir_commit (lfs , dir , (struct lfs_region []){
646
- {entry -> off , sizeof (entry -> d ), & entry -> d , sizeof (entry -> d )},
647
- {entry -> off + sizeof (entry -> d ), entry -> d .nlen , data , entry -> d .nlen }
664
+ {entry -> off , sizeof (entry -> d ),
665
+ LFS_FROM_MEM , {.mem = & entry -> d }, sizeof (entry -> d )},
666
+ {entry -> off + sizeof (entry -> d ), entry -> d .nlen ,
667
+ LFS_FROM_MEM , {.mem = data }, entry -> d .nlen }
648
668
}, data ? 2 : 1 );
649
669
lfs_entry_fromle32 (& entry -> d );
650
670
return err ;
@@ -659,8 +679,10 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
659
679
660
680
lfs_entry_tole32 (& entry -> d );
661
681
int err = lfs_dir_commit (lfs , dir , (struct lfs_region []){
662
- {entry -> off , 0 , & entry -> d , sizeof (entry -> d )},
663
- {entry -> off , 0 , data , entry -> d .nlen }
682
+ {entry -> off , 0 ,
683
+ LFS_FROM_MEM , {.mem = & entry -> d }, sizeof (entry -> d )},
684
+ {entry -> off , 0 ,
685
+ LFS_FROM_MEM , {.mem = data }, entry -> d .nlen }
664
686
}, 2 );
665
687
lfs_entry_fromle32 (& entry -> d );
666
688
return err ;
@@ -679,8 +701,10 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
679
701
entry -> off = dir -> d .size - 4 ;
680
702
lfs_entry_tole32 (& entry -> d );
681
703
err = lfs_dir_commit (lfs , dir , (struct lfs_region []){
682
- {entry -> off , 0 , & entry -> d , sizeof (entry -> d )},
683
- {entry -> off , 0 , data , entry -> d .nlen }
704
+ {entry -> off , 0 ,
705
+ LFS_FROM_MEM , {.mem = & entry -> d }, sizeof (entry -> d )},
706
+ {entry -> off , 0 ,
707
+ LFS_FROM_MEM , {.mem = data }, entry -> d .nlen }
684
708
}, 2 );
685
709
lfs_entry_fromle32 (& entry -> d );
686
710
if (err ) {
@@ -720,7 +744,8 @@ static int lfs_dir_remove(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry) {
720
744
721
745
// shift out the entry
722
746
int err = lfs_dir_commit (lfs , dir , (struct lfs_region []){
723
- {entry -> off , lfs_entry_size (entry ), NULL , 0 },
747
+ {entry -> off , lfs_entry_size (entry ),
748
+ LFS_FROM_MEM , {.mem = NULL }, 0 },
724
749
}, 1 );
725
750
if (err ) {
726
751
return err ;
@@ -2153,7 +2178,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
2153
2178
for (int i = 0 ; i < 2 ; i ++ ) {
2154
2179
err = lfs_dir_commit (lfs , & superdir , (struct lfs_region []){
2155
2180
{sizeof (superdir .d ), sizeof (superblock .d ),
2156
- & superblock .d , sizeof (superblock .d )}
2181
+ LFS_FROM_MEM , {. mem = & superblock .d } , sizeof (superblock .d )}
2157
2182
}, 1 );
2158
2183
if (err && err != LFS_ERR_CORRUPT ) {
2159
2184
return err ;
0 commit comments