block: Add supports_zero_flag trait method
Add supports_zero_flag() to DiskFile trait to indicate whether a disk format can mark clusters/blocks as reading zeros without deallocating storage. QCOW2 supports this via the zero flag in L2 entries. VHDX also has PAYLOAD_BLOCK_ZERO state for this, though it's not yet implemented in cloud-hypervisor. This enables DISCARD to be advertised even with sparse=false for formats with zero-flag support, since they can mark regions as zeros (keeps storage allocated) instead of requiring full deallocation. Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
parent
7dfcbff309
commit
46e6ecddfe
3 changed files with 21 additions and 4 deletions
|
|
@ -84,6 +84,12 @@ pub trait DiskFile: Send {
|
|||
false
|
||||
}
|
||||
|
||||
/// Indicates support for zero flag optimization in WRITE_ZEROES. Override
|
||||
/// to return true when supported.
|
||||
fn supports_zero_flag(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns the file descriptor of the underlying disk image file.
|
||||
///
|
||||
/// The file descriptor is supposed to be used for `fcntl()` calls but no
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ impl DiskFile for QcowDiskSync {
|
|||
true
|
||||
}
|
||||
|
||||
fn supports_zero_flag(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn fd(&mut self) -> BorrowedDiskFd<'_> {
|
||||
BorrowedDiskFd::new(self.qcow_file.lock().unwrap().as_raw_fd())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -672,7 +672,7 @@ impl Block {
|
|||
exit_evt: EventFd,
|
||||
state: Option<BlockState>,
|
||||
queue_affinity: BTreeMap<u16, Vec<usize>>,
|
||||
_sparse: bool,
|
||||
sparse: bool,
|
||||
) -> io::Result<Self> {
|
||||
let (disk_nsectors, avail_features, acked_features, config, paused) =
|
||||
if let Some(state) = state {
|
||||
|
|
@ -704,10 +704,17 @@ impl Block {
|
|||
| (1u64 << VIRTIO_RING_F_EVENT_IDX)
|
||||
| (1u64 << VIRTIO_RING_F_INDIRECT_DESC);
|
||||
|
||||
// Only advertise discard/write zeroes if the backend supports sparse operations
|
||||
// When backend supports sparse operations:
|
||||
// - Always advertise WRITE_ZEROES
|
||||
// - Advertise DISCARD only if sparse=true OR format supports marking
|
||||
// clusters as zero without deallocating
|
||||
if disk_image.supports_sparse_operations() {
|
||||
avail_features |=
|
||||
(1u64 << VIRTIO_BLK_F_DISCARD) | (1u64 << VIRTIO_BLK_F_WRITE_ZEROES);
|
||||
avail_features |= 1u64 << VIRTIO_BLK_F_WRITE_ZEROES;
|
||||
if sparse || disk_image.supports_zero_flag() {
|
||||
avail_features |= 1u64 << VIRTIO_BLK_F_DISCARD;
|
||||
}
|
||||
} else if sparse {
|
||||
warn!("sparse=on requested but backend does not support sparse operations");
|
||||
}
|
||||
|
||||
if iommu {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue