Blame SOURCES/kvm-block-Fix-copy-on-read-crash-with-partial-final-clus.patch

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