Update number of free clusters when allocating and freeing
This commit is contained in:
parent
380add131d
commit
908ab61ee5
@ -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();
|
||||||
|
@ -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(())
|
||||||
|
26
src/fs.rs
26
src/fs.rs
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
src/table.rs
14
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)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user