Skip to content

Commit ab4b005

Browse files
committed
Return IO object when unmounting.
1 parent 12418eb commit ab4b005

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

src/fs.rs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
use alloc::string::String;
33
use core::borrow::BorrowMut;
44
use core::cell::{Cell, RefCell};
5-
use core::char;
5+
use core::mem::ManuallyDrop;
6+
use core::{char, ptr};
67
use core::cmp;
78
use core::convert::TryFrom;
89
use core::fmt::Debug;
@@ -256,7 +257,6 @@ impl FsOptions<DefaultTimeProvider, LossyOemCpConverter> {
256257

257258
impl<TP: TimeProvider, OCC: OemCpConverter> FsOptions<TP, OCC> {
258259
/// If enabled accessed date field in directory entry is updated when reading or writing a file.
259-
#[must_use]
260260
pub fn update_accessed_date(mut self, enabled: bool) -> Self {
261261
self.update_accessed_date = enabled;
262262
self
@@ -436,10 +436,6 @@ impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> {
436436
&full_label_slice[..len]
437437
}
438438

439-
fn offset_from_sector(&self, sector: u32) -> u64 {
440-
self.bpb.bytes_from_sectors(sector)
441-
}
442-
443439
fn sector_from_cluster(&self, cluster: u32) -> u32 {
444440
self.first_data_sector + self.bpb.sectors_from_clusters(cluster - RESERVED_FAT_ENTRIES)
445441
}
@@ -449,7 +445,7 @@ impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> {
449445
}
450446

451447
pub(crate) fn offset_from_cluster(&self, cluster: u32) -> u64 {
452-
self.offset_from_sector(self.sector_from_cluster(cluster))
448+
self.bpb.bytes_from_sectors(self.sector_from_cluster(cluster))
453449
}
454450

455451
pub(crate) fn bytes_from_clusters(&self, clusters: u32) -> u64 {
@@ -551,32 +547,37 @@ impl<IO: Read + Write + Seek, TP, OCC> FileSystem<IO, TP, OCC> {
551547
Ok(free_cluster_count)
552548
}
553549

554-
/// Unmounts the filesystem.
555-
///
556-
/// Updates the FS Information Sector if needed.
550+
/// Updates the FS Information Sector if needed and unmounts the filesystem.
557551
///
558552
/// # Errors
559553
///
560554
/// `Error::Io` will be returned if the underlying storage object returned an I/O error.
561-
pub fn unmount(self) -> Result<(), Error<IO::Error>> {
562-
self.unmount_internal()
563-
}
555+
pub fn unmount(mut self) -> Result<IO, Error<IO::Error>> {
556+
self.flush()?;
564557

565-
fn unmount_internal(&self) -> Result<(), Error<IO::Error>> {
566-
self.flush_fs_info()?;
567-
self.set_dirty_flag(false)?;
568-
Ok(())
558+
let mut fs = ManuallyDrop::new(self);
559+
// SAFETY: The `disk` field is only dropped once.
560+
let mut disk = unsafe { ptr::read(fs.disk.get_mut()) };
561+
disk.seek(SeekFrom::Start(0))?;
562+
Ok(disk)
569563
}
570564

571-
fn flush_fs_info(&self) -> Result<(), Error<IO::Error>> {
572-
let mut fs_info = self.fs_info.borrow_mut();
565+
/// Updates the FS information sector if needed.
566+
///
567+
/// # Errors
568+
///
569+
/// `Error::Io` will be returned if the underlying storage object returned an I/O error.
570+
pub fn flush(&mut self) -> Result<(), Error<IO::Error>> {
571+
let fs_info = self.fs_info.get_mut();
573572
if self.fat_type == FatType::Fat32 && fs_info.dirty {
574-
let mut disk = self.disk.borrow_mut();
575-
let fs_info_sector_offset = self.offset_from_sector(u32::from(self.bpb.fs_info_sector));
573+
let fs_info_sector_offset = self.bpb.bytes_from_sectors(self.bpb.fs_info_sector.into());
574+
let disk = self.disk.get_mut();
576575
disk.seek(SeekFrom::Start(fs_info_sector_offset))?;
577-
fs_info.serialize(&mut *disk)?;
576+
fs_info.serialize(disk)?;
578577
fs_info.dirty = false;
579578
}
579+
580+
self.set_dirty_flag(false)?;
580581
Ok(())
581582
}
582583

@@ -685,7 +686,7 @@ impl<IO: ReadWriteSeek, TP: TimeProvider, OCC: OemCpConverter> FileSystem<IO, TP
685686
/// `Drop` implementation tries to unmount the filesystem when dropping.
686687
impl<IO: ReadWriteSeek, TP, OCC> Drop for FileSystem<IO, TP, OCC> {
687688
fn drop(&mut self) {
688-
if let Err(err) = self.unmount_internal() {
689+
if let Err(err) = self.flush() {
689690
error!("unmount failed {:?}", err);
690691
}
691692
}

0 commit comments

Comments
 (0)