@@ -624,6 +624,7 @@ where
624
624
let ( block_idx, block_offset, block_avail) = self . find_data_on_disk (
625
625
volume_idx,
626
626
& mut current_cluster,
627
+ self . open_files [ file_idx] . entry . cluster ,
627
628
self . open_files [ file_idx] . current_offset ,
628
629
) ?;
629
630
self . open_files [ file_idx] . current_cluster = current_cluster;
@@ -701,44 +702,45 @@ where
701
702
written, bytes_to_write, current_cluster
702
703
) ;
703
704
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 ) ;
737
727
}
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
738
739
}
739
740
}
740
- Err ( e) => return Err ( e) ,
741
- } ;
741
+ }
742
+ Err ( e) => return Err ( e) ,
743
+ } ;
742
744
let mut blocks = [ Block :: new ( ) ] ;
743
745
let to_copy = core:: cmp:: min ( block_avail, bytes_to_write - written) ;
744
746
if block_offset != 0 {
@@ -1043,18 +1045,33 @@ where
1043
1045
1044
1046
/// This function turns `desired_offset` into an appropriate block to be
1045
1047
/// 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.
1047
1055
fn find_data_on_disk (
1048
1056
& self ,
1049
1057
volume_idx : usize ,
1050
1058
start : & mut ( u32 , ClusterId ) ,
1059
+ file_start : ClusterId ,
1051
1060
desired_offset : u32 ,
1052
1061
) -> Result < ( BlockIdx , usize , usize ) , Error < D :: Error > > {
1053
1062
let bytes_per_cluster = match & self . open_volumes [ volume_idx] . volume_type {
1054
1063
VolumeType :: Fat ( fat) => fat. bytes_per_cluster ( ) ,
1055
1064
} ;
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
+ }
1056
1072
// How many clusters forward do we need to go?
1057
1073
let offset_from_cluster = desired_offset - start. 0 ;
1074
+ // walk through the FAT chain
1058
1075
let num_clusters = offset_from_cluster / bytes_per_cluster;
1059
1076
let mut block_cache = BlockCache :: empty ( ) ;
1060
1077
for _ in 0 ..num_clusters {
@@ -1065,7 +1082,7 @@ where
1065
1082
} ;
1066
1083
start. 0 += bytes_per_cluster;
1067
1084
}
1068
- // How many blocks in are we?
1085
+ // How many blocks in are we now ?
1069
1086
let offset_from_cluster = desired_offset - start. 0 ;
1070
1087
assert ! ( offset_from_cluster < bytes_per_cluster) ;
1071
1088
let num_blocks = BlockCount ( offset_from_cluster / Block :: LEN_U32 ) ;
0 commit comments