From nobody Mon Sep 28 02:07:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1785535290; cv=none; d=zohomail.com; s=zohoarc; b=Pf5E+px4SdIOwNLfHZfV/tgTyuuvjJU/4/dclRcIfIQluaEz9rz4e+CdLUXbWQQtdRC8Coj2ekeVDiQIxQtAlsrC8WLRmTUySqN5CjvShHkIp4ndn6XnKkYK6QqLtOtj8ATgQJVJa/hVY+kau3c/rnEPKvnTk/483kKhS/aozwI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785535290; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=uSiA6NHPpgPJGQnSafEN4vWcEnf8GiGHd436OL4FkHs=; b=HlCXLjyFcWnJMUklQMfCZ9iFiab/sEaFVbdDVLnD6E3llcjg4gAfWne91HobgzGjxvnSiE7kDaGAYBwXG5E9KhzU7R7gcw4QjY2bB2jiOHH93erWPwaTpYcFPLLlRYl8tQ1nYvk3B7a/zZe8C3AqyCnZHS5TqSTMHdyOrO3Bi/U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785535290384171.46520966826836; Fri, 31 Jul 2026 15:01:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wpvHe-00065Q-Td; Fri, 31 Jul 2026 18:00:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wpvHb-00063c-Ed for qemu-devel@nongnu.org; Fri, 31 Jul 2026 18:00:47 -0400 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wpvHY-0007SQ-W9 for qemu-devel@nongnu.org; Fri, 31 Jul 2026 18:00:47 -0400 Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-47f3b39f2a1so904940f8f.2 for ; Fri, 31 Jul 2026 15:00:44 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:1758:fc6:a5f8:a15f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47fd41e2cf1sm9711152f8f.10.2026.07.31.15.00.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jul 2026 15:00:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1785535243; x=1786140043; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=uSiA6NHPpgPJGQnSafEN4vWcEnf8GiGHd436OL4FkHs=; b=N6f2YmUDfqrhQS1eOvmsIfKt+ne2dUPUemamY22gedF0hRgAd7bbKLjgeeJLBF8Vyd 8+OYYk7F+gEjOLM+Ee+wcUvucVz8zUYiR61v6iQwI+h8DUTLLbFl1HBBoZa0szgn31vp 3fN8zElFsTSd54h5DJ5GWVmOsiohbq4AqYT/oAPeCexhoFOvGYyRz8sM4cfrxmeaCloQ 6Nfa0/fhNoyzzBOLeJGwSxMSF5psqNQpmwtXHmZwoTjVoKh3MdcED4ZdCiqWBpFqzSLy 3DLOrQWe5kVBx/i9FEYb6IYgkf+WlE1oJvUmL1j6InKgnrcLxCqTQ79Kz61clVZXTI1Y F8CA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785535243; x=1786140043; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=uSiA6NHPpgPJGQnSafEN4vWcEnf8GiGHd436OL4FkHs=; b=ctttptrr/4r6z/n+vykCBW+MxAEb7Pf6R0ek1Z4pFNTmUb2TBJTL0bv7XuoRDvbbQ/ ckFuYY7PoF7z93JE+/Iys6lZfSuOOyozNjTykvrLrUluxLMNV4cPRsIjO/mjDLYsLHS/ 0hLtxlEDlwblY+ZezrYUwCUdJO0UUVix5CPVQ76Rrqvyvc/GEOb4cGRLSIqtXld+5fZd g2ezSa8wl718Q36BXjfPKlXah/cfsN9joYf2OizsftgySVsYQk96e+y88mEUp4pwijDV b5RHXeSVqnKj+RGW9VKvx3djx0yWL+/9oWVcSPawtIe8kTIli4r0HRlwVjTgqz8KUOpO BwBQ== X-Forwarded-Encrypted: i=1; AHgh+RpxUfx6YrkfHa/ztWYS6ie2S3b0DbP6Z952fPeHZ2uX89ApUpG1GJWsaj9PVguDcuYz3wHFYLUX1qgD@nongnu.org X-Gm-Message-State: AOJu0YzG1pcfEGXrUSssbiOBHuVojDAOW8meoTaDPv1J9j3eeCidvqop FHZrxZanKLPeNYMdBz7wk9RcwE64MGGodZPQ5pDe8Yq9koI0PiD/BZe/bmUY+Pv2xx4= X-Gm-Gg: AR+sD10ykzR/JNQsYWbi9iHBXHUHU37ySBJ4EgYrCZaPp0m5nNSWdqb7rZvoknWQKfq TWguCMdSmJqX/Av+vg6WEgtciZNirQOEXThedZktctBIBSqBmUL51ZF0GzvHoxR6qoasz/5JJnc n2a9/2pMvlv8atc4aau4UpkMo3ofbwRnIoFyqEpaZn1alQli49iYJqZzi6RYY9ryMKtHp4oDwSL HmVJXAx3Zd2VtlAWM3Fz0fl+9x7Fr1QvRk1iAuD3lofav2yH/CIX+D+k+CKYP6mak3jO6bqVVa0 Jc91XK9c1TTeo2c2cdfOT7KILmnPTcUmGRDy4Xfiidu4WuKT1QSskmFsRFSjNwUbirkEOZ24ifx +vWsMbNTybdwgI0UUjcsiRMFjImvOd4PCKaoTFW7XFUaZ/prhMVq36H3mz+f/oizY+uvzLrgsPp 99DyYDPIK5Co71P6FSn7cWY7iXyUwQNoRuXB2hUzixvRRDZaa2LNWOWQ3dJ1QAwmGx630= X-Received: by 2002:adf:eac3:0:b0:47d:dfc6:b28b with SMTP id ffacd0b85a97d-47fd72e1887mr2042510f8f.30.1785535243383; Fri, 31 Jul 2026 15:00:43 -0700 (PDT) From: "Denis V. Lunev" To: qemu-block@nongnu.org, qemu-stable@nongnu.org, qemu-devel@nongnu.org Cc: den@openvz.org, Kevin Wolf , Hanna Reitz Subject: [PATCH 1/2] qcow2: do not clear the dirty bit when reopening a read-only node Date: Sat, 1 Aug 2026 00:00:38 +0200 Message-ID: <20260731220039.1765584-2-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260731220039.1765584-1-den@openvz.org> References: <20260731220039.1765584-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::436; envelope-from=den@openvz.org; helo=mail-wr1-x436.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @openvz.org) X-ZM-MESSAGEID: 1785535291256158500 Content-Type: text/plain; charset="utf-8" qcow2_reopen_prepare() clears the dirty bit whenever the node is reopened read-only, with an unguarded header write. A read-only node can still be dirty, inherited from an earlier writable session, and it holds no BLK_PERM_WRITE to resolve that. A read-only to read-only reopen of a dirty image therefore fails outright: $ qemu-io -r -f qcow2 dirty.qcow2 <<< $'reopen -r\nquit' qemu-io: failed while preparing to reopen image 'dirty.qcow2' Clear it only for a node that is writable now, the predicate qcow2_do_open() already uses for the repair. bdrv_is_writable() also excludes an inactive node, whose header must not be touched either. Signed-off-by: Denis V. Lunev CC: Kevin Wolf CC: Hanna Reitz --- block/qcow2.c | 8 +++++--- tests/qemu-iotests/039 | 11 +++++++++++ tests/qemu-iotests/039.out | 5 +++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 7292dd036c..1543255eba 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2102,9 +2102,11 @@ qcow2_reopen_prepare(BDRVReopenState *state,BlockReo= penQueue *queue, goto fail; } =20 - ret =3D qcow2_mark_clean(state->bs); - if (ret < 0) { - goto fail; + if (bdrv_is_writable(state->bs)) { + ret =3D qcow2_mark_clean(state->bs); + if (ret < 0) { + goto fail; + } } } =20 diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039 index 94a8bfe754..a5be81bc4a 100755 --- a/tests/qemu-iotests/039 +++ b/tests/qemu-iotests/039 @@ -95,6 +95,17 @@ $QEMU_IMG info --image-opts \ # The dirty bit must still be set: this open never wrote any guest data _qcow2_dump_header | grep incompatible_features =20 +echo +echo "=3D=3D Read-only reopen must not clear the dirty bit =3D=3D" + +# Reopening a read-only node must not try to write the QCOW2 header either, +# and must leave the dirty bit for whoever ends up repairing the image. +$QEMU_IO -r -c "reopen -r" -c "read -P 0x5a 0 512" "$TEST_IMG" \ + | _filter_qemu_io + +# The dirty bit must still be set +_qcow2_dump_header | grep incompatible_features + echo echo "=3D=3D Repairing the image file must succeed =3D=3D" =20 diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out index c66361128f..3c71e5a3dd 100644 --- a/tests/qemu-iotests/039.out +++ b/tests/qemu-iotests/039.out @@ -27,6 +27,11 @@ incompatible_features [0] =3D=3D Read-only open must not crash on close =3D=3D incompatible_features [0] =20 +=3D=3D Read-only reopen must not clear the dirty bit =3D=3D +read 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +incompatible_features [0] + =3D=3D Repairing the image file must succeed =3D=3D ERROR cluster 5 refcount=3D0 reference=3D1 Rebuilding refcount structure --=20 2.53.0 From nobody Mon Sep 28 02:07:56 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1785535301; cv=none; d=zohomail.com; s=zohoarc; b=ctZ2LqzcpnYuZcuJj5SCxjguloyQL8lNWSETuMvwz/L/t9YDsqLfoJD451fOtzZ/Pv/9KkpqVwENPRIPOtaLdjSMAr/ans7/eObXwSg4EY9Bg1o14VhPU1oznAuTZiHl2Xkjuw5Nv/1H00RD29oBUrniiBYMvSnAtVxtEXKBVKw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785535301; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=EqUCep0HZSTo8W3y5ufyYcxJQO20NzUS0NZ7qB5Dt3s=; b=XJZ5xXCgd48QmLE5AojZeQCi2l/zHuZydr/lR+0hncSREH8FB2Iwrcz6qPr8rjjcUm/92q5GAdvoxcuNWs4yh/YZSxi6jiIeqVSRetdN9+XY3irqXMdJFfp/OJssVIvBfGU0K5YlwKrPrNU2UUkoV36MyOv3rKC0D/AeesAvTZ0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785535301542261.8403525898908; Fri, 31 Jul 2026 15:01:41 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wpvHi-00066L-0v; Fri, 31 Jul 2026 18:00:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wpvHc-00064C-BX for qemu-devel@nongnu.org; Fri, 31 Jul 2026 18:00:48 -0400 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wpvHa-0007Sm-HZ for qemu-devel@nongnu.org; Fri, 31 Jul 2026 18:00:48 -0400 Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-47f3b39f2a1so904982f8f.2 for ; Fri, 31 Jul 2026 15:00:46 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:1758:fc6:a5f8:a15f]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47fd41e2cf1sm9711152f8f.10.2026.07.31.15.00.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jul 2026 15:00:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1785535245; x=1786140045; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=EqUCep0HZSTo8W3y5ufyYcxJQO20NzUS0NZ7qB5Dt3s=; b=g3ta6camtSBV/Hjy6teFwssOYe8KvSXTgNE3g7AXVO1PQOgoxIWJ2KbClLWmWiMk0t Gsk3w3lyx3B4oBWiTaWeowVj0vQHRIv9xNHoDfjDDJNB4pbBT1T15RCR2s6EpNRoxMlm DVWcaAbVs4dFNQTfIC7cZuv/PHERbWs1Sg3+8AoKZEgD5dsZcDX+UcgEqIww/2Yr56Jz SQuCPWrVQIfonv/kYnTehQq6Ee3OEmR7Pj2kvx/rxRasS9VsMJ7z0mYIzhCBf901rEES hx5NclKNS9izP4XRqh+jE3xJ6c7n4go6H/fEnGF89aqN4occ4VmINAsTT3zdndfwrdov LZbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785535245; x=1786140045; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=EqUCep0HZSTo8W3y5ufyYcxJQO20NzUS0NZ7qB5Dt3s=; b=rouLuyR6CC5hcGHeR995INtPbM4S50YF35lAkPUm2tzDBp9Yf8SYFMp/iDqZK0BuOT Y26NWlgV2RuvUJUj7nV07ucDDaE4+FuW5e0r06fxELclQoPV0gO1vbI3OB/F/YIg3qxA gghIWwOTfblr6R13JVb4YViOqsBNShtsms8zBv+78sAgKFD+g4EQLugucO6RKEPnbURr eCD5JE7aXePzKJaTVvWKcUy6ivQ0nlq5/DYZ+STCJia8/92Xt37alb4fCCvIDzpzApp+ nLaKdD1IQL1f9R8oAoeHutz8p2+FNiq8wgxH5vC8ln1c/WDBl+Rz7c1IGXhkFMGQu+XN DRTw== X-Forwarded-Encrypted: i=1; AHgh+RrAKfRfstwjLpnywj7PtvPX7Bb5tuoA1+niZ305LxGzB44NCWeEmqiOEdx2cdvDQX+d2CLcSbOjmQyS@nongnu.org X-Gm-Message-State: AOJu0YyESwys6DU4wGd7IaD/a07OJVCtVDM/2800yRfkWmvHAYQA+CzM rEUC63suLffhoYDBav2GG8Kp9WvjmQF0F4rvBSxTT1/JGCofcU6uaOTPhj1zakV5nec= X-Gm-Gg: AR+sD13FehG8NJUPhLOMFSenlZhHTu7gkoyBoEQRjlnpId9uRQQyKdNcrFVSEkJ3gCS D07P02l6xBZq3EsLWe7bzA4bGQBwa5zUQgiRmSR/ajF6eZMnUDyYq8199vHRGrzaJ5ecAZtb9C9 43Qpbz8BwtT7u1mUxVtGCfN5KJMUNz1MpRRm3haQyefhlF+Gkv0ZEfhwwKnZRMNw8X5QgO5pS4C DUq3dPVJ1YwZZ0+NiIaFYD6UFdPeUm3awvDN14ziob0cTLD48UddBVQ6+JbaPXBcNCffSZL/IaQ j4gqzC2LGG90bLlo7huFAyj8alk/Hs1sL18+hYLTDl6hRRfVu2+3TR1WMrrPQJIQhLO33tRatir pjRlBNKbunRB0SIxzwwWkAKH6SslxEACaWxb7pcxCko29zmP2fmkariAwn1ajmmBBPYgjE5Es+7 m7vK5MP0M6jPxG2zqn22l2BV9zlluu+qP4fOwlu+VUByA8J/0MSaYXmwSa2+uYMhFVPuFF X-Received: by 2002:a05:6000:b44:b0:47f:81c4:36a5 with SMTP id ffacd0b85a97d-47fd72a8cdfmr2140256f8f.15.1785535245168; Fri, 31 Jul 2026 15:00:45 -0700 (PDT) From: "Denis V. Lunev" To: qemu-block@nongnu.org, qemu-stable@nongnu.org, qemu-devel@nongnu.org Cc: den@openvz.org, Kevin Wolf , Hanna Reitz Subject: [PATCH 2/2] qcow2: repair a dirty image when it becomes writable Date: Sat, 1 Aug 2026 00:00:39 +0200 Message-ID: <20260731220039.1765584-3-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260731220039.1765584-1-den@openvz.org> References: <20260731220039.1765584-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=den@openvz.org; helo=mail-wr1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @openvz.org) X-ZM-MESSAGEID: 1785535302838158500 Content-Type: text/plain; charset="utf-8" A dirty image must be repaired before anything allocates a cluster in it. qcow2_do_open() does that, but only for a node that is writable from the start. A node opened read-only skips it, and nothing revisits the question once that node becomes writable, which block-commit does routinely: commit_active_start() and commit_start() reopen the base read-write for the duration of the job. With lazy refcounts the on-disk refcount block then still accounts for the metadata clusters only, so the allocator restarts at the front of the image and hands out clusters that L2 entries point at. Two guest offsets end up sharing one host cluster. Nothing fails, the corrupt bit stays clear, and a clean close clears the dirty bit, so no later open repairs the image either. Do the repair in qcow2_reopen_commit_post(). bdrv_reopen_prepare() runs before bdrv_list_refresh_perms(), so it holds no BLK_PERM_WRITE and, with auto-read-only, bs->file may still have an O_RDONLY descriptor. commit_post cannot reject the reopen, so signal corruption if the repair fails rather than let writes alias live clusters. An inactive node is skipped: bdrv_activate() calls qcow2_do_open() again through qcow2_co_invalidate_cache(). Signed-off-by: Denis V. Lunev CC: Kevin Wolf CC: Hanna Reitz --- block/qcow2.c | 14 ++++++++++++++ tests/qemu-iotests/039 | 24 ++++++++++++++++++++++++ tests/qemu-iotests/039.out | 17 +++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/block/qcow2.c b/block/qcow2.c index 1543255eba..e660655a0d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2147,8 +2147,22 @@ static void qcow2_reopen_commit(BDRVReopenState *sta= te) =20 static void qcow2_reopen_commit_post(BDRVReopenState *state) { + BDRVQcow2State *s =3D state->bs->opaque; + GRAPH_RDLOCK_GUARD_MAINLOOP(); =20 + if (bdrv_is_writable(state->bs) && + (s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) { + BdrvCheckResult result =3D {0}; + int ret; + + ret =3D bdrv_check(state->bs, &result, BDRV_FIX_ERRORS | BDRV_FIX_= LEAKS); + if (ret < 0 || result.check_errors) { + qcow2_signal_corruption(state->bs, true, -1, -1, + "Could not repair dirty image"); + } + } + if (state->flags & BDRV_O_RDWR) { Error *local_err =3D NULL; =20 diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039 index a5be81bc4a..255dc2e7e5 100755 --- a/tests/qemu-iotests/039 +++ b/tests/qemu-iotests/039 @@ -137,6 +137,30 @@ $QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io # The dirty bit must not be set _qcow2_dump_header | grep incompatible_features =20 +echo +echo "=3D=3D Reopening a dirty image read/write should repair it =3D=3D" + +_make_test_img -o "compat=3D1.1,lazy_refcounts=3Don" $size + +_NO_VALGRIND \ +$QEMU_IO -c "write -P 0x5a 0 512" \ + -c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \ + | _filter_qemu_io + +# The dirty bit must be set +_qcow2_dump_header | grep incompatible_features + +# The refcounts are only resolved when the node becomes writable. Without +# that, this write is allocated on top of the cluster at offset 0 and read= ing +# it back returns the data written here. +$QEMU_IO -r -c "reopen -w" \ + -c "write -P 0xb1 1M 512" \ + -c "read -P 0x5a 0 512" "$TEST_IMG" | _filter_qemu_io + +# The dirty bit must not be set +_qcow2_dump_header | grep incompatible_features +_check_test_img + echo echo "=3D=3D Creating an image file with lazy_refcounts=3Doff =3D=3D" =20 diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out index 3c71e5a3dd..62073916a9 100644 --- a/tests/qemu-iotests/039.out +++ b/tests/qemu-iotests/039.out @@ -64,6 +64,23 @@ wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) incompatible_features [] =20 +=3D=3D Reopening a dirty image read/write should repair it =3D=3D +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D134217728 +wrote 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +./common.rc: Killed ( VALGRIND_QEMU=3D"${VALGRIND_QEMU_IO}" _qemu_proc_exe= c "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" ) +incompatible_features [0] +ERROR cluster 5 refcount=3D0 reference=3D1 +Rebuilding refcount structure +Repairing cluster 1 refcount=3D1 reference=3D0 +Repairing cluster 2 refcount=3D1 reference=3D0 +wrote 512/512 bytes at offset 1048576 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +incompatible_features [] +No errors were found on the image. + =3D=3D Creating an image file with lazy_refcounts=3Doff =3D=3D Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D134217728 wrote 512/512 bytes at offset 0 --=20 2.53.0