Update number of free clusters when allocating and freeing

This commit is contained in:
Rafał Harabień 2018-05-27 23:31:40 +02:00
parent 380add131d
commit 908ab61ee5
4 changed files with 37 additions and 12 deletions

View File

@ -203,9 +203,8 @@ impl <'a, 'b> Dir<'a, 'b> {
return Err(io::Error::new(ErrorKind::NotFound, "removing non-empty directory is denied")); return Err(io::Error::new(ErrorKind::NotFound, "removing non-empty directory is denied"));
} }
// free directory data // free directory data
match e.first_cluster() { if let Some(n) = e.first_cluster() {
Some(n) => self.fs.cluster_iter(n).free()?, self.fs.free_cluster_chain(n)?;
_ => {},
} }
// free long and short name entries // free long and short name entries
let mut stream = self.stream.clone(); let mut stream = self.stream.clone();

View File

@ -51,11 +51,11 @@ impl <'a, 'b> File<'a, 'b> {
if self.offset > 0 { if self.offset > 0 {
debug_assert!(self.current_cluster.is_some()); debug_assert!(self.current_cluster.is_some());
// if offset is not 0 current cluster cannot be empty // if offset is not 0 current cluster cannot be empty
self.fs.cluster_iter(self.current_cluster.unwrap()).truncate() // SAFE self.fs.truncate_cluster_chain(self.current_cluster.unwrap()) // SAFE
} else { } else {
debug_assert!(self.current_cluster.is_none()); debug_assert!(self.current_cluster.is_none());
if let Some(n) = self.first_cluster { if let Some(n) = self.first_cluster {
self.fs.cluster_iter(n).free()?; self.fs.free_cluster_chain(n)?;
self.first_cluster = None; self.first_cluster = None;
} }
Ok(()) Ok(())

View File

@ -261,6 +261,12 @@ impl FsInfoSector {
wrt.write_u32::<LittleEndian>(Self::TRAIL_SIG)?; wrt.write_u32::<LittleEndian>(Self::TRAIL_SIG)?;
Ok(()) Ok(())
} }
fn add_free_clusters(&mut self, free_clusters: i32) {
if let Some(n) = self.free_cluster_count {
self.free_cluster_count = Some((n as i32 + free_clusters) as u32);
}
}
} }
/// FAT filesystem options. /// FAT filesystem options.
@ -433,11 +439,29 @@ impl <'a> FileSystem<'a> {
ClusterIterator::new(disk_slice, self.fat_type, cluster) ClusterIterator::new(disk_slice, self.fat_type, cluster)
} }
pub(crate) fn truncate_cluster_chain(&self, cluster: u32) -> io::Result<()> {
let mut iter = self.cluster_iter(cluster);
let num_free = iter.truncate()?;
let mut fs_info = self.fs_info.borrow_mut();
fs_info.add_free_clusters(num_free as i32);
Ok(())
}
pub(crate) fn free_cluster_chain(&self, cluster: u32) -> io::Result<()> {
let mut iter = self.cluster_iter(cluster);
let num_free = iter.free()?;
let mut fs_info = self.fs_info.borrow_mut();
fs_info.add_free_clusters(num_free as i32);
Ok(())
}
pub(crate) fn alloc_cluster(&self, prev_cluster: Option<u32>) -> io::Result<u32> { pub(crate) fn alloc_cluster(&self, prev_cluster: Option<u32>) -> io::Result<u32> {
let hint = self.fs_info.borrow().next_free_cluster; let hint = self.fs_info.borrow().next_free_cluster;
let mut fat = self.fat_slice(); let mut fat = self.fat_slice();
let cluster = alloc_cluster(&mut fat, self.fat_type, prev_cluster, hint, self.total_clusters)?; let cluster = alloc_cluster(&mut fat, self.fat_type, prev_cluster, hint, self.total_clusters)?;
self.fs_info.borrow_mut().next_free_cluster = Some(cluster + 1); let mut fs_info = self.fs_info.borrow_mut();
fs_info.next_free_cluster = Some(cluster + 1);
fs_info.add_free_clusters(-1);
Ok(cluster) Ok(cluster)
} }

View File

@ -337,14 +337,14 @@ impl <'a, 'b> ClusterIterator<'a, 'b> {
pub(crate) fn new(fat: DiskSlice<'a, 'b>, fat_type: FatType, cluster: u32) pub(crate) fn new(fat: DiskSlice<'a, 'b>, fat_type: FatType, cluster: u32)
-> ClusterIterator<'a, 'b> { -> ClusterIterator<'a, 'b> {
ClusterIterator { ClusterIterator {
fat: fat, fat,
fat_type: fat_type, fat_type,
cluster: Some(cluster), cluster: Some(cluster),
err: false, err: false,
} }
} }
pub(crate) fn truncate(&mut self) -> io::Result<()> { pub(crate) fn truncate(&mut self) -> io::Result<u32> {
match self.cluster { match self.cluster {
Some(n) => { Some(n) => {
// Move to the next cluster // Move to the next cluster
@ -354,16 +354,18 @@ impl <'a, 'b> ClusterIterator<'a, 'b> {
// Free rest of chain // Free rest of chain
self.free() self.free()
}, },
None => Ok(()), None => Ok(0),
} }
} }
pub(crate) fn free(&mut self) -> io::Result<()> { pub(crate) fn free(&mut self) -> io::Result<u32> {
let mut num_free = 0;
while let Some(n) = self.cluster { while let Some(n) = self.cluster {
self.next(); self.next();
write_fat(&mut self.fat, self.fat_type, n, FatValue::Free)?; write_fat(&mut self.fat, self.fat_type, n, FatValue::Free)?;
num_free += 1;
} }
Ok(()) Ok(num_free)
} }
} }