yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-block-Require-aligned-image-size-to-avoid-assertion-.patch

a19a21
From e191ab6358b656764374ff1b3c7224a744dc902a Mon Sep 17 00:00:00 2001
a19a21
From: Kevin Wolf <kwolf@redhat.com>
a19a21
Date: Tue, 26 Jan 2021 17:21:02 -0500
a19a21
Subject: [PATCH 7/9] block: Require aligned image size to avoid assertion
a19a21
 failure
a19a21
a19a21
RH-Author: Kevin Wolf <kwolf@redhat.com>
a19a21
Message-id: <20210126172103.136060-2-kwolf@redhat.com>
a19a21
Patchwork-id: 100786
a19a21
O-Subject: [RHEL-8.4.0 qemu-kvm PATCH 1/2] block: Require aligned image size to avoid assertion failure
a19a21
Bugzilla: 1834281
a19a21
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
a19a21
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
a19a21
RH-Acked-by: Max Reitz <mreitz@redhat.com>
a19a21
a19a21
Unaligned requests will automatically be aligned to bl.request_alignment
a19a21
and we can't extend write requests to access space beyond the end of the
a19a21
image without resizing the image, so if we have the WRITE permission,
a19a21
but not the RESIZE one, it's required that the image size is aligned.
a19a21
a19a21
Failing to meet this requirement could cause assertion failures like
a19a21
this if RESIZE permissions weren't requested:
a19a21
a19a21
qemu-img: block/io.c:1910: bdrv_co_write_req_prepare: Assertion `end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE' failed.
a19a21
a19a21
This was e.g. triggered by qemu-img converting to a target image with 4k
a19a21
request alignment when the image was only aligned to 512 bytes, but not
a19a21
to 4k.
a19a21
a19a21
Turn this into a graceful error in bdrv_check_perm() so that WRITE
a19a21
without RESIZE can only be taken if the image size is aligned. If a user
a19a21
holds both permissions and drops only RESIZE, the function will return
a19a21
an error, but bdrv_child_try_set_perm() will ignore the failure silently
a19a21
if permissions are only requested to be relaxed and just keep both
a19a21
permissions while returning success.
a19a21
a19a21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
a19a21
Message-Id: <20200716142601.111237-2-kwolf@redhat.com>
a19a21
Reviewed-by: Max Reitz <mreitz@redhat.com>
a19a21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
a19a21
(cherry picked from commit 9c60a5d1978e6dcf85c0e01b50e6f7f54ca09104)
a19a21
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
a19a21
Signed-off-by: Jon Maloy <jmaloy.redhat.com>
a19a21
---
a19a21
 block.c | 16 ++++++++++++++++
a19a21
 1 file changed, 16 insertions(+)
a19a21
a19a21
diff --git a/block.c b/block.c
a19a21
index 57740d312e..e9579ddf84 100644
a19a21
--- a/block.c
a19a21
+++ b/block.c
a19a21
@@ -2009,6 +2009,22 @@ static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q,
a19a21
         return -EPERM;
a19a21
     }
a19a21
 
a19a21
+    /*
a19a21
+     * Unaligned requests will automatically be aligned to bl.request_alignment
a19a21
+     * and without RESIZE we can't extend requests to write to space beyond the
a19a21
+     * end of the image, so it's required that the image size is aligned.
a19a21
+     */
a19a21
+    if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) &&
a19a21
+        !(cumulative_perms & BLK_PERM_RESIZE))
a19a21
+    {
a19a21
+        if ((bs->total_sectors * BDRV_SECTOR_SIZE) % bs->bl.request_alignment) {
a19a21
+            error_setg(errp, "Cannot get 'write' permission without 'resize': "
a19a21
+                             "Image size is not a multiple of request "
a19a21
+                             "alignment");
a19a21
+            return -EPERM;
a19a21
+        }
a19a21
+    }
a19a21
+
a19a21
     /* Check this node */
a19a21
     if (!drv) {
a19a21
         return 0;
a19a21
-- 
a19a21
2.18.2
a19a21