mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
committed by
Rob Bradford
parent
7dfcbff309
commit
46e6ecddfe
@@ -84,6 +84,12 @@ pub trait DiskFile: Send {
|
|||||||
false
|
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.
|
/// Returns the file descriptor of the underlying disk image file.
|
||||||
///
|
///
|
||||||
/// The file descriptor is supposed to be used for `fcntl()` calls but no
|
/// The file descriptor is supposed to be used for `fcntl()` calls but no
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ impl DiskFile for QcowDiskSync {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supports_zero_flag(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn fd(&mut self) -> BorrowedDiskFd<'_> {
|
fn fd(&mut self) -> BorrowedDiskFd<'_> {
|
||||||
BorrowedDiskFd::new(self.qcow_file.lock().unwrap().as_raw_fd())
|
BorrowedDiskFd::new(self.qcow_file.lock().unwrap().as_raw_fd())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -672,7 +672,7 @@ impl Block {
|
|||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
state: Option<BlockState>,
|
state: Option<BlockState>,
|
||||||
queue_affinity: BTreeMap<u16, Vec<usize>>,
|
queue_affinity: BTreeMap<u16, Vec<usize>>,
|
||||||
_sparse: bool,
|
sparse: bool,
|
||||||
) -> io::Result<Self> {
|
) -> io::Result<Self> {
|
||||||
let (disk_nsectors, avail_features, acked_features, config, paused) =
|
let (disk_nsectors, avail_features, acked_features, config, paused) =
|
||||||
if let Some(state) = state {
|
if let Some(state) = state {
|
||||||
@@ -704,10 +704,17 @@ impl Block {
|
|||||||
| (1u64 << VIRTIO_RING_F_EVENT_IDX)
|
| (1u64 << VIRTIO_RING_F_EVENT_IDX)
|
||||||
| (1u64 << VIRTIO_RING_F_INDIRECT_DESC);
|
| (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() {
|
if disk_image.supports_sparse_operations() {
|
||||||
avail_features |=
|
avail_features |= 1u64 << VIRTIO_BLK_F_WRITE_ZEROES;
|
||||||
(1u64 << VIRTIO_BLK_F_DISCARD) | (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 {
|
if iommu {
|
||||||
|
|||||||
Reference in New Issue
Block a user