Update FSInfo sector on unmount/drop

This commit is contained in:
Rafał Harabień 2018-05-27 23:48:38 +02:00
parent 908ab61ee5
commit 147b31fdcd
3 changed files with 38 additions and 2 deletions

View File

@ -1,6 +1,5 @@
TODO TODO
==== ====
* FsInfo sector handling
* move file API * move file API
* format volume API * format volume API
* better no_std support * better no_std support

View File

@ -273,12 +273,14 @@ impl FsInfoSector {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct FsOptions { pub struct FsOptions {
pub(crate) update_accessed_date: bool, pub(crate) update_accessed_date: bool,
pub(crate) update_fs_info: bool,
} }
impl FsOptions { impl FsOptions {
pub fn new() -> Self { pub fn new() -> Self {
FsOptions { FsOptions {
update_accessed_date: false, update_accessed_date: false,
update_fs_info: false,
} }
} }
@ -287,6 +289,12 @@ impl FsOptions {
self.update_accessed_date = enabled; self.update_accessed_date = enabled;
self self
} }
/// If enabled library updates FSInfo sector when unmounting
pub fn update_fs_info(mut self, enabled: bool) -> Self {
self.update_fs_info = enabled;
self
}
} }
/// FAT filesystem statistics /// FAT filesystem statistics
@ -493,6 +501,35 @@ impl <'a> FileSystem<'a> {
free_clusters, free_clusters,
}) })
} }
/// Unmounts filesystem. Updates FSInfo sector if required in options.
pub fn unmount(self) -> io::Result<()> {
self.unmount_internal()
}
fn unmount_internal(&self) -> io::Result<()> {
if self.options.update_fs_info {
self.flush_fs_info()?;
}
Ok(())
}
fn flush_fs_info(&self) -> io::Result<()> {
if self.fat_type == FatType::Fat32 {
let mut disk = self.disk.borrow_mut();
disk.seek(SeekFrom::Start(self.bpb.fs_info_sector as u64 * 512))?;
self.fs_info.borrow().serialize(&mut *disk)?;
}
Ok(())
}
}
impl<'a> Drop for FileSystem<'a> {
fn drop(&mut self) {
if let Err(err) = self.unmount_internal() {
error!("unmount failed {}", err);
}
}
} }
#[derive(Clone)] #[derive(Clone)]

View File

@ -24,7 +24,7 @@ fn call_with_fs(f: &Fn(FileSystem) -> (), filename: &str, test_seq: u32) {
{ {
let file = fs::OpenOptions::new().read(true).write(true).open(&tmp_path).unwrap(); let file = fs::OpenOptions::new().read(true).write(true).open(&tmp_path).unwrap();
let mut buf_file = BufStream::new(file); let mut buf_file = BufStream::new(file);
let options = FsOptions::new().update_accessed_date(true); let options = FsOptions::new().update_accessed_date(true).update_fs_info(true);
let fs = FileSystem::new(&mut buf_file, options).unwrap(); let fs = FileSystem::new(&mut buf_file, options).unwrap();
f(fs); f(fs);
} }