yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
26ba25
From 3ad6a0d2e3805867cd5af8ccea841acb3608de99 Mon Sep 17 00:00:00 2001
26ba25
From: Kevin Wolf <kwolf@redhat.com>
26ba25
Date: Thu, 12 Jul 2018 15:00:08 +0200
26ba25
Subject: [PATCH 214/268] block: Fix copy-on-read crash with partial final
26ba25
 cluster
26ba25
26ba25
RH-Author: Kevin Wolf <kwolf@redhat.com>
26ba25
Message-id: <20180712150008.23662-2-kwolf@redhat.com>
26ba25
Patchwork-id: 81331
26ba25
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH 1/1] block: Fix copy-on-read crash with partial final cluster
26ba25
Bugzilla: 1590640
26ba25
RH-Acked-by: Max Reitz <mreitz@redhat.com>
26ba25
RH-Acked-by: Fam Zheng <famz@redhat.com>
26ba25
RH-Acked-by: John Snow <jsnow@redhat.com>
26ba25
RH-Acked-by: Richard Jones <rjones@redhat.com>
26ba25
26ba25
If the virtual disk size isn't aligned to full clusters,
26ba25
bdrv_co_do_copy_on_readv() may get pnum == 0 before having the full
26ba25
cluster completed, which will let it run into an assertion failure:
26ba25
26ba25
qemu-io: block/io.c:1203: bdrv_co_do_copy_on_readv: Assertion `skip_bytes < pnum' failed.
26ba25
26ba25
Check for EOF, assert that we read at least as much as the read request
26ba25
originally wanted to have (which is true at EOF because otherwise
26ba25
bdrv_check_byte_request() would already have returned an error) and
26ba25
return success early even though we couldn't copy the full cluster.
26ba25
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
(cherry picked from commit b0ddcbbb36a66a605eb232b905cb49b1cc72e74e)
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
---
26ba25
 block/io.c                 | 6 ++++++
26ba25
 tests/qemu-iotests/197     | 9 +++++++++
26ba25
 tests/qemu-iotests/197.out | 8 ++++++++
26ba25
 3 files changed, 23 insertions(+)
26ba25
26ba25
diff --git a/block/io.c b/block/io.c
26ba25
index ad8afc0..ac36d1c 100644
26ba25
--- a/block/io.c
26ba25
+++ b/block/io.c
26ba25
@@ -1095,6 +1095,12 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child,
26ba25
             pnum = MIN(cluster_bytes, max_transfer);
26ba25
         }
26ba25
 
26ba25
+        /* Stop at EOF if the image ends in the middle of the cluster */
26ba25
+        if (ret == 0 && pnum == 0) {
26ba25
+            assert(progress >= bytes);
26ba25
+            break;
26ba25
+        }
26ba25
+
26ba25
         assert(skip_bytes < pnum);
26ba25
 
26ba25
         if (ret <= 0) {
26ba25
diff --git a/tests/qemu-iotests/197 b/tests/qemu-iotests/197
26ba25
index 3ae4975..0369aa5 100755
26ba25
--- a/tests/qemu-iotests/197
26ba25
+++ b/tests/qemu-iotests/197
26ba25
@@ -109,6 +109,15 @@ $QEMU_IO -f qcow2 -c map "$TEST_WRAP"
26ba25
 _check_test_img
26ba25
 $QEMU_IMG compare -f $IMGFMT -F qcow2 "$TEST_IMG" "$TEST_WRAP"
26ba25
 
26ba25
+echo
26ba25
+echo '=== Partial final cluster ==='
26ba25
+echo
26ba25
+
26ba25
+_make_test_img 1024
26ba25
+$QEMU_IO -f $IMGFMT -C -c 'read 0 1024' "$TEST_IMG" | _filter_qemu_io
26ba25
+$QEMU_IO -f $IMGFMT -c map "$TEST_IMG"
26ba25
+_check_test_img
26ba25
+
26ba25
 # success, all done
26ba25
 echo '*** done'
26ba25
 status=0
26ba25
diff --git a/tests/qemu-iotests/197.out b/tests/qemu-iotests/197.out
26ba25
index 52b4137..8febda5 100644
26ba25
--- a/tests/qemu-iotests/197.out
26ba25
+++ b/tests/qemu-iotests/197.out
26ba25
@@ -23,4 +23,12 @@ can't open device TEST_DIR/t.wrap.qcow2: Can't use copy-on-read on read-only dev
26ba25
 1023.938 MiB (0x3fff0000) bytes not allocated at offset 3 GiB (0xc0010000)
26ba25
 No errors were found on the image.
26ba25
 Images are identical.
26ba25
+
26ba25
+=== Partial final cluster ===
26ba25
+
26ba25
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1024
26ba25
+read 1024/1024 bytes at offset 0
26ba25
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
26ba25
+1 KiB (0x400) bytes     allocated at offset 0 bytes (0x0)
26ba25
+No errors were found on the image.
26ba25
 *** done
26ba25
-- 
26ba25
1.8.3.1
26ba25