[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 017/156] qcow2: Flush metadata during read-only reop
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 017/156] qcow2: Flush metadata during read-only reopen |
Date: |
Tue, 8 Jul 2014 12:16:48 -0500 |
From: Kevin Wolf <address@hidden>
If lazy refcounts are enabled for a backing file, committing to this
backing file may leave it in a dirty state even if the commit succeeds.
The reason is that the bdrv_flush() call in bdrv_commit() doesn't flush
refcount updates with lazy refcounts enabled, and qcow2_reopen_prepare()
doesn't take care to flush metadata.
In order to fix this, this patch also fixes qcow2_mark_clean(), which
contains another ineffective bdrv_flush() call beause lazy refcounts are
disabled only afterwards. All existing callers of qcow2_mark_clean()
either don't modify refcounts or already flush manually, so that this
fixes only a latent, but not yet actually triggerable bug.
Another instance of the same problem is live snapshots. Again, a real
corruption is prevented by an explicit flush for non-read-only images in
external_snapshot_prepare(), but images using lazy refcounts stay dirty.
Cc: address@hidden
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
(cherry picked from commit 4c2e5f8f46a17966dc45b5a3e07b97434c0eabdf)
Signed-off-by: Michael Roth <address@hidden>
---
block/qcow2.c | 25 +++++++++++++++++++++----
tests/qemu-iotests/039 | 20 ++++++++++++++++++++
tests/qemu-iotests/039.out | 11 +++++++++++
3 files changed, 52 insertions(+), 4 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 6e5d98d..b43c7d0 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -269,12 +269,15 @@ static int qcow2_mark_clean(BlockDriverState *bs)
BDRVQcowState *s = bs->opaque;
if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) {
- int ret = bdrv_flush(bs);
+ int ret;
+
+ s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY;
+
+ ret = bdrv_flush(bs);
if (ret < 0) {
return ret;
}
- s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY;
return qcow2_update_header(bs);
}
return 0;
@@ -792,11 +795,25 @@ static int qcow2_set_key(BlockDriverState *bs, const char
*key)
return 0;
}
-/* We have nothing to do for QCOW2 reopen, stubs just return
- * success */
+/* We have no actual commit/abort logic for qcow2, but we need to write out any
+ * unwritten data if we reopen read-only. */
static int qcow2_reopen_prepare(BDRVReopenState *state,
BlockReopenQueue *queue, Error **errp)
{
+ int ret;
+
+ if ((state->flags & BDRV_O_RDWR) == 0) {
+ ret = bdrv_flush(state->bs);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = qcow2_mark_clean(state->bs);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
return 0;
}
diff --git a/tests/qemu-iotests/039 b/tests/qemu-iotests/039
index 8bade92..cc4fad8 100755
--- a/tests/qemu-iotests/039
+++ b/tests/qemu-iotests/039
@@ -130,6 +130,26 @@ ulimit -c "$old_ulimit"
./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
_check_test_img
+echo
+echo "== Committing to a backing file with lazy_refcounts=on =="
+
+IMGOPTS="compat=1.1,lazy_refcounts=on"
+TEST_IMG="$TEST_IMG".base _make_test_img $size
+
+IMGOPTS="compat=1.1,lazy_refcounts=on,backing_file=$TEST_IMG.base"
+_make_test_img $size
+
+$QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG commit "$TEST_IMG"
+
+# The dirty bit must not be set
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+./qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features
+
+_check_test_img
+TEST_IMG="$TEST_IMG".base _check_test_img
+
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out
index 077fa64..fb31ae0 100644
--- a/tests/qemu-iotests/039.out
+++ b/tests/qemu-iotests/039.out
@@ -54,4 +54,15 @@ wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
incompatible_features 0x0
No errors were found on the image.
+
+== Committing to a backing file with lazy_refcounts=on ==
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
backing_file='TEST_DIR/t.IMGFMT.base'
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+Image committed.
+incompatible_features 0x0
+incompatible_features 0x0
+No errors were found on the image.
+No errors were found on the image.
*** done
--
1.9.1
- [Qemu-devel] Patch Round-up for stable 1.7.2, freeze on 2014-07-14, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 002/156] scsi-bus: Fix transfer length for VERIFY with BYTCHK=11b, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 001/156] char: restore read callback on a reattached (hotplug) chardev, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 005/156] target-i386: Fix CC_OP_CLR vs PF, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 020/156] megasas: Implement LD_LIST_QUERY, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 021/156] arm: translate.c: Fix smlald Instruction, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 017/156] qcow2: Flush metadata during read-only reopen,
Michael Roth <=
- [Qemu-devel] [PATCH 013/156] mirror: fix early wake from sleep due to aio, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 022/156] block: Prevent coroutine stack overflow when recursing in bdrv_open_backing_file., Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 025/156] s390x: empty function stubs in preparation for __KVM_HAVE_GUEST_DEBUG, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 018/156] block-commit: speed is an optional parameter, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 024/156] s390x/helper: Added format control bit to MMU translation, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 003/156] block/iscsi: fix deadlock on scsi check condition, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 029/156] vmxnet3: validate queues configuration coming from guest, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 028/156] vmxnet3: validate interrupt indices coming from guest, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 031/156] vmxnet3: validate queues configuration read on migration, Michael Roth, 2014/07/08
- [Qemu-devel] [PATCH 027/156] acpi: fix tables for no-hpet configuration, Michael Roth, 2014/07/08