The basic version of pcache driver for easy preparation of a patch set. Signed-off-by: Pavel Butsykin <pbutsy...@virtuozzo.com> --- block/Makefile.objs | 1 + block/pcache.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 block/pcache.c
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 <pbutsy...@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); -- 2.8.3