thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone

Blame SOURCES/kvm-block-make-bdrv_co_do_write_zeroes-stricter-in-produ.patch.patch.patch

9ae3a8
From 4a1e019ac51460ce6329892cc99fc11d518d2eb2 Mon Sep 17 00:00:00 2001
9ae3a8
Message-Id: <4a1e019ac51460ce6329892cc99fc11d518d2eb2.1389014116.git.minovotn@redhat.com>
9ae3a8
In-Reply-To: <c8cc35838d42aa286242772d97e3a9be7bb786ba.1389014116.git.minovotn@redhat.com>
9ae3a8
References: <c8cc35838d42aa286242772d97e3a9be7bb786ba.1389014116.git.minovotn@redhat.com>
9ae3a8
From: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
Date: Mon, 9 Dec 2013 14:09:16 +0100
9ae3a8
Subject: [PATCH 28/50] block: make bdrv_co_do_write_zeroes stricter in
9ae3a8
 producing aligned requests
9ae3a8
9ae3a8
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
Message-id: <1386598178-11845-31-git-send-email-pbonzini@redhat.com>
9ae3a8
Patchwork-id: 56067
9ae3a8
O-Subject: [RHEL 7.0 qemu-kvm PATCH 30/52] block: make bdrv_co_do_write_zeroes stricter in producing aligned requests
9ae3a8
Bugzilla: 1007815
9ae3a8
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
9ae3a8
RH-Acked-by: Fam Zheng <famz@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
9ae3a8
Right now, bdrv_co_do_write_zeroes will only try to align the
9ae3a8
beginning of the request.  However, it is simpler for many
9ae3a8
formats to expect the block layer to separate both the head *and*
9ae3a8
the tail.  This makes sure that the format's bdrv_co_write_zeroes
9ae3a8
function will be called with aligned sector_num and nb_sectors for
9ae3a8
the bulk of the request.
9ae3a8
9ae3a8
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
Reviewed-by: Peter Lieven <pl@kamp.de>
9ae3a8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
(cherry picked from commit b8d71c09f31a9cae248d167dddc75c66d5135ff2)
9ae3a8
---
9ae3a8
 block.c | 35 +++++++++++++++++++++++------------
9ae3a8
 1 file changed, 23 insertions(+), 12 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Michal Novotny <minovotn@redhat.com>
9ae3a8
---
9ae3a8
 block.c | 35 +++++++++++++++++++++++------------
9ae3a8
 1 file changed, 23 insertions(+), 12 deletions(-)
9ae3a8
9ae3a8
diff --git a/block.c b/block.c
9ae3a8
index c9e65b4..1ac1ab3 100644
9ae3a8
--- a/block.c
9ae3a8
+++ b/block.c
9ae3a8
@@ -2781,14 +2781,21 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
9ae3a8
     while (nb_sectors > 0 && !ret) {
9ae3a8
         int num = nb_sectors;
9ae3a8
 
9ae3a8
-        /* align request */
9ae3a8
-        if (bs->bl.write_zeroes_alignment &&
9ae3a8
-            num >= bs->bl.write_zeroes_alignment &&
9ae3a8
-            sector_num % bs->bl.write_zeroes_alignment) {
9ae3a8
-            if (num > bs->bl.write_zeroes_alignment) {
9ae3a8
+        /* Align request.  Block drivers can expect the "bulk" of the request
9ae3a8
+         * to be aligned.
9ae3a8
+         */
9ae3a8
+        if (bs->bl.write_zeroes_alignment
9ae3a8
+            && num > bs->bl.write_zeroes_alignment) {
9ae3a8
+            if (sector_num % bs->bl.write_zeroes_alignment != 0) {
9ae3a8
+                /* Make a small request up to the first aligned sector.  */
9ae3a8
                 num = bs->bl.write_zeroes_alignment;
9ae3a8
+                num -= sector_num % bs->bl.write_zeroes_alignment;
9ae3a8
+            } else if ((sector_num + num) % bs->bl.write_zeroes_alignment != 0) {
9ae3a8
+                /* Shorten the request to the last aligned sector.  num cannot
9ae3a8
+                 * underflow because num > bs->bl.write_zeroes_alignment.
9ae3a8
+                 */
9ae3a8
+                num -= (sector_num + num) % bs->bl.write_zeroes_alignment;
9ae3a8
             }
9ae3a8
-            num -= sector_num % bs->bl.write_zeroes_alignment;
9ae3a8
         }
9ae3a8
 
9ae3a8
         /* limit request size */
9ae3a8
@@ -2806,16 +2813,20 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
9ae3a8
             /* Fall back to bounce buffer if write zeroes is unsupported */
9ae3a8
             iov.iov_len = num * BDRV_SECTOR_SIZE;
9ae3a8
             if (iov.iov_base == NULL) {
9ae3a8
-                /* allocate bounce buffer only once and ensure that it
9ae3a8
-                 * is big enough for this and all future requests.
9ae3a8
-                 */
9ae3a8
-                size_t bufsize = num <= nb_sectors ? num : max_write_zeroes;
9ae3a8
-                iov.iov_base = qemu_blockalign(bs, bufsize * BDRV_SECTOR_SIZE);
9ae3a8
-                memset(iov.iov_base, 0, bufsize * BDRV_SECTOR_SIZE);
9ae3a8
+                iov.iov_base = qemu_blockalign(bs, num * BDRV_SECTOR_SIZE);
9ae3a8
+                memset(iov.iov_base, 0, num * BDRV_SECTOR_SIZE);
9ae3a8
             }
9ae3a8
             qemu_iovec_init_external(&qiov, &iov, 1);
9ae3a8
 
9ae3a8
             ret = drv->bdrv_co_writev(bs, sector_num, num, &qiov);
9ae3a8
+
9ae3a8
+            /* Keep bounce buffer around if it is big enough for all
9ae3a8
+             * all future requests.
9ae3a8
+             */
9ae3a8
+            if (num < max_write_zeroes) {
9ae3a8
+                qemu_vfree(iov.iov_base);
9ae3a8
+                iov.iov_base = NULL;
9ae3a8
+            }
9ae3a8
         }
9ae3a8
 
9ae3a8
         sector_num += num;
9ae3a8
-- 
9ae3a8
1.7.11.7
9ae3a8