From 0854c3e082726edd156b65079c4c6c62f58bc352 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 26 Mar 2026 20:17:20 +0100 Subject: [PATCH] performance-metrics: Add empty QCOW2 tempfile helper Add empty_qcow_tempfile() which creates a QCOW2 v3 image with no allocated clusters so every write triggers the full cluster allocation path including L2 entry allocation and refcount updates. Signed-off-by: Anatol Belski --- performance-metrics/src/util.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/performance-metrics/src/util.rs b/performance-metrics/src/util.rs index ce480aa4f..345e62a41 100644 --- a/performance-metrics/src/util.rs +++ b/performance-metrics/src/util.rs @@ -98,6 +98,24 @@ pub fn submit_reads(async_io: &mut dyn AsyncIo, count: usize, stride: u64, iovec } } +/// Create an empty QCOW2 image sized for `num_clusters` clusters. +/// No data clusters are allocated. +fn create_empty_qcow_tempfile(num_clusters: usize) -> TempFile { + let tmp = TempFile::new().expect("failed to create tempfile"); + let virtual_size = QCOW_CLUSTER_SIZE * num_clusters as u64; + let raw = RawFile::new(tmp.as_file().try_clone().unwrap(), false); + QcowFile::new(raw, 3, virtual_size, true).expect("failed to create qcow2 file"); + tmp +} + +/// Empty QCOW2 opened via QcowDiskSync. +pub fn empty_qcow_tempfile(num_clusters: usize) -> (TempFile, QcowDiskSync) { + let tmp = create_empty_qcow_tempfile(num_clusters); + let disk = QcowDiskSync::new(tmp.as_file().try_clone().unwrap(), false, false, true) + .expect("failed to open qcow2 via QcowDiskSync"); + (tmp, disk) +} + /// Spin and wait until the given eventfd becomes readable. pub fn wait_for_eventfd(notifier: &EventFd) { loop {