26ba25
From b4442d3284353b0ad54eacbe7e29c8d09dbcf301 Mon Sep 17 00:00:00 2001
26ba25
From: Max Reitz <mreitz@redhat.com>
26ba25
Date: Mon, 18 Jun 2018 16:12:04 +0200
26ba25
Subject: [PATCH 037/268] block: Add COR filter driver
26ba25
26ba25
RH-Author: Max Reitz <mreitz@redhat.com>
26ba25
Message-id: <20180618161212.14444-3-mreitz@redhat.com>
26ba25
Patchwork-id: 80762
26ba25
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH 02/10] block: Add COR filter driver
26ba25
Bugzilla: 1518738
26ba25
RH-Acked-by: John Snow <jsnow@redhat.com>
26ba25
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
26ba25
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
26ba25
This adds a simple copy-on-read filter driver.  It relies on the already
26ba25
existing COR functionality in the central block layer code, which may be
26ba25
moved here once we no longer need it there.
26ba25
26ba25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26ba25
Message-id: 20180421132929.21610-2-mreitz@redhat.com
26ba25
Reviewed-by: Alberto Garcia <berto@igalia.com>
26ba25
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26ba25
(cherry picked from commit 6c6f24fd84895d03baa898bbc4324dd4ccc97071)
26ba25
Signed-off-by: Max Reitz <mreitz@redhat.com>
26ba25
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
---
26ba25
 block/Makefile.objs  |   2 +-
26ba25
 block/copy-on-read.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++
26ba25
 qapi/block-core.json |   5 +-
26ba25
 3 files changed, 176 insertions(+), 2 deletions(-)
26ba25
 create mode 100644 block/copy-on-read.c
26ba25
26ba25
diff --git a/block/Makefile.objs b/block/Makefile.objs
26ba25
index c0693fc..be2cda1 100644
26ba25
--- a/block/Makefile.objs
26ba25
+++ b/block/Makefile.objs
26ba25
@@ -26,7 +26,7 @@ block-obj-y += accounting.o dirty-bitmap.o
26ba25
 block-obj-y += write-threshold.o
26ba25
 block-obj-y += backup.o
26ba25
 block-obj-$(CONFIG_REPLICATION) += replication.o
26ba25
-block-obj-y += throttle.o
26ba25
+block-obj-y += throttle.o copy-on-read.o
26ba25
 
26ba25
 block-obj-y += crypto.o
26ba25
 
26ba25
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
26ba25
new file mode 100644
26ba25
index 0000000..823ec75
26ba25
--- /dev/null
26ba25
+++ b/block/copy-on-read.c
26ba25
@@ -0,0 +1,171 @@
26ba25
+/*
26ba25
+ * Copy-on-read filter block driver
26ba25
+ *
26ba25
+ * Copyright (c) 2018 Red Hat, Inc.
26ba25
+ *
26ba25
+ * Author:
26ba25
+ *   Max Reitz <mreitz@redhat.com>
26ba25
+ *
26ba25
+ * This program is free software; you can redistribute it and/or
26ba25
+ * modify it under the terms of the GNU General Public License as
26ba25
+ * published by the Free Software Foundation; either version 2 or
26ba25
+ * (at your option) version 3 of the License.
26ba25
+ *
26ba25
+ * This program is distributed in the hope that it will be useful,
26ba25
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26ba25
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26ba25
+ * GNU General Public License for more details.
26ba25
+ *
26ba25
+ * You should have received a copy of the GNU General Public License
26ba25
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
26ba25
+ */
26ba25
+
26ba25
+#include "qemu/osdep.h"
26ba25
+#include "block/block_int.h"
26ba25
+
26ba25
+
26ba25
+static int cor_open(BlockDriverState *bs, QDict *options, int flags,
26ba25
+                    Error **errp)
26ba25
+{
26ba25
+    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
26ba25
+                               errp);
26ba25
+    if (!bs->file) {
26ba25
+        return -EINVAL;
26ba25
+    }
26ba25
+
26ba25
+    bs->supported_write_flags = BDRV_REQ_FUA &
26ba25
+                                    bs->file->bs->supported_write_flags;
26ba25
+
26ba25
+    bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
26ba25
+                                    bs->file->bs->supported_zero_flags;
26ba25
+
26ba25
+    return 0;
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static void cor_close(BlockDriverState *bs)
26ba25
+{
26ba25
+}
26ba25
+
26ba25
+
26ba25
+#define PERM_PASSTHROUGH (BLK_PERM_CONSISTENT_READ \
26ba25
+                          | BLK_PERM_WRITE \
26ba25
+                          | BLK_PERM_RESIZE)
26ba25
+#define PERM_UNCHANGED (BLK_PERM_ALL & ~PERM_PASSTHROUGH)
26ba25
+
26ba25
+static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
26ba25
+                           const BdrvChildRole *role,
26ba25
+                           BlockReopenQueue *reopen_queue,
26ba25
+                           uint64_t perm, uint64_t shared,
26ba25
+                           uint64_t *nperm, uint64_t *nshared)
26ba25
+{
26ba25
+    if (c == NULL) {
26ba25
+        *nperm = (perm & PERM_PASSTHROUGH) | BLK_PERM_WRITE_UNCHANGED;
26ba25
+        *nshared = (shared & PERM_PASSTHROUGH) | PERM_UNCHANGED;
26ba25
+        return;
26ba25
+    }
26ba25
+
26ba25
+    *nperm = (perm & PERM_PASSTHROUGH) |
26ba25
+             (c->perm & PERM_UNCHANGED);
26ba25
+    *nshared = (shared & PERM_PASSTHROUGH) |
26ba25
+               (c->shared_perm & PERM_UNCHANGED);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static int64_t cor_getlength(BlockDriverState *bs)
26ba25
+{
26ba25
+    return bdrv_getlength(bs->file->bs);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static int cor_truncate(BlockDriverState *bs, int64_t offset,
26ba25
+                        PreallocMode prealloc, Error **errp)
26ba25
+{
26ba25
+    return bdrv_truncate(bs->file, offset, prealloc, errp);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static int coroutine_fn cor_co_preadv(BlockDriverState *bs,
26ba25
+                                      uint64_t offset, uint64_t bytes,
26ba25
+                                      QEMUIOVector *qiov, int flags)
26ba25
+{
26ba25
+    return bdrv_co_preadv(bs->file, offset, bytes, qiov,
26ba25
+                          flags | BDRV_REQ_COPY_ON_READ);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static int coroutine_fn cor_co_pwritev(BlockDriverState *bs,
26ba25
+                                       uint64_t offset, uint64_t bytes,
26ba25
+                                       QEMUIOVector *qiov, int flags)
26ba25
+{
26ba25
+
26ba25
+    return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static int coroutine_fn cor_co_pwrite_zeroes(BlockDriverState *bs,
26ba25
+                                             int64_t offset, int bytes,
26ba25
+                                             BdrvRequestFlags flags)
26ba25
+{
26ba25
+    return bdrv_co_pwrite_zeroes(bs->file, offset, bytes, flags);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static int coroutine_fn cor_co_pdiscard(BlockDriverState *bs,
26ba25
+                                        int64_t offset, int bytes)
26ba25
+{
26ba25
+    return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static void cor_eject(BlockDriverState *bs, bool eject_flag)
26ba25
+{
26ba25
+    bdrv_eject(bs->file->bs, eject_flag);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static void cor_lock_medium(BlockDriverState *bs, bool locked)
26ba25
+{
26ba25
+    bdrv_lock_medium(bs->file->bs, locked);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+static bool cor_recurse_is_first_non_filter(BlockDriverState *bs,
26ba25
+                                            BlockDriverState *candidate)
26ba25
+{
26ba25
+    return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
26ba25
+}
26ba25
+
26ba25
+
26ba25
+BlockDriver bdrv_copy_on_read = {
26ba25
+    .format_name                        = "copy-on-read",
26ba25
+
26ba25
+    .bdrv_open                          = cor_open,
26ba25
+    .bdrv_close                         = cor_close,
26ba25
+    .bdrv_child_perm                    = cor_child_perm,
26ba25
+
26ba25
+    .bdrv_getlength                     = cor_getlength,
26ba25
+    .bdrv_truncate                      = cor_truncate,
26ba25
+
26ba25
+    .bdrv_co_preadv                     = cor_co_preadv,
26ba25
+    .bdrv_co_pwritev                    = cor_co_pwritev,
26ba25
+    .bdrv_co_pwrite_zeroes              = cor_co_pwrite_zeroes,
26ba25
+    .bdrv_co_pdiscard                   = cor_co_pdiscard,
26ba25
+
26ba25
+    .bdrv_eject                         = cor_eject,
26ba25
+    .bdrv_lock_medium                   = cor_lock_medium,
26ba25
+
26ba25
+    .bdrv_co_block_status               = bdrv_co_block_status_from_file,
26ba25
+
26ba25
+    .bdrv_recurse_is_first_non_filter   = cor_recurse_is_first_non_filter,
26ba25
+
26ba25
+    .has_variable_length                = true,
26ba25
+    .is_filter                          = true,
26ba25
+};
26ba25
+
26ba25
+static void bdrv_copy_on_read_init(void)
26ba25
+{
26ba25
+    bdrv_register(&bdrv_copy_on_read);
26ba25
+}
26ba25
+
26ba25
+block_init(bdrv_copy_on_read_init);
26ba25
diff --git a/qapi/block-core.json b/qapi/block-core.json
26ba25
index 51eafdd..9e4f1ac 100644
26ba25
--- a/qapi/block-core.json
26ba25
+++ b/qapi/block-core.json
26ba25
@@ -2506,11 +2506,12 @@
26ba25
 # @vxhs: Since 2.10
26ba25
 # @throttle: Since 2.11
26ba25
 # @nvme: Since 2.12
26ba25
+# @copy-on-read: Since 2.13
26ba25
 #
26ba25
 # Since: 2.9
26ba25
 ##
26ba25
 { 'enum': 'BlockdevDriver',
26ba25
-  'data': [ 'blkdebug', 'blkverify', 'bochs', 'cloop',
26ba25
+  'data': [ 'blkdebug', 'blkverify', 'bochs', 'cloop', 'copy-on-read',
26ba25
             'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom',
26ba25
             'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs',
26ba25
             'null-aio', 'null-co', 'nvme', 'parallels', 'qcow', 'qcow2', 'qed',
26ba25
@@ -3541,6 +3542,7 @@
26ba25
       'blkverify':  'BlockdevOptionsBlkverify',
26ba25
       'bochs':      'BlockdevOptionsGenericFormat',
26ba25
       'cloop':      'BlockdevOptionsGenericFormat',
26ba25
+      'copy-on-read':'BlockdevOptionsGenericFormat',
26ba25
       'dmg':        'BlockdevOptionsGenericFormat',
26ba25
       'file':       'BlockdevOptionsFile',
26ba25
       'ftp':        'BlockdevOptionsCurlFtp',
26ba25
@@ -4068,6 +4070,7 @@
26ba25
       'blkverify':      'BlockdevCreateNotSupported',
26ba25
       'bochs':          'BlockdevCreateNotSupported',
26ba25
       'cloop':          'BlockdevCreateNotSupported',
26ba25
+      'copy-on-read':   'BlockdevCreateNotSupported',
26ba25
       'dmg':            'BlockdevCreateNotSupported',
26ba25
       'file':           'BlockdevCreateOptionsFile',
26ba25
       'ftp':            'BlockdevCreateNotSupported',
26ba25
-- 
26ba25
1.8.3.1
26ba25