Struct SyncFormatAccess

Source
pub struct SyncFormatAccess<S: Storage + 'static> {
    inner: FormatAccess<S>,
    runtime: Runtime,
}
Expand description

Synchronous wrapper around FormatAccess.

Creates and keeps a tokio runtime in which to run I/O.

Fields§

§inner: FormatAccess<S>

Wrapped asynchronous FormatAccess.

§runtime: Runtime

Tokio runtime in which I/O is run.

Implementations§

Source§

impl<S: Storage + 'static> SyncFormatAccess<S>

Source

pub fn new<D: FormatDriverInstance<Storage = S> + 'static>( inner: D, ) -> Result<Self>

Like FormatAccess::new(), but create a synchronous wrapper.

Source

pub fn inner(&self) -> &FormatAccess<S>

Get a reference to the contained async FormatAccess object.

Source

pub fn size(&self) -> u64

Return the disk size in bytes.

Source

pub fn set_async_read_parallelization(&mut self, count: usize)

Set the number of simultaneous async requests per read.

When issuing read requests, issue this many async requests in parallel (still in a single thread). The default count is 1, i.e. no parallel requests.

Note that inside of this synchronous wrapper, we still run async functions, so this setting is valid even for SyncFormatAccess.

Source

pub fn set_async_write_parallelization(&mut self, count: usize)

Set the number of simultaneous async requests per write.

When issuing write requests, issue this many async requests in parallel (still in a single thread). The default count is 1, i.e. no parallel requests.

Note that inside of this synchronous wrapper, we still run async functions, so this setting is valid even for SyncFormatAccess.

Source

pub fn req_align(&self) -> usize

Minimal I/O alignment, for both length and offset.

All requests to this image should be aligned to this value, both in length and offset.

Requests that do not match this alignment will be realigned internally, which requires creating bounce buffers and read-modify-write cycles for write requests, which is costly, so should be avoided.

Source

pub fn mem_align(&self) -> usize

Minimal memory buffer alignment, for both address and length.

All buffers used in requests to this image should be aligned to this value, both their address and length.

Request buffers that do not match this alignment will be realigned internally, which requires creating bounce buffers, which is costly, so should be avoided.

Source

pub fn get_mapping_sync( &self, offset: u64, max_length: u64, ) -> Result<(Mapping<'_, S>, u64)>

Return the mapping at offset.

Find what offset is mapped to, return that mapping information, and the length of that continuous mapping (from offset).

Source

pub fn ensure_data_mapping( &self, offset: u64, length: u64, overwrite: bool, ) -> Result<(&S, u64, u64)>

Create a raw data mapping at offset.

Ensure that offset is directly mapped to some storage object, up to a length of length. Return the storage object, the corresponding offset there, and the continuous length that we were able to map (less than or equal to length).

If overwrite is true, the contents in the range are supposed to be overwritten and may be discarded. Otherwise, they are kept.

Source

pub fn readv(&self, bufv: IoVectorMut<'_>, offset: u64) -> Result<()>

Read data at offset into bufv.

Reads until bufv is filled completely, i.e. will not do short reads. When reaching the end of file, the rest of bufv is filled with 0.

Source

pub fn read<'a>( &'a self, buf: impl Into<IoVectorMut<'a>>, offset: u64, ) -> Result<()>

Read data at offset into buf.

Reads until buf is filled completely, i.e. will not do short reads. When reaching the end of file, the rest of buf is filled with 0.

Source

pub fn writev(&self, bufv: IoVector<'_>, offset: u64) -> Result<()>

Write data from bufv to offset.

Writes all data from bufv (or returns an error), i.e. will not do short writes. Reaching the end of file before the end of the buffer results in an error.

Source

pub fn write<'a>( &'a self, buf: impl Into<IoVector<'a>>, offset: u64, ) -> Result<()>

Write data from buf to offset.

Writes all data from bufv (or returns an error), i.e. will not do short writes. Reaching the end of file before the end of the buffer results in an error.

Source

pub fn write_zeroes(&self, offset: u64, length: u64) -> Result<()>

Ensure the given range reads as zeroes.

May use efficient zeroing for a subset of the given range, if supported by the format. Will not discard anything, which keeps existing data mappings usable, albeit writing to mappings that are now zeroed may have no effect.

Check if SyncFormatAccess::discard_to_zero() better suits your needs: It may work better on a wider range of formats (write_zeroes() requires support for preallocated zero clusters, which qcow2 does have, but other formats may not), and can actually free up space. However, because it can break existing data mappings, it requires a mutable self reference.

Source

pub fn discard_to_zero(&mut self, offset: u64, length: u64) -> Result<()>

Discard the given range, ensure it is read back as zeroes.

Effectively the same as SyncFormatAccess::write_zeroes(), but discard as much of the existing allocation as possible. This breaks existing data mappings, so needs a mutable reference to self, which ensures that existing data references (which have the lifetime of an immutable self reference) cannot be kept.

Areas that cannot be discarded (because of format-inherent alignment restrictions) are still overwritten with zeroes, unless discarding is not supported altogether.

Source

pub fn discard_to_any(&mut self, offset: u64, length: u64) -> Result<()>

Discard the given range, not guaranteeing specific data on read-back.

Discard as much of the given range as possible, and keep the rest as-is. Does not guarantee any specific data on read-back, in contrast to SyncFormatAccess::discard_to_zero().

Discarding being unsupported by this format is still returned as an error (std::io::ErrorKind::Unsupported)

Source

pub fn discard_to_backing(&mut self, offset: u64, length: u64) -> Result<()>

Discard the given range, such that the backing image becomes visible.

Discard as much of the given range as possible so that a backing image’s data becomes visible, and keep the rest as-is. This breaks existing data mappings, so needs a mutable reference to self, which ensures that existing data references (which have the lifetime of an immutable self reference) cannot be kept.

Source

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

Flush internal buffers.

Does not necessarily sync those buffers to disk. When using flush(), consider whether you want to call sync() afterwards.

Note that this will not drop the buffers, so they may still be used to serve later accesses. Use SyncFormatAccess::invalidate_cache() to drop all buffers.

Source

pub fn sync(&self) -> Result<()>

Sync data already written to the storage hardware.

This does not necessarily include flushing internal buffers, i.e. flush. When using sync(), consider whether you want to call flush() before it.

Source

pub unsafe fn invalidate_cache(&self) -> Result<()>

Drop internal buffers.

This drops all internal buffers, but does not flush them! All cached data is reloaded from disk on subsequent accesses.

§Safety

Not flushing internal buffers may cause image corruption. You must ensure the on-disk state is consistent.

Source

pub fn resize( &mut self, new_size: u64, prealloc_mode: PreallocateMode, ) -> Result<()>

Resize to the given size.

Set the disk size to new_size. If new_size is smaller than the current size, ignore both preallocation modes and discard the data after new_size.

If new_size is larger than the current size, prealloc_mode determines whether and how the new range should be allocated; depending on the image format, is possible some preallocation modes are not supported, in which case an std::io::ErrorKind::Unsupported is returned.

This may break existing data mappings, so needs a mutable reference to self, which ensures that existing data references (which have the lifetime of an immutable self reference) cannot be kept.

See also SyncFormatAccess::resize_grow() and SyncFormatAccess::resize_shrink(), whose more specialized interface may be useful when you know whether you want to grow or shrink the image.

Source

pub fn resize_grow( &self, new_size: u64, prealloc_mode: PreallocateMode, ) -> Result<()>

Resize to the given size, which must be greater than the current size.

Set the disk size to new_size, preallocating the new space according to prealloc_mode. Depending on the image format, it is possible some preallocation modes are not supported, in which case an std::io::ErrorKind::Unsupported is returned.

Source

pub fn resize_shrink(&mut self, new_size: u64) -> Result<()>

Truncate to the given size, which must be smaller than the current size.

Set the disk size to new_size, discarding the data after new_size.

May break existing data mappings thanks to the mutable self reference.

Trait Implementations§

Source§

impl<S: Storage> Drop for SyncFormatAccess<S>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<S: Storage> TryFrom<FormatAccess<S>> for SyncFormatAccess<S>

Source§

type Error = Error

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

fn try_from(async_access: FormatAccess<S>) -> Result<Self>

Performs the conversion.

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.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more