Blame SOURCES/kvm-qemu-img-Convert-with-copy-offloading.patch

383d26
From 2b47a16d95ebd4d50a0a62d30acd007eb50ce0ea Mon Sep 17 00:00:00 2001
383d26
From: Fam Zheng <famz@redhat.com>
383d26
Date: Wed, 4 Jul 2018 07:56:31 +0200
383d26
Subject: [PATCH 46/57] qemu-img: Convert with copy offloading
383d26
383d26
RH-Author: Fam Zheng <famz@redhat.com>
383d26
Message-id: <20180629061153.12687-11-famz@redhat.com>
383d26
Patchwork-id: 81158
383d26
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH v2 10/13] qemu-img: Convert with copy offloading
383d26
Bugzilla: 1482537
383d26
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
383d26
RH-Acked-by: Max Reitz <mreitz@redhat.com>
383d26
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
383d26
383d26
The new blk_co_copy_range interface offers a more efficient way in the
383d26
case of network based storage. Make use of it to allow faster convert
383d26
operation.
383d26
383d26
Since copy offloading cannot do zero detection ('-S') and compression
383d26
(-c), only try it when these options are not used.
383d26
383d26
Signed-off-by: Fam Zheng <famz@redhat.com>
383d26
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
383d26
Message-id: 20180601092648.24614-11-famz@redhat.com
383d26
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
383d26
(cherry picked from commit ee5306d0923377439776e8a30b9fd2de34b5cbfb)
383d26
Signed-off-by: Fam Zheng <famz@redhat.com>
383d26
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
---
383d26
 qemu-img.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++--
383d26
 1 file changed, 48 insertions(+), 2 deletions(-)
383d26
383d26
diff --git a/qemu-img.c b/qemu-img.c
383d26
index 9fc8e66..b2ef54e 100644
383d26
--- a/qemu-img.c
383d26
+++ b/qemu-img.c
383d26
@@ -1561,6 +1561,7 @@ typedef struct ImgConvertState {
383d26
     bool target_has_backing;
383d26
     int64_t target_backing_sectors; /* negative if unknown */
383d26
     bool wr_in_order;
383d26
+    bool copy_range;
383d26
     int min_sparse;
383d26
     size_t cluster_sectors;
383d26
     size_t buf_sectors;
383d26
@@ -1765,6 +1766,37 @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
383d26
     return 0;
383d26
 }
383d26
 
383d26
+static int coroutine_fn convert_co_copy_range(ImgConvertState *s, int64_t sector_num,
383d26
+                                              int nb_sectors)
383d26
+{
383d26
+    int n, ret;
383d26
+
383d26
+    while (nb_sectors > 0) {
383d26
+        BlockBackend *blk;
383d26
+        int src_cur;
383d26
+        int64_t bs_sectors, src_cur_offset;
383d26
+        int64_t offset;
383d26
+
383d26
+        convert_select_part(s, sector_num, &src_cur, &src_cur_offset);
383d26
+        offset = (sector_num - src_cur_offset) << BDRV_SECTOR_BITS;
383d26
+        blk = s->src[src_cur];
383d26
+        bs_sectors = s->src_sectors[src_cur];
383d26
+
383d26
+        n = MIN(nb_sectors, bs_sectors - (sector_num - src_cur_offset));
383d26
+
383d26
+        ret = blk_co_copy_range(blk, offset, s->target,
383d26
+                                sector_num << BDRV_SECTOR_BITS,
383d26
+                                n << BDRV_SECTOR_BITS, 0);
383d26
+        if (ret < 0) {
383d26
+            return ret;
383d26
+        }
383d26
+
383d26
+        sector_num += n;
383d26
+        nb_sectors -= n;
383d26
+    }
383d26
+    return 0;
383d26
+}
383d26
+
383d26
 static void coroutine_fn convert_co_do_copy(void *opaque)
383d26
 {
383d26
     ImgConvertState *s = opaque;
383d26
@@ -1787,6 +1819,7 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
383d26
         int n;
383d26
         int64_t sector_num;
383d26
         enum ImgConvertBlockStatus status;
383d26
+        bool copy_range;
383d26
 
383d26
         qemu_co_mutex_lock(&s->lock);
383d26
         if (s->ret != -EINPROGRESS || s->sector_num >= s->total_sectors) {
383d26
@@ -1816,7 +1849,9 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
383d26
                                         s->allocated_sectors, 0);
383d26
         }
383d26
 
383d26
-        if (status == BLK_DATA) {
383d26
+retry:
383d26
+        copy_range = s->copy_range && s->status == BLK_DATA;
383d26
+        if (status == BLK_DATA && !copy_range) {
383d26
             ret = convert_co_read(s, sector_num, n, buf);
383d26
             if (ret < 0) {
383d26
                 error_report("error while reading sector %" PRId64
383d26
@@ -1838,7 +1873,15 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
383d26
         }
383d26
 
383d26
         if (s->ret == -EINPROGRESS) {
383d26
-            ret = convert_co_write(s, sector_num, n, buf, status);
383d26
+            if (copy_range) {
383d26
+                ret = convert_co_copy_range(s, sector_num, n);
383d26
+                if (ret) {
383d26
+                    s->copy_range = false;
383d26
+                    goto retry;
383d26
+                }
383d26
+            } else {
383d26
+                ret = convert_co_write(s, sector_num, n, buf, status);
383d26
+            }
383d26
             if (ret < 0) {
383d26
                 error_report("error while writing sector %" PRId64
383d26
                              ": %s", sector_num, strerror(-ret));
383d26
@@ -1961,6 +2004,7 @@ static int img_convert(int argc, char **argv)
383d26
     ImgConvertState s = (ImgConvertState) {
383d26
         /* Need at least 4k of zeros for sparse detection */
383d26
         .min_sparse         = 8,
383d26
+        .copy_range         = true,
383d26
         .buf_sectors        = IO_BUF_SIZE / BDRV_SECTOR_SIZE,
383d26
         .wr_in_order        = true,
383d26
         .num_coroutines     = 8,
383d26
@@ -2001,6 +2045,7 @@ static int img_convert(int argc, char **argv)
383d26
             break;
383d26
         case 'c':
383d26
             s.compressed = true;
383d26
+            s.copy_range = false;
383d26
             break;
383d26
         case 'o':
383d26
             if (!is_valid_option_list(optarg)) {
383d26
@@ -2042,6 +2087,7 @@ static int img_convert(int argc, char **argv)
383d26
             }
383d26
 
383d26
             s.min_sparse = sval / BDRV_SECTOR_SIZE;
383d26
+            s.copy_range = false;
383d26
             break;
383d26
         }
383d26
         case 'p':
383d26
-- 
383d26
1.8.3.1
383d26