@@ -12,6 +12,8 @@ use crate::{
12
12
use byteorder:: { ByteOrder , LittleEndian } ;
13
13
use core:: convert:: TryFrom ;
14
14
15
+ use super :: BlockCache ;
16
+
15
17
/// The name given to a particular FAT formatted volume.
16
18
#[ cfg_attr( feature = "defmt-log" , derive( defmt:: Format ) ) ]
17
19
#[ derive( PartialEq , Eq ) ]
@@ -179,24 +181,21 @@ impl FatVolume {
179
181
& self ,
180
182
volume_mgr : & VolumeManager < D , T , MAX_DIRS , MAX_FILES > ,
181
183
cluster : Cluster ,
184
+ fat_block_cache : & mut BlockCache ,
182
185
) -> Result < Cluster , Error < D :: Error > >
183
186
where
184
187
D : BlockDevice ,
185
188
T : TimeSource ,
186
189
{
187
- let mut blocks = [ Block :: new ( ) ] ;
188
190
match & self . fat_specific_info {
189
191
FatSpecificInfo :: Fat16 ( _fat16_info) => {
190
192
let fat_offset = cluster. 0 * 2 ;
191
193
let this_fat_block_num = self . lba_start + self . fat_start . offset_bytes ( fat_offset) ;
192
194
let this_fat_ent_offset = ( fat_offset % Block :: LEN_U32 ) as usize ;
193
- volume_mgr
194
- . block_device
195
- . read ( & mut blocks, this_fat_block_num, "next_cluster" )
196
- . map_err ( Error :: DeviceError ) ?;
197
- let fat_entry = LittleEndian :: read_u16 (
198
- & blocks[ 0 ] [ this_fat_ent_offset..=this_fat_ent_offset + 1 ] ,
199
- ) ;
195
+ let block =
196
+ fat_block_cache. read ( & volume_mgr, this_fat_block_num, "next_cluster" ) ?;
197
+ let fat_entry =
198
+ LittleEndian :: read_u16 ( & block[ this_fat_ent_offset..=this_fat_ent_offset + 1 ] ) ;
200
199
match fat_entry {
201
200
0xFFF7 => {
202
201
// Bad cluster
@@ -216,13 +215,11 @@ impl FatVolume {
216
215
let fat_offset = cluster. 0 * 4 ;
217
216
let this_fat_block_num = self . lba_start + self . fat_start . offset_bytes ( fat_offset) ;
218
217
let this_fat_ent_offset = ( fat_offset % Block :: LEN_U32 ) as usize ;
219
- volume_mgr
220
- . block_device
221
- . read ( & mut blocks, this_fat_block_num, "next_cluster" )
222
- . map_err ( Error :: DeviceError ) ?;
223
- let fat_entry = LittleEndian :: read_u32 (
224
- & blocks[ 0 ] [ this_fat_ent_offset..=this_fat_ent_offset + 3 ] ,
225
- ) & 0x0FFF_FFFF ;
218
+ let block =
219
+ fat_block_cache. read ( & volume_mgr, this_fat_block_num, "next_cluster" ) ?;
220
+ let fat_entry =
221
+ LittleEndian :: read_u32 ( & block[ this_fat_ent_offset..=this_fat_ent_offset + 3 ] )
222
+ & 0x0FFF_FFFF ;
226
223
match fat_entry {
227
224
0x0000_0000 => {
228
225
// Jumped to free space
@@ -341,18 +338,20 @@ impl FatVolume {
341
338
}
342
339
}
343
340
if cluster != Cluster :: ROOT_DIR {
344
- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
345
- Ok ( n) => {
346
- first_dir_block_num = self . cluster_to_block ( n) ;
347
- Some ( n)
348
- }
349
- Err ( Error :: EndOfFile ) => {
350
- let c = self . alloc_cluster ( volume_mgr, Some ( cluster) , true ) ?;
351
- first_dir_block_num = self . cluster_to_block ( c) ;
352
- Some ( c)
353
- }
354
- _ => None ,
355
- } ;
341
+ let mut block_cache = BlockCache :: empty ( ) ;
342
+ current_cluster =
343
+ match self . next_cluster ( volume_mgr, cluster, & mut block_cache) {
344
+ Ok ( n) => {
345
+ first_dir_block_num = self . cluster_to_block ( n) ;
346
+ Some ( n)
347
+ }
348
+ Err ( Error :: EndOfFile ) => {
349
+ let c = self . alloc_cluster ( volume_mgr, Some ( cluster) , true ) ?;
350
+ first_dir_block_num = self . cluster_to_block ( c) ;
351
+ Some ( c)
352
+ }
353
+ _ => None ,
354
+ } ;
356
355
} else {
357
356
current_cluster = None ;
358
357
}
@@ -399,7 +398,9 @@ impl FatVolume {
399
398
}
400
399
}
401
400
}
402
- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
401
+ let mut block_cache = BlockCache :: empty ( ) ;
402
+ current_cluster = match self . next_cluster ( volume_mgr, cluster, & mut block_cache)
403
+ {
403
404
Ok ( n) => {
404
405
first_dir_block_num = self . cluster_to_block ( n) ;
405
406
Some ( n)
@@ -445,6 +446,7 @@ impl FatVolume {
445
446
_ => BlockCount ( u32:: from ( self . blocks_per_cluster ) ) ,
446
447
} ;
447
448
let mut blocks = [ Block :: new ( ) ] ;
449
+ let mut block_cache = BlockCache :: empty ( ) ;
448
450
while let Some ( cluster) = current_cluster {
449
451
for block in first_dir_block_num. range ( dir_size) {
450
452
volume_mgr
@@ -467,13 +469,14 @@ impl FatVolume {
467
469
}
468
470
}
469
471
if cluster != Cluster :: ROOT_DIR {
470
- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
471
- Ok ( n) => {
472
- first_dir_block_num = self . cluster_to_block ( n) ;
473
- Some ( n)
474
- }
475
- _ => None ,
476
- } ;
472
+ current_cluster =
473
+ match self . next_cluster ( volume_mgr, cluster, & mut block_cache) {
474
+ Ok ( n) => {
475
+ first_dir_block_num = self . cluster_to_block ( n) ;
476
+ Some ( n)
477
+ }
478
+ _ => None ,
479
+ } ;
477
480
} else {
478
481
current_cluster = None ;
479
482
}
@@ -486,6 +489,7 @@ impl FatVolume {
486
489
_ => Some ( dir. cluster ) ,
487
490
} ;
488
491
let mut blocks = [ Block :: new ( ) ] ;
492
+ let mut block_cache = BlockCache :: empty ( ) ;
489
493
while let Some ( cluster) = current_cluster {
490
494
let block_idx = self . cluster_to_block ( cluster) ;
491
495
for block in block_idx. range ( BlockCount ( u32:: from ( self . blocks_per_cluster ) ) ) {
@@ -508,7 +512,8 @@ impl FatVolume {
508
512
}
509
513
}
510
514
}
511
- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
515
+ current_cluster = match self . next_cluster ( volume_mgr, cluster, & mut block_cache)
516
+ {
512
517
Ok ( n) => Some ( n) ,
513
518
_ => None ,
514
519
} ;
@@ -545,6 +550,7 @@ impl FatVolume {
545
550
_ => BlockCount ( u32:: from ( self . blocks_per_cluster ) ) ,
546
551
} ;
547
552
553
+ let mut block_cache = BlockCache :: empty ( ) ;
548
554
while let Some ( cluster) = current_cluster {
549
555
for block in first_dir_block_num. range ( dir_size) {
550
556
match self . find_entry_in_block (
@@ -558,13 +564,14 @@ impl FatVolume {
558
564
}
559
565
}
560
566
if cluster != Cluster :: ROOT_DIR {
561
- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
562
- Ok ( n) => {
563
- first_dir_block_num = self . cluster_to_block ( n) ;
564
- Some ( n)
565
- }
566
- _ => None ,
567
- } ;
567
+ current_cluster =
568
+ match self . next_cluster ( volume_mgr, cluster, & mut block_cache) {
569
+ Ok ( n) => {
570
+ first_dir_block_num = self . cluster_to_block ( n) ;
571
+ Some ( n)
572
+ }
573
+ _ => None ,
574
+ } ;
568
575
} else {
569
576
current_cluster = None ;
570
577
}
@@ -576,6 +583,7 @@ impl FatVolume {
576
583
Cluster :: ROOT_DIR => Some ( fat32_info. first_root_dir_cluster ) ,
577
584
_ => Some ( dir. cluster ) ,
578
585
} ;
586
+ let mut block_cache = BlockCache :: empty ( ) ;
579
587
while let Some ( cluster) = current_cluster {
580
588
let block_idx = self . cluster_to_block ( cluster) ;
581
589
for block in block_idx. range ( BlockCount ( u32:: from ( self . blocks_per_cluster ) ) ) {
@@ -589,7 +597,8 @@ impl FatVolume {
589
597
x => return x,
590
598
}
591
599
}
592
- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
600
+ current_cluster = match self . next_cluster ( volume_mgr, cluster, & mut block_cache)
601
+ {
593
602
Ok ( n) => Some ( n) ,
594
603
_ => None ,
595
604
}
@@ -668,13 +677,15 @@ impl FatVolume {
668
677
}
669
678
}
670
679
if cluster != Cluster :: ROOT_DIR {
671
- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
672
- Ok ( n) => {
673
- first_dir_block_num = self . cluster_to_block ( n) ;
674
- Some ( n)
675
- }
676
- _ => None ,
677
- } ;
680
+ let mut block_cache = BlockCache :: empty ( ) ;
681
+ current_cluster =
682
+ match self . next_cluster ( volume_mgr, cluster, & mut block_cache) {
683
+ Ok ( n) => {
684
+ first_dir_block_num = self . cluster_to_block ( n) ;
685
+ Some ( n)
686
+ }
687
+ _ => None ,
688
+ } ;
678
689
} else {
679
690
current_cluster = None ;
680
691
}
@@ -694,7 +705,9 @@ impl FatVolume {
694
705
x => return x,
695
706
}
696
707
}
697
- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
708
+ let mut block_cache = BlockCache :: empty ( ) ;
709
+ current_cluster = match self . next_cluster ( volume_mgr, cluster, & mut block_cache)
710
+ {
698
711
Ok ( n) => Some ( n) ,
699
712
_ => None ,
700
713
}
@@ -920,10 +933,13 @@ impl FatVolume {
920
933
// file doesn't have any valid cluster allocated, there is nothing to do
921
934
return Ok ( ( ) ) ;
922
935
}
923
- let mut next = match self . next_cluster ( volume_mgr, cluster) {
924
- Ok ( n) => n,
925
- Err ( Error :: EndOfFile ) => return Ok ( ( ) ) ,
926
- Err ( e) => return Err ( e) ,
936
+ let mut next = {
937
+ let mut block_cache = BlockCache :: empty ( ) ;
938
+ match self . next_cluster ( volume_mgr, cluster, & mut block_cache) {
939
+ Ok ( n) => n,
940
+ Err ( Error :: EndOfFile ) => return Ok ( ( ) ) ,
941
+ Err ( e) => return Err ( e) ,
942
+ }
927
943
} ;
928
944
if let Some ( ref mut next_free_cluster) = self . next_free_cluster {
929
945
if next_free_cluster. 0 > next. 0 {
@@ -934,7 +950,8 @@ impl FatVolume {
934
950
}
935
951
self . update_fat ( volume_mgr, cluster, Cluster :: END_OF_FILE ) ?;
936
952
loop {
937
- match self . next_cluster ( volume_mgr, next) {
953
+ let mut block_cache = BlockCache :: empty ( ) ;
954
+ match self . next_cluster ( volume_mgr, next, & mut block_cache) {
938
955
Ok ( n) => {
939
956
self . update_fat ( volume_mgr, next, Cluster :: EMPTY ) ?;
940
957
next = n;
0 commit comments