Skip to content

Commit 07d7bd2

Browse files
committed
Bug fix for #131
Start from beginning of file if current position is *ahead* of desired position.
1 parent 83128a3 commit 07d7bd2

File tree

1 file changed

+52
-36
lines changed

1 file changed

+52
-36
lines changed

src/volume_mgr.rs

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {
@@ -1044,16 +1046,30 @@ where
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
10461048
/// from the last cluster we read - 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
};
10561065
// How many clusters forward do we need to go?
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+
}
1072+
// walk through the FAT chain
10571073
let offset_from_cluster = desired_offset - start.0;
10581074
let num_clusters = offset_from_cluster / bytes_per_cluster;
10591075
let mut block_cache = BlockCache::empty();
@@ -1065,7 +1081,7 @@ where
10651081
};
10661082
start.0 += bytes_per_cluster;
10671083
}
1068-
// How many blocks in are we?
1084+
// How many blocks in are we now?
10691085
let offset_from_cluster = desired_offset - start.0;
10701086
assert!(offset_from_cluster < bytes_per_cluster);
10711087
let num_blocks = BlockCount(offset_from_cluster / Block::LEN_U32);

0 commit comments

Comments
 (0)