Skip to main content

FileDevice

Struct FileDevice 

Source
pub struct FileDevice { /* private fields */ }
Expand description

A file opened as a block device.

§Reads do not take the lock; writes do

A read was seek then read under a mutex, which made the file’s cursor shared state: two threads reading different offsets had to take turns, not because the device could not serve them at once but because one would have moved the other’s cursor.

On Unix the cursor is not involved at all — pread takes the offset as an argument — so reads run without the lock and genuinely overlap.

On Windows the equivalent (seek_read) does move the file pointer, so the lock stays there. Same behaviour, one platform paying for it.

Writes keep the lock on both, because write_at is still seek plus write_all and a partial write must not have another writer’s seek land in the middle of it.

Implementations§

Source§

impl FileDevice

Source

pub fn open<P: AsRef<Path>>(path: P) -> Result<Self>

Open read-only.

Source

pub fn open_rw<P: AsRef<Path>>(path: P) -> Result<Self>

Open read-write. Errors if the path is not writable.

Source

pub fn open_best_effort<P: AsRef<Path>>(path: P) -> Result<Self>

Open read-write if possible, fall back to read-only otherwise.

Trait Implementations§

Source§

impl BlockDevice for FileDevice

Source§

fn write_at(&self, offset: u64, buf: &[u8]) -> Result<()>

Write exactly buf.len() bytes at offset. Default: returns Error::ReadOnly.
Source§

fn flush(&self) -> Result<()>

Flush pending writes to stable storage. No-op by default.
Source§

fn is_writable(&self) -> bool

Whether write_at is likely to succeed. Mount paths use this to decide whether to attempt journal replay or stay strict-read-only.
Source§

impl BlockRead for FileDevice

Source§

fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<()>

Read exactly buf.len() bytes starting at offset (bytes from the start of the device).
Source§

fn size_bytes(&self) -> u64

Total device size in bytes. Used for bounds checks.

Auto Trait Implementations§

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.