@@ -12,6 +12,8 @@ use crate::{
1212use byteorder:: { ByteOrder , LittleEndian } ;
1313use core:: convert:: TryFrom ;
1414
15+ use super :: BlockCache ;
16+
1517/// The name given to a particular FAT formatted volume.
1618#[ cfg_attr( feature = "defmt-log" , derive( defmt:: Format ) ) ]
1719#[ derive( PartialEq , Eq ) ]
@@ -179,24 +181,21 @@ impl FatVolume {
179181 & self ,
180182 volume_mgr : & VolumeManager < D , T , MAX_DIRS , MAX_FILES > ,
181183 cluster : Cluster ,
184+ fat_block_cache : & mut BlockCache ,
182185 ) -> Result < Cluster , Error < D :: Error > >
183186 where
184187 D : BlockDevice ,
185188 T : TimeSource ,
186189 {
187- let mut blocks = [ Block :: new ( ) ] ;
188190 match & self . fat_specific_info {
189191 FatSpecificInfo :: Fat16 ( _fat16_info) => {
190192 let fat_offset = cluster. 0 * 2 ;
191193 let this_fat_block_num = self . lba_start + self . fat_start . offset_bytes ( fat_offset) ;
192194 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 ] ) ;
200199 match fat_entry {
201200 0xFFF7 => {
202201 // Bad cluster
@@ -216,13 +215,11 @@ impl FatVolume {
216215 let fat_offset = cluster. 0 * 4 ;
217216 let this_fat_block_num = self . lba_start + self . fat_start . offset_bytes ( fat_offset) ;
218217 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 ;
226223 match fat_entry {
227224 0x0000_0000 => {
228225 // Jumped to free space
@@ -341,18 +338,20 @@ impl FatVolume {
341338 }
342339 }
343340 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+ } ;
356355 } else {
357356 current_cluster = None ;
358357 }
@@ -399,7 +398,9 @@ impl FatVolume {
399398 }
400399 }
401400 }
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+ {
403404 Ok ( n) => {
404405 first_dir_block_num = self . cluster_to_block ( n) ;
405406 Some ( n)
@@ -445,6 +446,7 @@ impl FatVolume {
445446 _ => BlockCount ( u32:: from ( self . blocks_per_cluster ) ) ,
446447 } ;
447448 let mut blocks = [ Block :: new ( ) ] ;
449+ let mut block_cache = BlockCache :: empty ( ) ;
448450 while let Some ( cluster) = current_cluster {
449451 for block in first_dir_block_num. range ( dir_size) {
450452 volume_mgr
@@ -467,13 +469,14 @@ impl FatVolume {
467469 }
468470 }
469471 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+ } ;
477480 } else {
478481 current_cluster = None ;
479482 }
@@ -486,6 +489,7 @@ impl FatVolume {
486489 _ => Some ( dir. cluster ) ,
487490 } ;
488491 let mut blocks = [ Block :: new ( ) ] ;
492+ let mut block_cache = BlockCache :: empty ( ) ;
489493 while let Some ( cluster) = current_cluster {
490494 let block_idx = self . cluster_to_block ( cluster) ;
491495 for block in block_idx. range ( BlockCount ( u32:: from ( self . blocks_per_cluster ) ) ) {
@@ -508,7 +512,8 @@ impl FatVolume {
508512 }
509513 }
510514 }
511- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
515+ current_cluster = match self . next_cluster ( volume_mgr, cluster, & mut block_cache)
516+ {
512517 Ok ( n) => Some ( n) ,
513518 _ => None ,
514519 } ;
@@ -545,6 +550,7 @@ impl FatVolume {
545550 _ => BlockCount ( u32:: from ( self . blocks_per_cluster ) ) ,
546551 } ;
547552
553+ let mut block_cache = BlockCache :: empty ( ) ;
548554 while let Some ( cluster) = current_cluster {
549555 for block in first_dir_block_num. range ( dir_size) {
550556 match self . find_entry_in_block (
@@ -558,13 +564,14 @@ impl FatVolume {
558564 }
559565 }
560566 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+ } ;
568575 } else {
569576 current_cluster = None ;
570577 }
@@ -576,6 +583,7 @@ impl FatVolume {
576583 Cluster :: ROOT_DIR => Some ( fat32_info. first_root_dir_cluster ) ,
577584 _ => Some ( dir. cluster ) ,
578585 } ;
586+ let mut block_cache = BlockCache :: empty ( ) ;
579587 while let Some ( cluster) = current_cluster {
580588 let block_idx = self . cluster_to_block ( cluster) ;
581589 for block in block_idx. range ( BlockCount ( u32:: from ( self . blocks_per_cluster ) ) ) {
@@ -589,7 +597,8 @@ impl FatVolume {
589597 x => return x,
590598 }
591599 }
592- current_cluster = match self . next_cluster ( volume_mgr, cluster) {
600+ current_cluster = match self . next_cluster ( volume_mgr, cluster, & mut block_cache)
601+ {
593602 Ok ( n) => Some ( n) ,
594603 _ => None ,
595604 }
@@ -668,13 +677,15 @@ impl FatVolume {
668677 }
669678 }
670679 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+ } ;
678689 } else {
679690 current_cluster = None ;
680691 }
@@ -694,7 +705,9 @@ impl FatVolume {
694705 x => return x,
695706 }
696707 }
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+ {
698711 Ok ( n) => Some ( n) ,
699712 _ => None ,
700713 }
@@ -920,10 +933,13 @@ impl FatVolume {
920933 // file doesn't have any valid cluster allocated, there is nothing to do
921934 return Ok ( ( ) ) ;
922935 }
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+ }
927943 } ;
928944 if let Some ( ref mut next_free_cluster) = self . next_free_cluster {
929945 if next_free_cluster. 0 > next. 0 {
@@ -934,7 +950,8 @@ impl FatVolume {
934950 }
935951 self . update_fat ( volume_mgr, cluster, Cluster :: END_OF_FILE ) ?;
936952 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) {
938955 Ok ( n) => {
939956 self . update_fat ( volume_mgr, next, Cluster :: EMPTY ) ?;
940957 next = n;
0 commit comments