@@ -624,6 +624,7 @@ where
624624 let ( block_idx, block_offset, block_avail) = self . find_data_on_disk (
625625 volume_idx,
626626 & mut current_cluster,
627+ self . open_files [ file_idx] . entry . cluster ,
627628 self . open_files [ file_idx] . current_offset ,
628629 ) ?;
629630 self . open_files [ file_idx] . current_cluster = current_cluster;
@@ -701,44 +702,45 @@ where
701702 written, bytes_to_write, current_cluster
702703 ) ;
703704 let current_offset = self . open_files [ file_idx] . current_offset ;
704- let ( block_idx, block_offset, block_avail) =
705- match self . find_data_on_disk ( volume_idx, & mut current_cluster, current_offset) {
706- Ok ( vars) => {
707- debug ! (
708- "Found block_idx={:?}, block_offset={:?}, block_avail={}" ,
709- vars. 0 , vars. 1 , vars. 2
710- ) ;
711- vars
712- }
713- Err ( Error :: EndOfFile ) => {
714- debug ! ( "Extending file" ) ;
715- match self . open_volumes [ volume_idx] . volume_type {
716- VolumeType :: Fat ( ref mut fat) => {
717- if fat
718- . alloc_cluster (
719- & self . block_device ,
720- Some ( current_cluster. 1 ) ,
721- false ,
722- )
723- . is_err ( )
724- {
725- return Err ( Error :: DiskFull ) ;
726- }
727- debug ! ( "Allocated new FAT cluster, finding offsets..." ) ;
728- let new_offset = self
729- . find_data_on_disk (
730- volume_idx,
731- & mut current_cluster,
732- self . open_files [ file_idx] . current_offset ,
733- )
734- . map_err ( |_| Error :: AllocationError ) ?;
735- debug ! ( "New offset {:?}" , new_offset) ;
736- new_offset
705+ let ( block_idx, block_offset, block_avail) = match self . find_data_on_disk (
706+ volume_idx,
707+ & mut current_cluster,
708+ self . open_files [ file_idx] . entry . cluster ,
709+ current_offset,
710+ ) {
711+ Ok ( vars) => {
712+ debug ! (
713+ "Found block_idx={:?}, block_offset={:?}, block_avail={}" ,
714+ vars. 0 , vars. 1 , vars. 2
715+ ) ;
716+ vars
717+ }
718+ Err ( Error :: EndOfFile ) => {
719+ debug ! ( "Extending file" ) ;
720+ match self . open_volumes [ volume_idx] . volume_type {
721+ VolumeType :: Fat ( ref mut fat) => {
722+ if fat
723+ . alloc_cluster ( & self . block_device , Some ( current_cluster. 1 ) , false )
724+ . is_err ( )
725+ {
726+ return Err ( Error :: DiskFull ) ;
737727 }
728+ debug ! ( "Allocated new FAT cluster, finding offsets..." ) ;
729+ let new_offset = self
730+ . find_data_on_disk (
731+ volume_idx,
732+ & mut current_cluster,
733+ self . open_files [ file_idx] . entry . cluster ,
734+ self . open_files [ file_idx] . current_offset ,
735+ )
736+ . map_err ( |_| Error :: AllocationError ) ?;
737+ debug ! ( "New offset {:?}" , new_offset) ;
738+ new_offset
738739 }
739740 }
740- Err ( e) => return Err ( e) ,
741- } ;
741+ }
742+ Err ( e) => return Err ( e) ,
743+ } ;
742744 let mut blocks = [ Block :: new ( ) ] ;
743745 let to_copy = core:: cmp:: min ( block_avail, bytes_to_write - written) ;
744746 if block_offset != 0 {
@@ -1043,18 +1045,33 @@ where
10431045
10441046 /// This function turns `desired_offset` into an appropriate block to be
10451047 /// read. It either calculates this based on the start of the file, or
1046- /// from the last cluster we read - whichever is better.
1048+ /// from the given start point - whichever is better.
1049+ ///
1050+ /// Returns:
1051+ ///
1052+ /// * the index for the block on the disk that contains the data we want,
1053+ /// * the byte offset into that block for the data we want, and
1054+ /// * how many bytes remain in that block.
10471055 fn find_data_on_disk (
10481056 & self ,
10491057 volume_idx : usize ,
10501058 start : & mut ( u32 , ClusterId ) ,
1059+ file_start : ClusterId ,
10511060 desired_offset : u32 ,
10521061 ) -> Result < ( BlockIdx , usize , usize ) , Error < D :: Error > > {
10531062 let bytes_per_cluster = match & self . open_volumes [ volume_idx] . volume_type {
10541063 VolumeType :: Fat ( fat) => fat. bytes_per_cluster ( ) ,
10551064 } ;
1065+ // do we need to be before our start point?
1066+ if desired_offset < start. 0 {
1067+ // user wants to go backwards - start from the beginning of the file
1068+ // because the FAT is only a singly-linked list.
1069+ start. 0 = 0 ;
1070+ start. 1 = file_start;
1071+ }
10561072 // How many clusters forward do we need to go?
10571073 let offset_from_cluster = desired_offset - start. 0 ;
1074+ // walk through the FAT chain
10581075 let num_clusters = offset_from_cluster / bytes_per_cluster;
10591076 let mut block_cache = BlockCache :: empty ( ) ;
10601077 for _ in 0 ..num_clusters {
@@ -1065,7 +1082,7 @@ where
10651082 } ;
10661083 start. 0 += bytes_per_cluster;
10671084 }
1068- // How many blocks in are we?
1085+ // How many blocks in are we now ?
10691086 let offset_from_cluster = desired_offset - start. 0 ;
10701087 assert ! ( offset_from_cluster < bytes_per_cluster) ;
10711088 let num_blocks = BlockCount ( offset_from_cluster / Block :: LEN_U32 ) ;
0 commit comments