diff --git a/src/lib.rs b/src/lib.rs index 27d54f6..c1a610f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -202,6 +202,10 @@ where DiskFull, /// A directory with that name already exists DirAlreadyExists, + /// The filesystem tried to gain a lock whilst already locked. + /// + /// This is a bug in the filesystem. Please open an issue. + LockError, } impl embedded_io::Error for Error { @@ -216,7 +220,8 @@ impl embedded_io::Error for Error { | Error::EndOfFile | Error::DiskFull | Error::NotEnoughSpace - | Error::AllocationError => ErrorKind::Other, + | Error::AllocationError + | Error::LockError => ErrorKind::Other, Error::NoSuchVolume | Error::FilenameError(_) | Error::BadHandle diff --git a/src/volume_mgr.rs b/src/volume_mgr.rs index 9e45a21..8202c08 100644 --- a/src/volume_mgr.rs +++ b/src/volume_mgr.rs @@ -135,7 +135,7 @@ where const PARTITION_INFO_LBA_START_INDEX: usize = 8; const PARTITION_INFO_NUM_BLOCKS_INDEX: usize = 12; - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; if data.open_volumes.is_full() { return Err(Error::TooManyOpenVolumes); @@ -218,7 +218,7 @@ where pub fn open_root_dir(&self, volume: RawVolume) -> Result> { // Opening a root directory twice is OK - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; let directory_id = RawDirectory(data.id_generator.generate()); let dir_info = DirectoryInfo { @@ -247,7 +247,7 @@ where where N: ToShortFileName, { - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; if data.open_dirs.is_full() { return Err(Error::TooManyOpenDirs); @@ -310,7 +310,7 @@ where /// Close a directory. You cannot perform operations on an open directory /// and so must close it if you want to do something with it. pub fn close_dir(&self, directory: RawDirectory) -> Result<(), Error> { - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; for (idx, info) in data.open_dirs.iter().enumerate() { if directory == info.raw_directory { @@ -325,7 +325,7 @@ where /// /// You can't close it if there are any files or directories open on it. pub fn close_volume(&self, volume: RawVolume) -> Result<(), Error> { - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; for f in data.open_files.iter() { if f.raw_volume == volume { @@ -393,7 +393,7 @@ where where N: ToShortFileName, { - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; // This check is load-bearing - we do an unchecked push later. if data.open_files.is_full() { @@ -625,7 +625,7 @@ where /// Read from an open file. pub fn read(&self, file: RawFile, buffer: &mut [u8]) -> Result> { - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; let file_idx = data.get_file_by_id(file)?; let volume_idx = data.get_volume_by_id(data.open_files[file_idx].raw_volume)?; @@ -673,7 +673,7 @@ where #[cfg(feature = "log")] debug!("write(file={:?}, buffer={:x?}", file, buffer); - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; // Clone this so we can touch our other structures. Need to ensure we // write it back at the end. @@ -799,7 +799,7 @@ where /// Close a file with the given raw file handle. pub fn close_file(&self, file: RawFile) -> Result<(), Error> { let flush_result = self.flush_file(file); - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; let file_idx = data.get_file_by_id(file)?; data.open_files.swap_remove(file_idx); flush_result @@ -808,7 +808,7 @@ where /// Flush (update the entry) for a file with the given raw file handle. pub fn flush_file(&self, file: RawFile) -> Result<(), Error> { use core::ops::DerefMut; - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; let data = data.deref_mut(); let file_id = data.get_file_by_id(file)?; @@ -851,7 +851,7 @@ where /// Seek a file with an offset from the start of the file. pub fn file_seek_from_start(&self, file: RawFile, offset: u32) -> Result<(), Error> { - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; let file_idx = data.get_file_by_id(file)?; data.open_files[file_idx] .seek_from_start(offset) @@ -865,7 +865,7 @@ where file: RawFile, offset: i32, ) -> Result<(), Error> { - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; let file_idx = data.get_file_by_id(file)?; data.open_files[file_idx] .seek_from_current(offset) @@ -875,7 +875,7 @@ where /// Seek a file with an offset back from the end of the file. pub fn file_seek_from_end(&self, file: RawFile, offset: u32) -> Result<(), Error> { - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; let file_idx = data.get_file_by_id(file)?; data.open_files[file_idx] .seek_from_end(offset) @@ -907,7 +907,7 @@ where N: ToShortFileName, { use core::ops::DerefMut; - let mut data = self.data.borrow_mut(); + let mut data = self.data.try_borrow_mut().map_err(|_| Error::LockError)?; let data = data.deref_mut(); // This check is load-bearing - we do an unchecked push later.