pub trait DiskIo:
'static
+ Send
+ Sync
+ Inspect {
Show 16 methods
// Required methods
fn disk_type(&self) -> &str;
fn sector_count(&self) -> u64;
fn sector_size(&self) -> u32;
fn disk_id(&self) -> Option<[u8; 16]>;
fn physical_sector_size(&self) -> u32;
fn is_fua_respected(&self) -> bool;
fn is_read_only(&self) -> bool;
fn unmap(
&self,
sector: u64,
count: u64,
block_level_only: bool,
) -> impl Future<Output = Result<(), DiskError>> + Send;
fn unmap_behavior(&self) -> UnmapBehavior;
fn read_vectored(
&self,
buffers: &RequestBuffers<'_>,
sector: u64,
) -> impl Future<Output = Result<(), DiskError>> + Send;
fn write_vectored(
&self,
buffers: &RequestBuffers<'_>,
sector: u64,
fua: bool,
) -> impl Future<Output = Result<(), DiskError>> + Send;
fn sync_cache(&self) -> impl Future<Output = Result<(), DiskError>> + Send;
// Provided methods
fn optimal_unmap_sectors(&self) -> u32 { ... }
fn pr(&self) -> Option<&dyn PersistentReservation> { ... }
fn eject(&self) -> impl Future<Output = Result<(), DiskError>> + Send { ... }
fn wait_resize(&self, sector_count: u64) -> impl Future<Output = u64> + Send { ... }
}Expand description
Disk metadata and IO operations.
§Sector range validation
Sector numbers reaching a backend originate with the guest, so
implementations must not panic for any sector value, and must return
DiskError::IllegalBlock for requests that fall outside the disk.
Callers are not required to validate the range beforehand — they cannot
do so meaningfully, since DiskIo::sector_count may change at runtime,
so a range checked by a caller can be invalidated before the request is
issued. Only the backend can validate against its own state.
An implementation may delegate this to whatever it is layered on top of,
but only if the backing object’s bounds coincide exactly with the disk’s,
out-of-range operations fail rather than silently succeeding, and the
resulting error is mapped to DiskError::IllegalBlock.
In exchange, implementations may rely on one guarantee from Disk: the
end byte offset of any request — that is, (sector + count) * sector_size
— is representable and no greater than i64::MAX. Sector arithmetic
therefore cannot overflow, and a backend that transforms the offset (adding
a header size, a chunk base, and so on) has 2^63 bytes of headroom in which
to do so. Note that this says nothing about how large the disk is, so it is
not a substitute for the range check above.
Required Methods§
Sourcefn disk_type(&self) -> &str
fn disk_type(&self) -> &str
Returns the disk type name as a string.
This is used for diagnostic purposes.
Sourcefn sector_count(&self) -> u64
fn sector_count(&self) -> u64
Returns the current sector count.
For some backing stores, this may change at runtime. If it does, then
the backing store must also implement DiskIo::wait_resize.
Sourcefn sector_size(&self) -> u32
fn sector_size(&self) -> u32
Returns the logical sector size of the backing store.
This must not change at runtime.
Sourcefn disk_id(&self) -> Option<[u8; 16]>
fn disk_id(&self) -> Option<[u8; 16]>
Optionally returns a 16-byte identifier for the disk, if there is a natural one for this backing store.
This may be exposed to the guest as a unique disk identifier. This must not change at runtime.
Sourcefn physical_sector_size(&self) -> u32
fn physical_sector_size(&self) -> u32
Returns the physical sector size of the backing store.
This must not change at runtime.
Sourcefn is_fua_respected(&self) -> bool
fn is_fua_respected(&self) -> bool
Returns true if the fua parameter to DiskIo::write_vectored is
respected by the backing store by ensuring that the IO is immediately
committed to disk.
Sourcefn is_read_only(&self) -> bool
fn is_read_only(&self) -> bool
Returns true if the disk is read only.
Sourcefn unmap(
&self,
sector: u64,
count: u64,
block_level_only: bool,
) -> impl Future<Output = Result<(), DiskError>> + Send
fn unmap( &self, sector: u64, count: u64, block_level_only: bool, ) -> impl Future<Output = Result<(), DiskError>> + Send
Unmap sectors from the layer.
See the trait documentation for the requirements on out-of-range requests.
Sourcefn unmap_behavior(&self) -> UnmapBehavior
fn unmap_behavior(&self) -> UnmapBehavior
Returns the behavior of the unmap operation.
This tells callers what happens to the content of unmapped sectors:
UnmapBehavior::Zeroes— unmapped sectors read back as zero.UnmapBehavior::Unspecified— content may or may not change, and not necessarily to zero.UnmapBehavior::Ignored— unmap is a no-op; content is unchanged.
Sourcefn read_vectored(
&self,
buffers: &RequestBuffers<'_>,
sector: u64,
) -> impl Future<Output = Result<(), DiskError>> + Send
fn read_vectored( &self, buffers: &RequestBuffers<'_>, sector: u64, ) -> impl Future<Output = Result<(), DiskError>> + Send
Issues an asynchronous read-scatter operation to the disk.
§Arguments
buffers- An object representing the data buffers into which the disk data will be transferred.sector- The logical sector at which the read operation starts.
Sourcefn write_vectored(
&self,
buffers: &RequestBuffers<'_>,
sector: u64,
fua: bool,
) -> impl Future<Output = Result<(), DiskError>> + Send
fn write_vectored( &self, buffers: &RequestBuffers<'_>, sector: u64, fua: bool, ) -> impl Future<Output = Result<(), DiskError>> + Send
Issues an asynchronous write-gather operation to the disk.
§Arguments
buffers- An object representing the data buffers containing the data to transfer to the disk.sector- The logical sector at which the write operation starts.fua- A flag indicates if FUA (force unit access) is requested.
Provided Methods§
Sourcefn optimal_unmap_sectors(&self) -> u32
fn optimal_unmap_sectors(&self) -> u32
Returns the optimal granularity for unmaps, in sectors.
Sourcefn pr(&self) -> Option<&dyn PersistentReservation>
fn pr(&self) -> Option<&dyn PersistentReservation>
Optionally returns a trait object to issue persistent reservation requests.
Sourcefn eject(&self) -> impl Future<Output = Result<(), DiskError>> + Send
fn eject(&self) -> impl Future<Output = Result<(), DiskError>> + Send
Issues an asynchronous eject media operation to the disk.
The default implementation returns DiskError::UnsupportedEject.
Eject is primarily a media state change managed by the SCSI DVD layer
(SimpleScsiDvd), not by disk backends. Backends generally do not
need to override this.
Sourcefn wait_resize(&self, sector_count: u64) -> impl Future<Output = u64> + Send
fn wait_resize(&self, sector_count: u64) -> impl Future<Output = u64> + Send
Waits for the disk sector count to change from the specified value.
Returns the new sector count once DiskIo::sector_count would return
a value different from sector_count. Frontends use this to detect
runtime capacity changes and notify the guest (NVMe via AEN, SCSI via
UNIT_ATTENTION).
The default implementation returns std::future::pending(), meaning
the disk never signals a resize. Only backends that can detect runtime
capacity changes should override this — for example, BlockDeviceDisk
(via Linux uevent) and NvmeDisk (via NVMe AEN). Decorator wrappers
and LayeredDisk should delegate to the inner disk.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.