Skip to main content

VolumeManager

Struct VolumeManager 

Source
pub struct VolumeManager<D, T, const MAX_DIRS: usize = 4, const MAX_FILES: usize = 4, const MAX_VOLUMES: usize = 1>
where D: BlockDevice, T: TimeSource,
{ /* private fields */ }
Expand description

Wraps a block device and gives access to the FAT-formatted volumes within it.

Tracks which files and directories are open, to prevent you from deleting a file or directory you currently have open.

Implementations§

Source§

impl<D, T> VolumeManager<D, T, 4, 4>
where D: BlockDevice, T: TimeSource,

Source

pub fn new(block_device: D, time_source: T) -> Self

Create a new Volume Manager using a generic BlockDevice. From this object we can open volumes (partitions) and with those we can open files.

This creates a VolumeManager with default values MAX_DIRS = 4, MAX_FILES = 4, MAX_VOLUMES = 1. Call VolumeManager::new_with_limits(block_device, time_source) if you need different limits.

Source§

impl<D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where D: BlockDevice, T: TimeSource,

Source

pub fn new_with_limits(block_device: D, time_source: T, id_offset: u32) -> Self

Create a new Volume Manager using a generic BlockDevice. From this object we can open volumes (partitions) and with those we can open files.

You can also give an offset for all the IDs this volume manager generates, which might help you find the IDs in your logs when debugging.

Source

pub fn device<R, F>(&self, f: F) -> R
where F: FnOnce(&mut D) -> R,

Temporarily get access to the underlying block device.

Source

pub fn open_volume( &self, volume_idx: VolumeIdx, ) -> Result<Volume<'_, D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>, Error<D::Error>>

Get a volume (or partition) based on entries in the Master Boot Record.

We do not support GUID Partition Table disks. Nor do we support any concept of drive letters - that is for a higher layer to handle.

Source

pub fn open_raw_volume( &self, volume_idx: VolumeIdx, ) -> Result<RawVolume, Error<D::Error>>

Get a volume (or partition) based on entries in the Master Boot Record.

We do not support GUID Partition Table disks. Nor do we support any concept of drive letters - that is for a higher layer to handle.

This function gives you a RawVolume and when you are finished with it, you must close the volume by calling VolumeManager::close_volume otherwise you will leak internal resources.

If you want a volume handle that closes itself on drop, see Volume.

Source

pub fn open_root_dir( &self, volume: RawVolume, ) -> Result<RawDirectory, Error<D::Error>>

Open the volume’s root directory.

You can then read the directory entries with iterate_dir, or you can use open_file_in_dir.

This function gives you a RawDirectory and when you are finished with it, you must close the directory by calling VolumeManager::close_dir otherwise you will leak internal resources.

If you want a directory handle that closes itself on drop, see Directory.

Source

pub fn open_dir<N>( &self, parent_dir: RawDirectory, name: N, ) -> Result<RawDirectory, Error<D::Error>>
where N: ToShortFileName,

Open a directory.

You can then read the directory entries with iterate_dir and open_file_in_dir.

Passing “.” as the name results in opening the parent_dir a second time.

This function gives you a RawDirectory and when you are finished with it, you must close the directory by calling VolumeManager::close_dir otherwise you will leak internal resources.

If you want a directory handle that closes itself on drop, see Directory.

Source

pub fn close_dir(&self, directory: RawDirectory) -> Result<(), Error<D::Error>>

Close a directory.

This releases internal resources and renders the given RawDirectory unusable (although you should discard the value rather than relying on getting an error if you do attempt to use it again).

Source

pub fn close_volume(&self, volume: RawVolume) -> Result<(), Error<D::Error>>

Close a volume.

You can’t close it if there are any files or directories open on it.

If the info sector update (which is non-critical) fails, the volume is closed anyway and the resulting error is returned.

This releases internal resources and renders the given RawVolume unusable (although you should discard the value rather than relying on getting an error if you do attempt to use it again).

Source

pub fn find_directory_entry<N>( &self, directory: RawDirectory, name: N, ) -> Result<DirEntry, Error<D::Error>>
where N: ToShortFileName,

Look in a directory for a named file.

You will either get DirEntry with a matching file name, or an error. The DirEntry will give you the file size, creation date, etc.

You can just drop the DirEntry when you are done with it - it’s a stand-alone object and takes up no resources in this Volume Manager.

§Open Files

The file length and last update time may be wrong for any currently open files that have not been flushed.

Source

pub fn iterate_dir<F>( &self, directory: RawDirectory, func: F, ) -> Result<(), Error<D::Error>>
where F: FnMut(&DirEntry) -> ControlFlow<()>,

Call a callback function for each directory entry in a directory.

Long File Names will be ignored.

Do not attempt to call any methods on the VolumeManager or any of its handles from inside the callback. You will get a lock error because the object is already locked in order to do the iteration.

§Open Files

The file length and last update time may be wrong for any currently open files that have not been flushed.

Source

pub fn iterate_dir_lfn<F>( &self, directory: RawDirectory, lfn_buffer: &mut LfnBuffer<'_>, func: F, ) -> Result<(), Error<D::Error>>
where F: FnMut(&DirEntry, Option<&str>) -> ControlFlow<()>,

Call a callback function for each directory entry in a directory, and process Long File Names.

You must supply a LfnBuffer this API can use to temporarily hold the Long File Name. If you pass one that isn’t large enough, any Long File Names that don’t fit will be ignored and presented as if they only had a Short File Name.

Do not attempt to call any methods on the VolumeManager or any of its handles from inside the callback. You will get a lock error because the object is already locked in order to do the iteration.

§Open Files

The file length and last update time may be wrong for any currently open files that have not been flushed.

Source

pub fn open_file_in_dir<N>( &self, directory: RawDirectory, name: N, mode: Mode, ) -> Result<RawFile, Error<D::Error>>
where N: ToShortFileName,

Open a file with the given short file name, in the given directory.

This function gives you a RawFile and when you are finished with it, you must close the file by calling VolumeManager::close_file otherwise you will leak internal resources and/or suffer file-system corruption and data loss.

If you want a file handle that closes itself on drop, see File.

Source

pub fn open_long_name_file_in_dir( &self, directory: RawDirectory, name: &str, mode: Mode, ) -> Result<RawFile, Error<D::Error>>

Open a file with the given Unicode long file name, in the given directory.

You can only open existing long-file-name files - you cannot create them.

This function gives you a RawFile and when you are finished with it, you must close the file by calling VolumeManager::close_file otherwise you will leak internal resources and/or suffer file-system corruption and data loss.

If you want a file handle that closes itself on drop, see File.

Source

pub fn delete_entry_in_dir<N>( &self, directory: RawDirectory, name: N, ) -> Result<(), Error<D::Error>>
where N: ToShortFileName,

Delete a closed file or empty directory with the given filename, if it exists.

Source

pub fn get_root_volume_label( &self, raw_volume: RawVolume, ) -> Result<Option<VolumeName>, Error<D::Error>>

Get the volume label

Will look in the filesystem metadata for a volume label, and if nothing is found, will search the root directory for a volume label.

Source

pub fn read( &self, file: RawFile, buffer: &mut [u8], ) -> Result<usize, Error<D::Error>>

Read from an open file.

We read as many bytes as we can, stopping at either the length of buffer, or the end of the file.

The number of bytes written to buffer is returned on success, otherwise you get an error and you should not rely on either the current seek position or the contents of buffer.

Source

pub fn write(&self, file: RawFile, buffer: &[u8]) -> Result<(), Error<D::Error>>

Write to a open file.

Endeavours to write the entire contents of the slice, stopping only if there is an error reading from or writing to the disk, or if the volume runs out of space.

If you get an error, then you cannot be sure how much of buffer was successfully written, nor can you rely on the current seek position.

Source

pub fn close_file(&self, file: RawFile) -> Result<(), Error<D::Error>>

Close a file with the given raw file handle.

Attempts to flush the file before closing, if necessary. If the flush fails, the file is closed anyway and the resulting error is returned.

This is important as it causes the file metadata to be updated in the file’s directory entry. Simply dropping the RawFile would leak internal resources and cause that metadata to be wrong.

Source

pub fn flush_file(&self, file: RawFile) -> Result<(), Error<D::Error>>

Flush (update the entry) for a file with the given raw file handle.

Source

pub fn has_open_handles(&self) -> bool

Check if any files or folders are open.

Source

pub fn free(self) -> (D, T)

Consume self and return BlockDevice and TimeSource

Source

pub fn file_eof(&self, file: RawFile) -> Result<bool, Error<D::Error>>

Check if a file is at End Of File.

A file is at End of File if the seek position is equal to the length of the file. This means any reads will fail with an End of File error, and any writes will append to the file.

Source

pub fn file_seek_from_start( &self, file: RawFile, offset: u32, ) -> Result<(), Error<D::Error>>

Seek a file with an offset from the start of the file.

The file seek position will end up equal to the offset given.

Note that the offset is only a u32, therefore we can only handle files up to 4 GiB in size.

Source

pub fn file_seek_from_current( &self, file: RawFile, offset: i32, ) -> Result<(), Error<D::Error>>

Seek a file with an offset from the current position.

The file seek position will be adjusted by the amount given.

Note that the offset is only a i32, therefore we can only handle seeks that are up to 2 GiB before or after the current position. If this is a problem, seek in multiple steps.

Source

pub fn file_seek_from_end( &self, file: RawFile, offset: u32, ) -> Result<(), Error<D::Error>>

Seek a file with an offset back from the end of the file.

The file seek position will set to the file length, minus the amount given.

Note that the offset is only a u32, therefore we can only handle files up to 4 GiB in size.

Source

pub fn file_length(&self, file: RawFile) -> Result<u32, Error<D::Error>>

Get the length of a file

Note that the file length is only a u32, therefore we can only handle files up to 4 GiB in size.

Source

pub fn file_offset(&self, file: RawFile) -> Result<u32, Error<D::Error>>

Get the current offset of a file

Note that the file offset is only a u32, therefore we can only handle files up to 4 GiB in size.

Source

pub fn make_dir_in_dir<N>( &self, directory: RawDirectory, name: N, ) -> Result<(), Error<D::Error>>
where N: ToShortFileName,

Create a directory in a given directory, with the given short name.

The directory will be empty (apart from any mandatory entries, such as the the . and .. entries on FAT filesystems).

Trait Implementations§

Source§

impl<D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> Debug for VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where D: BlockDevice + Debug, T: TimeSource + Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<D, T, const MAX_DIRS: usize = 4, const MAX_FILES: usize = 4, const MAX_VOLUMES: usize = 1> !Freeze for VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>

§

impl<D, T, const MAX_DIRS: usize = 4, const MAX_FILES: usize = 4, const MAX_VOLUMES: usize = 1> !RefUnwindSafe for VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>

§

impl<D, T, const MAX_DIRS: usize = 4, const MAX_FILES: usize = 4, const MAX_VOLUMES: usize = 1> !Sync for VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>

§

impl<D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> Send for VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where T: Send, D: Send,

§

impl<D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> Unpin for VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where T: Unpin, D: Unpin,

§

impl<D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> UnsafeUnpin for VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where T: UnsafeUnpin, D: UnsafeUnpin,

§

impl<D, T, const MAX_DIRS: usize, const MAX_FILES: usize, const MAX_VOLUMES: usize> UnwindSafe for VolumeManager<D, T, MAX_DIRS, MAX_FILES, MAX_VOLUMES>
where T: UnwindSafe, D: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.