diff --git a/src/fs.rs b/src/fs.rs index 4a5659a..9fdbfa2 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -424,31 +424,30 @@ impl FileSystem { // Validate the numbers stored in the free_cluster_count and next_free_cluster are within bounds for volume fs_info.validate_and_fix(total_clusters); - let mut fs = Self { - disk: RefCell::new(disk), - options, - fat_type, - bpb, - first_data_sector, - root_dir_sectors, - total_clusters, - fs_info: RefCell::new(fs_info), - current_status_flags: Cell::new(bpb_status_flags), - }; - let mut fat_status_flags = fs.read_fat_status_flags()?; + let mut fat_status_flags = read_fat_flags(&mut fat_slice::<&mut IO, IO::Error, IO>(&mut disk, &bpb), fat_type)?; if fat_status_flags.dirty() { - if fs.options.ignore_dirty_flag { + if options.ignore_dirty_flag { warn!("FAT is dirty, clearing dirty flag."); fat_status_flags.dirty = false; - fs.set_fat_status_flags(fat_status_flags)?; + write_fat_flags(&mut fat_slice::<&mut IO, IO::Error, IO>(&mut disk, &bpb), fat_type, fat_status_flags)?; } else { return Err(Error::DirtyFileSystem); } } trace!("FileSystem::new end"); - Ok(fs) + Ok(Self { + disk: RefCell::new(disk), + options, + fat_type, + bpb, + first_data_sector, + root_dir_sectors, + total_clusters, + fs_info: RefCell::new(fs_info), + current_status_flags: Cell::new(bpb_status_flags), + }) } /// Returns a type of File Allocation Table (FAT) used by this filesystem. @@ -499,15 +498,16 @@ impl FileSystem { self.bpb.clusters_from_bytes(bytes) } - fn fat_slice(&self) -> FatSlice<'_, IO, TP, OCC, IO::Error> { - let io = FsIoAdapter { fs: self }; + fn fat_slice(&self) -> FatSlice<'_, IO, IO::Error> { + let io = FsIoAdapter { + disk: &self.disk, + fat_type: self.fat_type(), + current_status_flags: &self.current_status_flags, + }; fat_slice(io, &self.bpb) } - pub(crate) fn cluster_iter( - &self, - cluster: u32, - ) -> ClusterIterator, IO::Error> { + pub(crate) fn cluster_iter(&self, cluster: u32) -> ClusterIterator, IO::Error> { let disk_slice = self.fat_slice(); ClusterIterator::new(disk_slice, self.fat_type, cluster) } @@ -553,7 +553,7 @@ impl FileSystem { /// `Error::Io` will be returned if the underlying storage object returned an I/O error. pub fn read_status_flags(&self) -> Result> { let bpb_status = self.current_status_flags.get(); - let fat_status = self.read_fat_status_flags()?; + let fat_status = read_fat_flags(&mut self.fat_slice(), self.fat_type)?; Ok(FsStatusFlags { dirty: bpb_status.dirty || fat_status.dirty, io_error: bpb_status.io_error || fat_status.io_error, @@ -619,31 +619,10 @@ impl FileSystem { Ok(()) } + #[inline] pub(crate) fn set_dirty_flag(&self, dirty: bool) -> Result<(), Error> { - let mut status_flags = self.current_status_flags.get(); - - if status_flags.dirty == dirty { - // Dirty flag did not change. - return Ok(()); - } - - status_flags.dirty = dirty; - let mut disk = self.disk.borrow_mut(); - write_bpb_status_flags(&mut *disk, self.fat_type(), status_flags)?; - self.current_status_flags.set(status_flags); - - Ok(()) - } - - #[inline] - fn read_fat_status_flags(&self) -> Result> { - read_fat_flags(&mut self.fat_slice(), self.fat_type) - } - - #[inline] - fn set_fat_status_flags(&self, status_flags: FsStatusFlags) -> Result<(), Error> { - write_fat_flags(&mut self.fat_slice(), self.fat_type, status_flags) + set_dirty_flag(&mut *disk, self.fat_type(), &self.current_status_flags, dirty) } /// Returns a root directory object allowing for futher penetration of a filesystem structure. @@ -773,6 +752,27 @@ impl Clone for FsIoAdapter<'_, IO, TP, OCC> { } } +fn set_dirty_flag( + disk: &mut IO, + fat_type: FatType, + current_status_flags: &Cell, + dirty: bool, +) -> Result<(), Error> { + let mut status_flags = current_status_flags.get(); + + if status_flags.dirty == dirty { + // Dirty flag did not change. + return Ok(()); + } + + status_flags.dirty = dirty; + + write_bpb_status_flags(disk, fat_type, status_flags)?; + current_status_flags.set(status_flags); + + Ok(()) +} + fn write_bpb_status_flags( disk: &mut IO, fat_type: FatType,