Skip to content

Commit c57fad8

Browse files
committed
Allow clearing FAT dirty flag.
1 parent 4892fb1 commit c57fad8

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

src/fs.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::error::Error;
1616
use crate::file::File;
1717
use crate::io::{self, IoBase, Read, ReadLeExt, Seek, SeekFrom, Write, WriteLeExt};
1818
use crate::table::{
19-
alloc_cluster, count_free_clusters, format_fat, read_fat_flags, ClusterIterator, RESERVED_FAT_ENTRIES,
19+
alloc_cluster, count_free_clusters, format_fat, read_fat_flags, write_fat_flags, ClusterIterator, RESERVED_FAT_ENTRIES,
2020
};
2121
use crate::time::{DefaultTimeProvider, TimeProvider};
2222

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

509+
fn fat_status_flags(&self) -> Result<FsStatusFlags, Error<IO::Error>> {
510+
read_fat_flags(&mut self.fat_slice(), self.fat_type)
511+
}
512+
509513
/// Returns status flags for this volume.
510514
///
511515
/// # Errors
512516
///
513517
/// `Error::Io` will be returned if the underlying storage object returned an I/O error.
514518
pub fn read_status_flags(&self) -> Result<FsStatusFlags, Error<IO::Error>> {
515519
let bpb_status = self.bpb.status_flags();
516-
let fat_status = read_fat_flags(&mut self.fat_slice(), self.fat_type)?;
520+
let fat_status = self.fat_status_flags()?;
517521
Ok(FsStatusFlags {
518522
dirty: bpb_status.dirty || fat_status.dirty,
519523
io_error: bpb_status.io_error || fat_status.io_error,
@@ -604,6 +608,15 @@ impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> {
604608
Ok(())
605609
}
606610

611+
pub fn set_fat_dirty_flag(&self, dirty: bool) -> Result<(), Error<IO::Error>> {
612+
let mut fat_status = self.fat_status_flags()?;
613+
fat_status.dirty = dirty;
614+
615+
write_fat_flags(&mut self.fat_slice(), self.fat_type, fat_status)?;
616+
617+
Ok(())
618+
}
619+
607620
/// Returns a root directory object allowing for futher penetration of a filesystem structure.
608621
pub fn root_dir(&self) -> Dir<IO, TP, OCC> {
609622
trace!("root_dir");

src/table.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ where
152152
Ok(new_cluster)
153153
}
154154

155+
const FAT16_IO_ERROR_BIT: u32 = 1 << 14;
156+
const FAT16_DIRTY_BIT: u32 = 1 << 15;
157+
158+
const FAT32_IO_ERROR_BIT: u32 = 1 << 26;
159+
const FAT32_DIRTY_BIT: u32 = 1 << 27;
160+
155161
pub(crate) fn read_fat_flags<S, E>(fat: &mut S, fat_type: FatType) -> Result<FsStatusFlags, Error<E>>
156162
where
157163
S: Read + Seek,
@@ -166,17 +172,57 @@ where
166172
};
167173
let dirty = match fat_type {
168174
FatType::Fat12 => false,
169-
FatType::Fat16 => val & (1 << 15) == 0,
170-
FatType::Fat32 => val & (1 << 27) == 0,
175+
FatType::Fat16 => val & FAT16_DIRTY_BIT == 0,
176+
FatType::Fat32 => val & FAT32_DIRTY_BIT == 0,
171177
};
172178
let io_error = match fat_type {
173179
FatType::Fat12 => false,
174-
FatType::Fat16 => val & (1 << 14) == 0,
175-
FatType::Fat32 => val & (1 << 26) == 0,
180+
FatType::Fat16 => val & FAT16_IO_ERROR_BIT == 0,
181+
FatType::Fat32 => val & FAT32_IO_ERROR_BIT == 0,
176182
};
177183
Ok(FsStatusFlags { dirty, io_error })
178184
}
179185

186+
pub(crate) fn write_fat_flags<S, E>(fat: &mut S, fat_type: FatType, fat_status: FsStatusFlags) -> Result<(), Error<E>>
187+
where
188+
S: Read + Write + Seek,
189+
E: IoError,
190+
Error<E>: From<S::Error>,
191+
{
192+
match fat_type {
193+
FatType::Fat12 => {
194+
Ok(())
195+
},
196+
FatType::Fat16 => {
197+
let mut val = 0;
198+
199+
if fat_status.dirty {
200+
val |= FAT16_DIRTY_BIT;
201+
}
202+
203+
if fat_status.io_error {
204+
val |= FAT16_IO_ERROR_BIT;
205+
}
206+
207+
Fat16::set(fat, 1, FatValue::Data(!val))
208+
},
209+
FatType::Fat32 => {
210+
211+
let mut val = 0;
212+
213+
if fat_status.dirty {
214+
val |= FAT32_DIRTY_BIT;
215+
}
216+
217+
if fat_status.io_error {
218+
val |= FAT32_IO_ERROR_BIT;
219+
}
220+
221+
Fat32::set(fat, 1, FatValue::Data(!val))
222+
},
223+
}
224+
}
225+
180226
pub(crate) fn count_free_clusters<S, E>(fat: &mut S, fat_type: FatType, total_clusters: u32) -> Result<u32, Error<E>>
181227
where
182228
S: Read + Seek,

0 commit comments

Comments
 (0)