diff --git a/src/dir.rs b/src/dir.rs index d00c525..c7a6d72 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -203,9 +203,8 @@ impl <'a, 'b> Dir<'a, 'b> { return Err(io::Error::new(ErrorKind::NotFound, "removing non-empty directory is denied")); } // free directory data - match e.first_cluster() { - Some(n) => self.fs.cluster_iter(n).free()?, - _ => {}, + if let Some(n) = e.first_cluster() { + self.fs.free_cluster_chain(n)?; } // free long and short name entries let mut stream = self.stream.clone(); diff --git a/src/file.rs b/src/file.rs index 9ab94d9..22cfc90 100644 --- a/src/file.rs +++ b/src/file.rs @@ -51,11 +51,11 @@ impl <'a, 'b> File<'a, 'b> { if self.offset > 0 { debug_assert!(self.current_cluster.is_some()); // 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 { debug_assert!(self.current_cluster.is_none()); if let Some(n) = self.first_cluster { - self.fs.cluster_iter(n).free()?; + self.fs.free_cluster_chain(n)?; self.first_cluster = None; } Ok(()) diff --git a/src/fs.rs b/src/fs.rs index 6993e2d..bf7105f 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -261,6 +261,12 @@ impl FsInfoSector { wrt.write_u32::(Self::TRAIL_SIG)?; 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. @@ -433,11 +439,29 @@ impl <'a> FileSystem<'a> { 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) -> io::Result { let hint = self.fs_info.borrow().next_free_cluster; let mut fat = self.fat_slice(); 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) } diff --git a/src/table.rs b/src/table.rs index cdfa311..7c088b4 100644 --- a/src/table.rs +++ b/src/table.rs @@ -337,14 +337,14 @@ impl <'a, 'b> ClusterIterator<'a, 'b> { pub(crate) fn new(fat: DiskSlice<'a, 'b>, fat_type: FatType, cluster: u32) -> ClusterIterator<'a, 'b> { ClusterIterator { - fat: fat, - fat_type: fat_type, + fat, + fat_type, cluster: Some(cluster), err: false, } } - pub(crate) fn truncate(&mut self) -> io::Result<()> { + pub(crate) fn truncate(&mut self) -> io::Result { match self.cluster { Some(n) => { // Move to the next cluster @@ -354,16 +354,18 @@ impl <'a, 'b> ClusterIterator<'a, 'b> { // Free rest of chain self.free() }, - None => Ok(()), + None => Ok(0), } } - pub(crate) fn free(&mut self) -> io::Result<()> { + pub(crate) fn free(&mut self) -> io::Result { + let mut num_free = 0; while let Some(n) = self.cluster { self.next(); write_fat(&mut self.fat, self.fat_type, n, FatValue::Free)?; + num_free += 1; } - Ok(()) + Ok(num_free) } }