pub struct Qcow2<S: Storage + 'static, F: WrappedFormat<S> + 'static = FormatAccess<S>> {
metadata: Arc<S>,
writable: bool,
storage_set: bool,
storage: Option<S>,
backing_set: bool,
backing: Option<F>,
storage_open_options: StorageOpenOptions,
header: Arc<Header>,
l1_table: RwLock<L1Table>,
l2_cache: AsyncLruCache<HostCluster, L2Table, L2CacheBackend<S>>,
allocator: Option<Mutex<Allocator<S>>>,
}
Expand description
Access qcow2 images.
Allows access to qcow2 images (v2 and v3), referencing the following objects:
- Metadata storage object: The image file itself
- Data file (storage object): May be the image file itself, or an external data file
- Backing image
WrappedFormat<S>
: A backing disk image in any format
Fields§
§metadata: Arc<S>
Image file (which contains the qcow2 metadata).
writable: bool
Whether this image may be modified.
storage_set: bool
Whether the user explicitly assigned a data file storage object (or None
).
storage: Option<S>
Data file storage object; will use metadata
if None
.
backing_set: bool
Whether the user explicitly assigned a backing file (or None
).
backing: Option<F>
Backing image.
storage_open_options: StorageOpenOptions
Base options to be used for implicitly opened storage objects.
header: Arc<Header>
Qcow2 header.
l1_table: RwLock<L1Table>
L1 table.
l2_cache: AsyncLruCache<HostCluster, L2Table, L2CacheBackend<S>>
L2 table cache.
allocator: Option<Mutex<Allocator<S>>>
Allocates clusters.
Is None
for read-only images.
Implementations§
Source§impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
Sourceasync fn allocator(&self) -> Result<MutexGuard<'_, Allocator<S>>>
async fn allocator(&self) -> Result<MutexGuard<'_, Allocator<S>>>
Return the central allocator instance.
Returns an error for read-only images.
Sourcepub(super) async fn allocate_meta_cluster(&self) -> Result<HostCluster>
pub(super) async fn allocate_meta_cluster(&self) -> Result<HostCluster>
Allocate one metadata cluster.
Metadata clusters are allocated exclusively in the metadata (image) file.
Sourcepub(super) async fn allocate_meta_clusters(
&self,
count: ClusterCount,
) -> Result<HostCluster>
pub(super) async fn allocate_meta_clusters( &self, count: ClusterCount, ) -> Result<HostCluster>
Allocate multiple continuous metadata clusters.
Useful e.g. for the L1 table or refcount table.
Sourcepub(super) async fn allocate_data_cluster(
&self,
guest_cluster: GuestCluster,
) -> Result<HostCluster>
pub(super) async fn allocate_data_cluster( &self, guest_cluster: GuestCluster, ) -> Result<HostCluster>
Allocate one data clusters for the given guest cluster.
Without an external data file, data clusters are allocated in the image file, just like metadata clusters.
With an external data file, data clusters aren’t really allocated, but just put there at the same offset as their guest offset. Their refcount is not tracked by the qcow2 metadata structures (which only cover the metadata (image) file).
Sourcepub(super) async fn allocate_data_cluster_at(
&self,
guest_cluster: GuestCluster,
mandatory_host_cluster: Option<HostCluster>,
) -> Result<Option<HostCluster>>
pub(super) async fn allocate_data_cluster_at( &self, guest_cluster: GuestCluster, mandatory_host_cluster: Option<HostCluster>, ) -> Result<Option<HostCluster>>
Allocate the data cluster with the given index.
Without a mandatory_host_cluster
given, this is the same as
Qcow2::allocate_data_cluster()
.
With a mandatory_host_cluster
given, try to allocate that cluster. If that is not
possible because it is already allocated, return Ok(None)
.
Sourcepub(super) async fn free_meta_clusters(
&self,
cluster: HostCluster,
count: ClusterCount,
)
pub(super) async fn free_meta_clusters( &self, cluster: HostCluster, count: ClusterCount, )
Free metadata clusters (i.e. decrement their refcount).
Best-effort operation. On error, the given clusters may be leaked, but no errors are ever returned (because there is no good way to handle such errors anyway).
Sourcepub(super) async fn free_data_clusters(
&self,
cluster: HostCluster,
count: ClusterCount,
)
pub(super) async fn free_data_clusters( &self, cluster: HostCluster, count: ClusterCount, )
Free data clusters (i.e. decrement their refcount).
Best-effort operation. On error, the given clusters may be leaked, but no errors are ever returned (because there is no good way to handle such errors anyway).
Source§impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
Sourcepub(super) async fn read_compressed_cluster(
&self,
buf: &mut [u8],
compressed_offset: HostOffset,
compressed_length: u64,
) -> Result<()>
pub(super) async fn read_compressed_cluster( &self, buf: &mut [u8], compressed_offset: HostOffset, compressed_length: u64, ) -> Result<()>
Read one compressed cluster.
Read the compressed data at compressed_offset
of length compressed_length
(which must
be the values from the L2 compressed cluster descriptor) into a bounce buffer, then
decompress it into buf
(which must have a length of exactly one cluster).
Source§impl<S: Storage, F: WrappedFormat<S>> Qcow2<S, F>
impl<S: Storage, F: WrappedFormat<S>> Qcow2<S, F>
Sourcepub(super) async fn cow_cluster(
&self,
cluster: GuestCluster,
mandatory_host_cluster: Option<HostCluster>,
partial_skip_cow: Option<Range<usize>>,
l2_table: &mut L2TableWriteGuard<'_>,
leaked_allocations: &mut Vec<(HostCluster, ClusterCount)>,
) -> Result<Option<HostCluster>>
pub(super) async fn cow_cluster( &self, cluster: GuestCluster, mandatory_host_cluster: Option<HostCluster>, partial_skip_cow: Option<Range<usize>>, l2_table: &mut L2TableWriteGuard<'_>, leaked_allocations: &mut Vec<(HostCluster, ClusterCount)>, ) -> Result<Option<HostCluster>>
Do copy-on-write for the given guest cluster, if necessary.
If the given guest cluster is backed by an allocated copied data cluster, return that cluster, so it can just be written into.
Otherwise, allocate a new data cluster and copy the previously visible cluster contents there:
- For non-copied data clusters, copy the cluster contents.
- For zero clusters, write zeroes.
- For unallocated clusters, copy data from the backing file (if any, zeroes otherwise).
- For compressed clusters, decompress the data and write it into the new cluster.
Return the new cluster, if any was allocated, or the old cluster in case it was already
safe to write to. I.e., the returned cluster is where data for cluster
may be written
to.
cluster
is the guest cluster to COW.
mandatory_host_cluster
may specify the cluster that must be used for the new allocation,
or that an existing data cluster allocation must match. If it does not match, or that
cluster is already allocated and cannot be used, return Ok(None)
.
partial_skip_cow
may give an in-cluster range that is supposed to be overwritten
immediately anyway, i.e. that need not be copied.
l2_table
is the L2 table for offset
.
If a previously existing allocation is replaced, the old one will be put into
leaked_allocations
. The caller must free it.
Sourcefn get_cow_range(
&self,
partial_skip_cow: Option<Range<usize>>,
alignment: usize,
) -> Option<Range<usize>>
fn get_cow_range( &self, partial_skip_cow: Option<Range<usize>>, alignment: usize, ) -> Option<Range<usize>>
Calculate what range of a cluster we need to COW.
Given potentially a range to skip, calculate what we should COW. The range will only be taken into account if it is at one end of the cluster, to always yield a continuous range to COW (one without a hole in the middle).
The returned range is also aligned to alignment
if possible.
Sourceasync fn cow_copy_storage(
&self,
from: &S,
from_cluster: HostCluster,
to_cluster: HostCluster,
partial_skip_cow: Option<Range<usize>>,
) -> Result<()>
async fn cow_copy_storage( &self, from: &S, from_cluster: HostCluster, to_cluster: HostCluster, partial_skip_cow: Option<Range<usize>>, ) -> Result<()>
Copy data from one data file cluster to another.
Used for COW on non-copied data clusters.
Sourceasync fn cow_copy_format(
&self,
from: &F,
from_offset: u64,
to_cluster: HostCluster,
partial_skip_cow: Option<Range<usize>>,
) -> Result<()>
async fn cow_copy_format( &self, from: &F, from_offset: u64, to_cluster: HostCluster, partial_skip_cow: Option<Range<usize>>, ) -> Result<()>
Copy data from another image into our data file.
Used for COW on clusters served by a backing image.
Sourceasync fn cow_zero(
&self,
to_cluster: HostCluster,
partial_skip_cow: Option<Range<usize>>,
) -> Result<()>
async fn cow_zero( &self, to_cluster: HostCluster, partial_skip_cow: Option<Range<usize>>, ) -> Result<()>
Fill the given cluster with zeroes.
Used for COW on zero clusters.
Sourceasync fn cow_compressed(
&self,
compressed_offset: HostOffset,
compressed_length: u64,
to_cluster: HostCluster,
) -> Result<()>
async fn cow_compressed( &self, compressed_offset: HostOffset, compressed_length: u64, to_cluster: HostCluster, ) -> Result<()>
Decompress a cluster into the target cluster.
Used for COW on compressed clusters.
Source§impl<S: Storage, F: WrappedFormat<S>> Qcow2<S, F>
impl<S: Storage, F: WrappedFormat<S>> Qcow2<S, F>
Sourcepub(super) async fn do_readv_special(
&self,
bufv: IoVectorMut<'_>,
offset: GuestOffset,
) -> Result<()>
pub(super) async fn do_readv_special( &self, bufv: IoVectorMut<'_>, offset: GuestOffset, ) -> Result<()>
Read the special range at offset
.
Currently, the only special range we have are compressed clusters.
Source§impl<S: Storage, F: WrappedFormat<S>> Qcow2<S, F>
impl<S: Storage, F: WrappedFormat<S>> Qcow2<S, F>
Sourcepub(super) async fn do_get_mapping(
&self,
offset: GuestOffset,
max_length: u64,
) -> Result<(ShallowMapping<'_, S>, u64)>
pub(super) async fn do_get_mapping( &self, offset: GuestOffset, max_length: u64, ) -> Result<(ShallowMapping<'_, S>, u64)>
Get the given range’s mapping information.
Underlying implementation for Qcow2::get_mapping()
.
Sourcepub(super) async fn do_get_mapping_with_l2(
&self,
offset: GuestOffset,
max_length: u64,
l2_table: &L2Table,
) -> Result<(ShallowMapping<'_, S>, u64)>
pub(super) async fn do_get_mapping_with_l2( &self, offset: GuestOffset, max_length: u64, l2_table: &L2Table, ) -> Result<(ShallowMapping<'_, S>, u64)>
Get the given range’s mapping information, when we already have the L2 table.
Sourcepub(super) async fn do_ensure_data_mapping(
&self,
offset: GuestOffset,
length: u64,
overwrite: bool,
) -> Result<(&S, u64, u64)>
pub(super) async fn do_ensure_data_mapping( &self, offset: GuestOffset, length: u64, overwrite: bool, ) -> Result<(&S, u64, u64)>
Make the given range be mapped by data clusters.
Underlying implementation for Qcow2::ensure_data_mapping()
.
Sourcepub(super) async fn ensure_fixed_mapping(
&self,
offset: GuestOffset,
length: u64,
mapping: FixedMapping,
) -> Result<(GuestOffset, u64)>
pub(super) async fn ensure_fixed_mapping( &self, offset: GuestOffset, length: u64, mapping: FixedMapping, ) -> Result<(GuestOffset, u64)>
Make the given range be mapped by a fixed kind of clusters.
Allows zeroing or discarding clusters. mapping
says which kind of mapping to create.
Return the offset of the first affected cluster, and the byte length affected (may be 0).
Sourcepub(super) async fn get_l2(
&self,
offset: GuestOffset,
writable: bool,
) -> Result<Option<Arc<L2Table>>>
pub(super) async fn get_l2( &self, offset: GuestOffset, writable: bool, ) -> Result<Option<Arc<L2Table>>>
Get the L2 table referenced by the given L1 table index, if any.
writable
says whether the L2 table should be modifiable.
If the L1 table index does not point to any L2 table, or the existing entry is not
modifiable but writable
is true, return Ok(None)
.
Sourcepub(super) async fn ensure_l2(
&self,
offset: GuestOffset,
) -> Result<Arc<L2Table>>
pub(super) async fn ensure_l2( &self, offset: GuestOffset, ) -> Result<Arc<L2Table>>
Get a L2 table for the given L1 table index.
If there already is an L2 table at that index, return it. Otherwise, create one and hook it up.
Sourcepub(super) async fn grow_l1_table<'a>(
&self,
l1_locked: RwLockWriteGuard<'a, L1Table>,
at_least_index: usize,
) -> Result<RwLockWriteGuard<'a, L1Table>>
pub(super) async fn grow_l1_table<'a>( &self, l1_locked: RwLockWriteGuard<'a, L1Table>, at_least_index: usize, ) -> Result<RwLockWriteGuard<'a, L1Table>>
Create a new L1 table covering at least at_least_index
.
Create a new L1 table of the required size with all the entries of the previous L1 table.
Sourceasync fn ensure_data_mapping_no_cleanup(
&self,
offset: GuestOffset,
full_length: u64,
overwrite: bool,
l2_table: L2TableWriteGuard<'_>,
leaked_allocations: &mut Vec<(HostCluster, ClusterCount)>,
) -> Result<(u64, u64)>
async fn ensure_data_mapping_no_cleanup( &self, offset: GuestOffset, full_length: u64, overwrite: bool, l2_table: L2TableWriteGuard<'_>, leaked_allocations: &mut Vec<(HostCluster, ClusterCount)>, ) -> Result<(u64, u64)>
Inner implementation for Qcow2::do_ensure_data_mapping()
.
Does not do any clean-up: The L2 table will probably be modified, but not written to disk.
Any existing allocations that have been removed from it (and are thus leaked) are entered
into leaked_allocations
, but not freed.
The caller must do both, ensuring it is done both in case of success and in case of error.
Sourceasync fn ensure_fixed_mapping_no_cleanup(
&self,
first_cluster: GuestCluster,
count: ClusterCount,
mapping: FixedMapping,
l2_table: L2TableWriteGuard<'_>,
leaked_allocations: &mut Vec<(HostCluster, ClusterCount)>,
) -> Result<ClusterCount>
async fn ensure_fixed_mapping_no_cleanup( &self, first_cluster: GuestCluster, count: ClusterCount, mapping: FixedMapping, l2_table: L2TableWriteGuard<'_>, leaked_allocations: &mut Vec<(HostCluster, ClusterCount)>, ) -> Result<ClusterCount>
Inner implementation for Qcow2::ensure_fixed_mapping()
.
Does not do any clean-up: The L2 table will probably be modified, but not written to disk.
Any existing allocations that have been removed from it (and are thus leaked) are entered
into leaked_allocations
, but not freed.
The caller must do both, ensuring it is done both in case of success and in case of error.
Allows zeroing or discarding clusters. mapping
says which kind of mapping to create.
Source§impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
Sourcepub(super) async fn preallocate_zero(
&self,
offset: u64,
length: u64,
) -> Result<()>
pub(super) async fn preallocate_zero( &self, offset: u64, length: u64, ) -> Result<()>
Make the given range zero.
Sourcepub(super) async fn preallocate(
&self,
offset: u64,
length: u64,
storage_prealloc_mode: PreallocateMode,
) -> Result<()>
pub(super) async fn preallocate( &self, offset: u64, length: u64, storage_prealloc_mode: PreallocateMode, ) -> Result<()>
Preallocate the given range as data clusters.
Does not write data beyond trying to ensure storage_prealloc_mode
for the underlying
clusters.
Source§impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
Sourcepub fn open_image_sync(metadata: S, writable: bool) -> Result<Self>
pub fn open_image_sync(metadata: S, writable: bool) -> Result<Self>
Synchronous wrapper around Qcow2::open_image()
.
Runs the async function in an ephemeral tokio runtime.
Sourcepub fn open_path_sync<P: AsRef<Path>>(path: P, writable: bool) -> Result<Self>
pub fn open_path_sync<P: AsRef<Path>>(path: P, writable: bool) -> Result<Self>
Synchronous wrapper around Qcow2::open_path()
.
Runs the async function in an ephemeral tokio runtime.
Sourcepub fn open_implicit_dependencies_sync(&mut self) -> Result<()>
pub fn open_implicit_dependencies_sync(&mut self) -> Result<()>
Synchronous wrapper around Qcow2::open_implicit_dependencies()
.
Runs the async function in an ephemeral tokio runtime.
Source§impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
impl<S: Storage + 'static, F: WrappedFormat<S> + 'static> Qcow2<S, F>
Sourcepub fn builder(image: S) -> Qcow2OpenBuilder<S, F>
pub fn builder(image: S) -> Qcow2OpenBuilder<S, F>
Create a new FormatDriverBuilder
instance for the given image.
Sourcepub fn builder_path<P: AsRef<Path>>(image_path: P) -> Qcow2OpenBuilder<S, F>
pub fn builder_path<P: AsRef<Path>>(image_path: P) -> Qcow2OpenBuilder<S, F>
Create a new FormatDriverBuilder
instance for an image under the given path.
Sourcepub fn create_builder(image: S) -> Qcow2CreateBuilder<S, F>
pub fn create_builder(image: S) -> Qcow2CreateBuilder<S, F>
Create a new FormatCreateBuilder
instance to format the given file.
Sourceasync fn do_open(
metadata: S,
writable: bool,
storage_open_options: StorageOpenOptions,
) -> Result<Self>
async fn do_open( metadata: S, writable: bool, storage_open_options: StorageOpenOptions, ) -> Result<Self>
Internal implementation for opening a qcow2 image.
Does not open external dependencies.
Sourcepub async fn open_image(metadata: S, writable: bool) -> Result<Self>
pub async fn open_image(metadata: S, writable: bool) -> Result<Self>
Opens a qcow2 file.
metadata
is the file containing the qcow2 metadata. If writable
is not set, no
modifications are permitted.
This will not open any other storage objects needed, i.e. no backing image, no external
data file. If you want to handle those manually, check whether an external data file is
needed via Qcow2::requires_external_data_file()
, and, if necessary, assign one via
Qcow2::set_data_file()
; and assign a backing image via Qcow2::set_backing()
.
If you want to use the implicit references given in the image header, use
Qcow2::open_implicit_dependencies()
.
Sourcepub async fn open_path<P: AsRef<Path>>(path: P, writable: bool) -> Result<Self>
pub async fn open_path<P: AsRef<Path>>(path: P, writable: bool) -> Result<Self>
Open a qcow2 file at the given path.
Open the file as a storage object via Storage::open()
, with write access if specified,
then pass that object to Qcow2::open_image()
.
This will not open any other storage objects needed, i.e. no backing image, no external
data file. If you want to handle those manually, check whether an external data file is
needed via Qcow2::requires_external_data_file()
, and, if necessary, assign one via
Qcow2::set_data_file()
; and assign a backing image via Qcow2::set_backing()
.
If you want to use the implicit references given in the image header, use
Qcow2::open_implicit_dependencies()
.
Sourcepub fn requires_external_data_file(&self) -> bool
pub fn requires_external_data_file(&self) -> bool
Does this qcow2 image require an external data file?
Conversely, if this is false
, this image must not use an external data file.
Sourcepub fn implicit_external_data_file(&self) -> Option<&String>
pub fn implicit_external_data_file(&self) -> Option<&String>
External data file filename given in the image header.
Note that even if an image requires an external data file, the header may not contain its
filename. In this case, an external data file must be set explicitly via
Qcow2::set_data_file()
.
Sourcepub fn implicit_backing_file(&self) -> Option<&String>
pub fn implicit_backing_file(&self) -> Option<&String>
Backing image filename given in the image header.
Sourcepub fn implicit_backing_format(&self) -> Option<&String>
pub fn implicit_backing_format(&self) -> Option<&String>
Backing image format given in the image header.
If this is None
, the backing image’s format should be probed. Note that this may be
dangerous if guests have write access to the backing file: Given a raw image, a guest can
write a qcow2 header into it, resulting in the image being opened as qcow2 the next time,
allowing the guest to read arbitrary files (e.g. by setting them as backing files).
Sourcepub fn set_data_file(&mut self, file: Option<S>)
pub fn set_data_file(&mut self, file: Option<S>)
Assign the data file.
None
means using the same data storage for both metadata and data, which should be used
if Qcow2::requires_external_data_file()
is false
.
Sourcepub fn set_backing(&mut self, backing: Option<F>)
pub fn set_backing(&mut self, backing: Option<F>)
Assign a backing image.
None
means no backing image, i.e. reading from unallocated areas will produce zeroes.
Sourcefn storage(&self) -> &S
fn storage(&self) -> &S
Get the data storage object.
If we have an external data file, return that. Otherwise, return the image (metadata) file.
Sourceasync fn open_implicit_data_file<G: ImplicitOpenGate<S>>(
&self,
gate: &mut G,
) -> Result<Option<S>>
async fn open_implicit_data_file<G: ImplicitOpenGate<S>>( &self, gate: &mut G, ) -> Result<Option<S>>
Return the image’s implicit data file (as given in the image header).
Sourceasync fn open_raw_backing_file<G: ImplicitOpenGate<S>>(
&self,
file: S,
gate: &mut G,
) -> Result<F>
async fn open_raw_backing_file<G: ImplicitOpenGate<S>>( &self, file: S, gate: &mut G, ) -> Result<F>
Wrap file
in the Raw
format. Helper for Qcow2::implicit_backing_file()
.
Sourceasync fn open_qcow2_backing_file<G: ImplicitOpenGate<S>>(
&self,
file: S,
gate: &mut G,
) -> Result<F>
async fn open_qcow2_backing_file<G: ImplicitOpenGate<S>>( &self, file: S, gate: &mut G, ) -> Result<F>
Wrap file
in the Qcow2
format. Helper for Qcow2::implicit_backing_file()
.
Sourceasync fn open_implicit_backing_file<G: ImplicitOpenGate<S>>(
&self,
gate: &mut G,
) -> Result<Option<F>>
async fn open_implicit_backing_file<G: ImplicitOpenGate<S>>( &self, gate: &mut G, ) -> Result<Option<F>>
Return the image’s implicit backing image (as given in the image header).
Anything opened will be passed through gate
.
Sourcepub async fn open_implicit_dependencies_gated<G: ImplicitOpenGate<S>>(
&mut self,
gate: G,
) -> Result<()>
pub async fn open_implicit_dependencies_gated<G: ImplicitOpenGate<S>>( &mut self, gate: G, ) -> Result<()>
Open all implicit dependencies.
Qcow2 images have dependencies:
- The metadata file, which is the image file itself.
- The data file, which may be the same as the metadata file, or may be an external data file.
- A backing disk image in any format.
All of this can be set explicitly:
- The metadata file is always given explicitly to
Qcow2::open_image()
. - The data file can be set via
Qcow2::set_data_file()
. - The backing image can be set via
Qcow2::set_backing()
.
But the image header can also provide “default” references to the data file and a backing
image, which we call implicit dependencies. This function opens all such implicit
dependencies if they have not been overridden with prior calls to
Qcow2::set_data_file()
or Qcow2::set_backing()
, respectively.
Any image or file is opened through gate
.
Sourcepub async fn open_implicit_dependencies(&mut self) -> Result<()>
pub async fn open_implicit_dependencies(&mut self) -> Result<()>
Open all implicit dependencies, ungated.
Same as Qcow2::open_implicit_dependencies_gated
, but does not perform any gating on
implicitly opened images/files.
See the cautionary notes on PermissiveImplicitOpenGate
on
FormatDriverInstance::probe()
on why this may be dangerous.
Sourcefn need_writable(&self) -> Result<()>
fn need_writable(&self) -> Result<()>
Require write access, i.e. return an error for read-only images.
Trait Implementations§
Source§impl<S: Storage, F: WrappedFormat<S>> FormatDriverInstance for Qcow2<S, F>
impl<S: Storage, F: WrappedFormat<S>> FormatDriverInstance for Qcow2<S, F>
Source§unsafe fn probe<'life0, 'async_trait>(
metadata: &'life0 S,
) -> Pin<Box<dyn Future<Output = Result<bool>> + 'async_trait>>where
Self: Sized + 'async_trait,
'life0: 'async_trait,
unsafe fn probe<'life0, 'async_trait>(
metadata: &'life0 S,
) -> Pin<Box<dyn Future<Output = Result<bool>> + 'async_trait>>where
Self: Sized + 'async_trait,
'life0: 'async_trait,
storage
has this format. Read moreSource§fn zero_granularity(&self) -> Option<u64>
fn zero_granularity(&self) -> Option<u64>
Source§fn collect_storage_dependencies(&self) -> Vec<&S>
fn collect_storage_dependencies(&self) -> Vec<&S>
Source§fn get_mapping<'a, 'async_trait>(
&'a self,
offset: u64,
max_length: u64,
) -> Pin<Box<dyn Future<Output = Result<(ShallowMapping<'a, S>, u64)>> + 'async_trait>>where
Self: 'async_trait,
'a: 'async_trait,
fn get_mapping<'a, 'async_trait>(
&'a self,
offset: u64,
max_length: u64,
) -> Pin<Box<dyn Future<Output = Result<(ShallowMapping<'a, S>, u64)>> + 'async_trait>>where
Self: 'async_trait,
'a: 'async_trait,
offset
. Read moreSource§fn ensure_data_mapping<'a, 'async_trait>(
&'a self,
offset: u64,
length: u64,
overwrite: bool,
) -> Pin<Box<dyn Future<Output = Result<(&'a S, u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'a: 'async_trait,
fn ensure_data_mapping<'a, 'async_trait>(
&'a self,
offset: u64,
length: u64,
overwrite: bool,
) -> Pin<Box<dyn Future<Output = Result<(&'a S, u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'a: 'async_trait,
Source§fn ensure_zero_mapping<'life0, 'async_trait>(
&'life0 self,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<(u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn ensure_zero_mapping<'life0, 'async_trait>(
&'life0 self,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<(u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn discard_to_zero<'life0, 'async_trait>(
&'life0 mut self,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<(u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn discard_to_zero<'life0, 'async_trait>(
&'life0 mut self,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<(u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn discard_to_any<'life0, 'async_trait>(
&'life0 mut self,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<(u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn discard_to_any<'life0, 'async_trait>(
&'life0 mut self,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<(u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn discard_to_backing<'life0, 'async_trait>(
&'life0 mut self,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<(u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn discard_to_backing<'life0, 'async_trait>(
&'life0 mut self,
offset: u64,
length: u64,
) -> Pin<Box<dyn Future<Output = Result<(u64, u64)>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn readv_special<'life0, 'life1, 'async_trait>(
&'life0 self,
bufv: IoVectorMut<'life1>,
offset: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn readv_special<'life0, 'life1, 'async_trait>(
&'life0 self,
bufv: IoVectorMut<'life1>,
offset: u64,
) -> Pin<Box<dyn Future<Output = Result<()>> + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
ShallowMapping::Special
area.