Skip to content

Commit

Permalink
Allow clearing FAT dirty flag.
Browse files Browse the repository at this point in the history
  • Loading branch information
reitermarkus committed May 31, 2022
1 parent 4892fb1 commit c57fad8
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 6 deletions.
17 changes: 15 additions & 2 deletions src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::error::Error;
use crate::file::File;
use crate::io::{self, IoBase, Read, ReadLeExt, Seek, SeekFrom, Write, WriteLeExt};
use crate::table::{
alloc_cluster, count_free_clusters, format_fat, read_fat_flags, ClusterIterator, RESERVED_FAT_ENTRIES,
alloc_cluster, count_free_clusters, format_fat, read_fat_flags, write_fat_flags, ClusterIterator, RESERVED_FAT_ENTRIES,
};
use crate::time::{DefaultTimeProvider, TimeProvider};

Expand Down Expand Up @@ -506,14 +506,18 @@ impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> {
Ok(cluster)
}

fn fat_status_flags(&self) -> Result<FsStatusFlags, Error<IO::Error>> {
read_fat_flags(&mut self.fat_slice(), self.fat_type)
}

/// Returns status flags for this volume.
///
/// # Errors
///
/// `Error::Io` will be returned if the underlying storage object returned an I/O error.
pub fn read_status_flags(&self) -> Result<FsStatusFlags, Error<IO::Error>> {
let bpb_status = self.bpb.status_flags();
let fat_status = read_fat_flags(&mut self.fat_slice(), self.fat_type)?;
let fat_status = self.fat_status_flags()?;
Ok(FsStatusFlags {
dirty: bpb_status.dirty || fat_status.dirty,
io_error: bpb_status.io_error || fat_status.io_error,
Expand Down Expand Up @@ -604,6 +608,15 @@ impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> {
Ok(())
}

pub fn set_fat_dirty_flag(&self, dirty: bool) -> Result<(), Error<IO::Error>> {
let mut fat_status = self.fat_status_flags()?;
fat_status.dirty = dirty;

write_fat_flags(&mut self.fat_slice(), self.fat_type, fat_status)?;

Ok(())
}

/// Returns a root directory object allowing for futher penetration of a filesystem structure.
pub fn root_dir(&self) -> Dir<IO, TP, OCC> {
trace!("root_dir");
Expand Down
54 changes: 50 additions & 4 deletions src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ where
Ok(new_cluster)
}

const FAT16_IO_ERROR_BIT: u32 = 1 << 14;
const FAT16_DIRTY_BIT: u32 = 1 << 15;

const FAT32_IO_ERROR_BIT: u32 = 1 << 26;
const FAT32_DIRTY_BIT: u32 = 1 << 27;

pub(crate) fn read_fat_flags<S, E>(fat: &mut S, fat_type: FatType) -> Result<FsStatusFlags, Error<E>>
where
S: Read + Seek,
Expand All @@ -166,17 +172,57 @@ where
};
let dirty = match fat_type {
FatType::Fat12 => false,
FatType::Fat16 => val & (1 << 15) == 0,
FatType::Fat32 => val & (1 << 27) == 0,
FatType::Fat16 => val & FAT16_DIRTY_BIT == 0,
FatType::Fat32 => val & FAT32_DIRTY_BIT == 0,
};
let io_error = match fat_type {
FatType::Fat12 => false,
FatType::Fat16 => val & (1 << 14) == 0,
FatType::Fat32 => val & (1 << 26) == 0,
FatType::Fat16 => val & FAT16_IO_ERROR_BIT == 0,
FatType::Fat32 => val & FAT32_IO_ERROR_BIT == 0,
};
Ok(FsStatusFlags { dirty, io_error })
}

pub(crate) fn write_fat_flags<S, E>(fat: &mut S, fat_type: FatType, fat_status: FsStatusFlags) -> Result<(), Error<E>>
where
S: Read + Write + Seek,
E: IoError,
Error<E>: From<S::Error>,
{
match fat_type {
FatType::Fat12 => {
Ok(())
},
FatType::Fat16 => {
let mut val = 0;

if fat_status.dirty {
val |= FAT16_DIRTY_BIT;
}

if fat_status.io_error {
val |= FAT16_IO_ERROR_BIT;
}

Fat16::set(fat, 1, FatValue::Data(!val))
},
FatType::Fat32 => {

let mut val = 0;

if fat_status.dirty {
val |= FAT32_DIRTY_BIT;
}

if fat_status.io_error {
val |= FAT32_IO_ERROR_BIT;
}

Fat32::set(fat, 1, FatValue::Data(!val))
},
}
}

pub(crate) fn count_free_clusters<S, E>(fat: &mut S, fat_type: FatType, total_clusters: u32) -> Result<u32, Error<E>>
where
S: Read + Seek,
Expand Down

0 comments on commit c57fad8

Please sign in to comment.