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

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