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

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