All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, richard.henderson@linaro.org, qemu-devel@nongnu.org
Subject: [PULL 09/11] qcow2: fix snapshot data corruption with discard-no-unref=on
Date: Mon,  9 Nov 2026 17:45:31 +0100	[thread overview]
Message-ID: <20261109164533.293487-10-kwolf@redhat.com> (raw)
In-Reply-To: <20261109164533.293487-1-kwolf@redhat.com>

From: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>

Whenever option discard-no-unref=on is enabled, we bypass refcount
machinery and unconditionally punch hole in the data on 'discard' and
'write -z -u' paths.  However, when this same cluster is also referenced
by an internal snapshot, such operations lead to problems.  The active L2
table is copied before it is changed, so the snapshot metadata stays
correct, but the host range under it is punched out and the snapshot reads
zeroes there afterwards. qemu-img check finds nothing wrong.

Fix this by guarding the 'keep_reference' flag by the presence of the
QCOW_OFLAG_COPIED bit.  I.e. only proceed with unconditional data
punching if we own this cluster exclusively.

Cc: qemu-stable@nongnu.org
Fixes: 42a2890a76f4 ("qcow2: add discard-no-unref option")
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20261105161515.794213-3-andrey.drobyshev@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-cluster.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index e02fae6a0c6..cc473c7c796 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1953,6 +1953,7 @@ discard_in_l2_slice(BlockDriverState *bs, uint64_t offset, uint64_t nb_clusters,
         QCow2ClusterType cluster_type =
             qcow2_get_cluster_type(bs, old_l2_entry);
         bool keep_reference = (cluster_type != QCOW2_CLUSTER_COMPRESSED) &&
+                              (old_l2_entry & QCOW_OFLAG_COPIED) &&
                               !full_discard &&
                               (s->discard_no_unref &&
                                type == QCOW2_DISCARD_REQUEST);
@@ -2097,8 +2098,9 @@ zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
         QCow2ClusterType type = qcow2_get_cluster_type(bs, old_l2_entry);
         bool unmap = (type == QCOW2_CLUSTER_COMPRESSED) ||
             ((flags & BDRV_REQ_MAY_UNMAP) && qcow2_cluster_is_allocated(type));
-        bool keep_reference =
-            (s->discard_no_unref && type != QCOW2_CLUSTER_COMPRESSED);
+        bool keep_reference = s->discard_no_unref &&
+                              type != QCOW2_CLUSTER_COMPRESSED &&
+                              (old_l2_entry & QCOW_OFLAG_COPIED);
         uint64_t new_l2_entry = old_l2_entry;
         uint64_t new_l2_bitmap = old_l2_bitmap;
 
-- 
2.56.0



  parent reply	other threads:[~2026-11-09 16:47 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
2026-11-09 16:45 ` [PULL 01/11] iotests: add --quiet arg to hide env variable dump Kevin Wolf
2026-11-09 16:45 ` [PULL 02/11] block/vmdk: Avoid assertion if image file has no extents Kevin Wolf
2026-11-09 16:45 ` [PULL 03/11] block/vmdk: Avoid reading off the end of descriptor memory Kevin Wolf
2026-11-09 16:45 ` [PULL 04/11] block/vmdk: Use larger types for byte counts in vmdk_read_extent() Kevin Wolf
2026-11-09 16:45 ` [PULL 05/11] block/vmdk: Reject a zero cluster_sectors parameter Kevin Wolf
2026-11-09 16:45 ` [PULL 06/11] block/vmdk: Avoid overflowing multiplication in vmdk_open_vmdk4() Kevin Wolf
2026-11-09 16:45 ` [PULL 07/11] block: add missing coroutine_fn annotations Kevin Wolf
2026-11-09 16:45 ` [PULL 08/11] iotests/290: add test case to check 'discard-no-unref' option behavior Kevin Wolf
2026-11-09 16:45 ` Kevin Wolf [this message]
2026-11-09 16:45 ` [PULL 10/11] iotests/290: add 'discard' and 'write -z -u' case with a snapshot Kevin Wolf
2026-11-09 16:45 ` [PULL 11/11] block/vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files Kevin Wolf
2026-11-09 20:53 ` [PULL 00/11] Block layer patches Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261109164533.293487-10-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.