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

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