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

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