diff mbox

[RFC,v2,01/22] block/pcache: empty pcache driver filter

Message ID 20160829171021.4902-2-pbutsykin@virtuozzo.com (mailing list archive)
State New, archived
Headers show

Commit Message

Pavel Butsykin Aug. 29, 2016, 5:10 p.m. UTC
The basic version of pcache driver for easy preparation of a patch set.

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
 block/Makefile.objs |   1 +
 block/pcache.c      | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+)
 create mode 100644 block/pcache.c

Comments

Kevin Wolf Sept. 1, 2016, 2:31 p.m. UTC | #1
Am 29.08.2016 um 19:10 hat Pavel Butsykin geschrieben:
> The basic version of pcache driver for easy preparation of a patch set.
> 
> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>

> +    .bdrv_aio_readv                     = pcache_aio_readv,
> +    .bdrv_aio_writev                    = pcache_aio_writev,

Can you please use .bdrv_co_preadv/pwritev instead and make everything
based on bytes rather than sectors?

Internally you can still spawn AIO requests to achieve the same
parallelism as you have now (we'll just need new byte-based
bdrv_co_aio_prw_vector() wrappers, but the functionality is there) and I
don't think making the outer layer coroutine based would be too hard. In
fact it might even simplify some code.

Kevin
Pavel Butsykin Sept. 6, 2016, 3:20 p.m. UTC | #2
On 01.09.2016 17:31, Kevin Wolf wrote:
> Am 29.08.2016 um 19:10 hat Pavel Butsykin geschrieben:
>> The basic version of pcache driver for easy preparation of a patch set.
>>
>> Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
>
>> +    .bdrv_aio_readv                     = pcache_aio_readv,
>> +    .bdrv_aio_writev                    = pcache_aio_writev,
>
> Can you please use .bdrv_co_preadv/pwritev instead and make everything
> based on bytes rather than sectors?
>
> Internally you can still spawn AIO requests to achieve the same
> parallelism as you have now (we'll just need new byte-based
> bdrv_co_aio_prw_vector() wrappers, but the functionality is there) and I
> don't think making the outer layer coroutine based would be too hard. In
> fact it might even simplify some code.
>
Of course, I just wrote pcache when new byte-based interfaces have not
yet been implemented.

> Kevin
>
diff mbox

Patch

diff --git a/block/Makefile.objs b/block/Makefile.objs
index 2593a2f..7c588ac 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -4,6 +4,7 @@  block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
 block-obj-y += qed-check.o
 block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
 block-obj-y += quorum.o
+block-obj-y += pcache.o
 block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o
 block-obj-y += block-backend.o snapshot.o qapi.o
 block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
diff --git a/block/pcache.c b/block/pcache.c
new file mode 100644
index 0000000..770bbc0
--- /dev/null
+++ b/block/pcache.c
@@ -0,0 +1,156 @@ 
+/*
+ * Prefetch cache driver filter
+ *
+ * Copyright (c) 2016 Pavel Butsykin <pbutsykin@virtuozzo.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "block/block_int.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qstring.h"
+
+
+static const AIOCBInfo pcache_aiocb_info = {
+    .aiocb_size = sizeof(BlockAIOCB),
+};
+
+static QemuOptsList runtime_opts = {
+    .name = "pcache",
+    .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
+    .desc = {
+        {
+            .name = "x-image",
+            .type = QEMU_OPT_STRING,
+            .help = "[internal use only, will be removed]",
+        },
+        { /* end of list */ }
+    },
+};
+
+static void pcache_aio_cb(void *opaque, int ret)
+{
+
+    BlockAIOCB *acb = opaque;
+
+    acb->cb(acb->opaque, ret);
+
+    qemu_aio_unref(acb);
+}
+
+static BlockAIOCB *pcache_aio_readv(BlockDriverState *bs,
+                                    int64_t sector_num,
+                                    QEMUIOVector *qiov,
+                                    int nb_sectors,
+                                    BlockCompletionFunc *cb,
+                                    void *opaque)
+{
+    BlockAIOCB *acb = qemu_aio_get(&pcache_aiocb_info, bs, cb, opaque);
+
+    bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors,
+                   pcache_aio_cb, acb);
+    return acb;
+}
+
+static BlockAIOCB *pcache_aio_writev(BlockDriverState *bs,
+                                     int64_t sector_num,
+                                     QEMUIOVector *qiov,
+                                     int nb_sectors,
+                                     BlockCompletionFunc *cb,
+                                     void *opaque)
+{
+    BlockAIOCB *acb = qemu_aio_get(&pcache_aiocb_info, bs, cb, opaque);
+
+    bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors,
+                    pcache_aio_cb, acb);
+    return acb;
+}
+
+static int pcache_file_open(BlockDriverState *bs, QDict *options, int flags,
+                            Error **errp)
+{
+    QemuOpts *opts;
+    Error *local_err = NULL;
+    int ret = 0;
+
+    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
+    qemu_opts_absorb_qdict(opts, options, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        ret = -EINVAL;
+        goto fail;
+    }
+
+    assert(bs->file == NULL);
+    bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options,
+                               "image", bs, &child_format, false, &local_err);
+    if (local_err) {
+        ret = -EINVAL;
+        error_propagate(errp, local_err);
+    }
+fail:
+    qemu_opts_del(opts);
+    return ret;
+}
+
+static void pcache_close(BlockDriverState *bs)
+{
+}
+
+static void pcache_parse_filename(const char *filename, QDict *options,
+                                  Error **errp)
+{
+    qdict_put(options, "x-image", qstring_from_str(filename));
+}
+
+static int64_t pcache_getlength(BlockDriverState *bs)
+{
+    return bdrv_getlength(bs->file->bs);
+}
+
+static bool pcache_recurse_is_first_non_filter(BlockDriverState *bs,
+                                               BlockDriverState *candidate)
+{
+    return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
+}
+
+static BlockDriver bdrv_pcache = {
+    .format_name                        = "pcache",
+    .protocol_name                      = "pcache",
+    .instance_size                      = 0,
+
+    .bdrv_parse_filename                = pcache_parse_filename,
+    .bdrv_file_open                     = pcache_file_open,
+    .bdrv_close                         = pcache_close,
+    .bdrv_getlength                     = pcache_getlength,
+
+    .bdrv_aio_readv                     = pcache_aio_readv,
+    .bdrv_aio_writev                    = pcache_aio_writev,
+
+    .is_filter                          = true,
+    .bdrv_recurse_is_first_non_filter   = pcache_recurse_is_first_non_filter,
+};
+
+static void bdrv_cache_init(void)
+{
+    bdrv_register(&bdrv_pcache);
+}
+
+block_init(bdrv_cache_init);