From 9e2e85a48fc52092c02c7e15e6fdc6f1dc8df552 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 27 Nov 2025 09:43:17 +0100 Subject: [PATCH] block: qcow: Fix refcount leak when refcount blocks are replaced When a refcount block is evicted from cache and replaced with a new one, the old refcount block cluster was added to unref_clusters but its refcount was never decremented to 0 on disk. This left the cluster with refcount=1 while no metadata referenced it, causing errors in qemu-img check `Leaked cluster X refcount=1 reference=0` This fix recursively calls set_cluster_refcount(freed_cluster, 0) to properly decrement the freed refcount block's refcount on disk. The recursion handles cascading replacements where freeing one refcount block may trigger the replacement of another. Signed-off-by: Anatol Belski --- block/src/qcow/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/block/src/qcow/mod.rs b/block/src/qcow/mod.rs index 46a938418..400e30a82 100644 --- a/block/src/qcow/mod.rs +++ b/block/src/qcow/mod.rs @@ -1518,7 +1518,9 @@ impl QcowFile { refcount_set = true; } Ok(Some(freed_cluster)) => { - unref_clusters.push(freed_cluster); + // Recursively set the freed refcount block's refcount to 0 + let mut freed = self.set_cluster_refcount(freed_cluster, 0)?; + unref_clusters.append(&mut freed); refcount_set = true; } Err(refcount::Error::EvictingRefCounts(e)) => {