]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
update to QEMU 5.1
[pve-qemu.git] / debian / patches / pve / 0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
CommitLineData
23102ed6 1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
95259824 2From: Wolfgang Bumiller <w.bumiller@proxmox.com>
83faa3fe
TL
3Date: Mon, 6 Apr 2020 12:16:47 +0200
4Subject: [PATCH] PVE: block: add the zeroinit block driver filter
95259824 5
b855dce7 6Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
95259824
WB
7---
8 block/Makefile.objs | 1 +
60ae3775
SR
9 block/zeroinit.c | 198 ++++++++++++++++++++++++++++++++++++++++++++
10 2 files changed, 199 insertions(+)
95259824
WB
11 create mode 100644 block/zeroinit.c
12
13diff --git a/block/Makefile.objs b/block/Makefile.objs
60ae3775 14index 19c6f371c9..d1a9227b8f 100644
95259824
WB
15--- a/block/Makefile.objs
16+++ b/block/Makefile.objs
b855dce7
TL
17@@ -11,6 +11,7 @@ block-obj-$(CONFIG_QED) += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
18 block-obj-$(CONFIG_QED) += qed-check.o
a544966d 19 block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
95259824
WB
20 block-obj-y += quorum.o
21+block-obj-y += zeroinit.o
b855dce7
TL
22 block-obj-y += blkdebug.o blkverify.o blkreplay.o
23 block-obj-$(CONFIG_PARALLELS) += parallels.o
53e83913 24 block-obj-y += blklogwrites.o
95259824
WB
25diff --git a/block/zeroinit.c b/block/zeroinit.c
26new file mode 100644
60ae3775 27index 0000000000..4fbb80eab0
95259824
WB
28--- /dev/null
29+++ b/block/zeroinit.c
60ae3775 30@@ -0,0 +1,198 @@
95259824
WB
31+/*
32+ * Filter to fake a zero-initialized block device.
33+ *
34+ * Copyright (c) 2016 Wolfgang Bumiller <w.bumiller@proxmox.com>
35+ * Copyright (c) 2016 Proxmox Server Solutions GmbH
36+ *
37+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
38+ * See the COPYING file in the top-level directory.
39+ */
40+
41+#include "qemu/osdep.h"
42+#include "qapi/error.h"
43+#include "block/block_int.h"
44+#include "qapi/qmp/qdict.h"
45+#include "qapi/qmp/qstring.h"
46+#include "qemu/cutils.h"
53e83913 47+#include "qemu/option.h"
be901f66 48+#include "qemu/module.h"
95259824
WB
49+
50+typedef struct {
51+ bool has_zero_init;
52+ int64_t extents;
53+} BDRVZeroinitState;
54+
55+/* Valid blkverify filenames look like blkverify:path/to/raw_image:path/to/image */
56+static void zeroinit_parse_filename(const char *filename, QDict *options,
57+ Error **errp)
58+{
59+ QString *raw_path;
60+
61+ /* Parse the blkverify: prefix */
62+ if (!strstart(filename, "zeroinit:", &filename)) {
63+ /* There was no prefix; therefore, all options have to be already
64+ present in the QDict (except for the filename) */
65+ return;
66+ }
67+
68+ raw_path = qstring_from_str(filename);
69+ qdict_put(options, "x-next", raw_path);
70+}
71+
72+static QemuOptsList runtime_opts = {
73+ .name = "zeroinit",
74+ .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
75+ .desc = {
76+ {
77+ .name = "x-next",
78+ .type = QEMU_OPT_STRING,
79+ .help = "[internal use only, will be removed]",
80+ },
81+ {
82+ .name = "x-zeroinit",
83+ .type = QEMU_OPT_BOOL,
84+ .help = "set has_initialized_zero flag",
85+ },
86+ { /* end of list */ }
87+ },
88+};
89+
90+static int zeroinit_open(BlockDriverState *bs, QDict *options, int flags,
91+ Error **errp)
92+{
93+ BDRVZeroinitState *s = bs->opaque;
94+ QemuOpts *opts;
95+ Error *local_err = NULL;
96+ int ret;
97+
98+ s->extents = 0;
99+
100+ opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
101+ qemu_opts_absorb_qdict(opts, options, &local_err);
102+ if (local_err) {
103+ error_propagate(errp, local_err);
104+ ret = -EINVAL;
105+ goto fail;
106+ }
107+
108+ /* Open the raw file */
109+ bs->file = bdrv_open_child(qemu_opt_get(opts, "x-next"), options, "next",
60ae3775 110+ bs, &child_of_bds, BDRV_CHILD_FILTERED, false, &local_err);
95259824
WB
111+ if (local_err) {
112+ ret = -EINVAL;
113+ error_propagate(errp, local_err);
114+ goto fail;
115+ }
116+
117+ /* set the options */
118+ s->has_zero_init = qemu_opt_get_bool(opts, "x-zeroinit", true);
119+
120+ ret = 0;
121+fail:
122+ if (ret < 0) {
123+ bdrv_unref_child(bs, bs->file);
124+ }
125+ qemu_opts_del(opts);
126+ return ret;
127+}
128+
129+static void zeroinit_close(BlockDriverState *bs)
130+{
131+ BDRVZeroinitState *s = bs->opaque;
132+ (void)s;
133+}
134+
135+static int64_t zeroinit_getlength(BlockDriverState *bs)
136+{
137+ return bdrv_getlength(bs->file->bs);
138+}
139+
6838f038
WB
140+static int coroutine_fn zeroinit_co_preadv(BlockDriverState *bs,
141+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
95259824 142+{
6838f038 143+ return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
95259824
WB
144+}
145+
146+static int coroutine_fn zeroinit_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
147+ int count, BdrvRequestFlags flags)
148+{
149+ BDRVZeroinitState *s = bs->opaque;
150+ if (offset >= s->extents)
151+ return 0;
152+ return bdrv_pwrite_zeroes(bs->file, offset, count, flags);
153+}
154+
6838f038
WB
155+static int coroutine_fn zeroinit_co_pwritev(BlockDriverState *bs,
156+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
95259824
WB
157+{
158+ BDRVZeroinitState *s = bs->opaque;
6838f038 159+ int64_t extents = offset + bytes;
95259824
WB
160+ if (extents > s->extents)
161+ s->extents = extents;
6838f038 162+ return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
95259824
WB
163+}
164+
95259824
WB
165+static coroutine_fn int zeroinit_co_flush(BlockDriverState *bs)
166+{
167+ return bdrv_co_flush(bs->file->bs);
168+}
169+
170+static int zeroinit_has_zero_init(BlockDriverState *bs)
171+{
172+ BDRVZeroinitState *s = bs->opaque;
173+ return s->has_zero_init;
174+}
175+
a544966d
WB
176+static int coroutine_fn zeroinit_co_pdiscard(BlockDriverState *bs,
177+ int64_t offset, int count)
95259824 178+{
53e83913 179+ return bdrv_co_pdiscard(bs->file, offset, count);
95259824
WB
180+}
181+
53e83913 182+static int zeroinit_co_truncate(BlockDriverState *bs, int64_t offset,
60ae3775
SR
183+ _Bool exact, PreallocMode prealloc,
184+ BdrvRequestFlags req_flags, Error **errp)
95259824 185+{
60ae3775 186+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, req_flags, errp);
95259824
WB
187+}
188+
189+static int zeroinit_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
190+{
191+ return bdrv_get_info(bs->file->bs, bdi);
192+}
193+
194+static BlockDriver bdrv_zeroinit = {
195+ .format_name = "zeroinit",
196+ .protocol_name = "zeroinit",
197+ .instance_size = sizeof(BDRVZeroinitState),
198+
199+ .bdrv_parse_filename = zeroinit_parse_filename,
200+ .bdrv_file_open = zeroinit_open,
201+ .bdrv_close = zeroinit_close,
202+ .bdrv_getlength = zeroinit_getlength,
60ae3775 203+ .bdrv_child_perm = bdrv_default_perms,
95259824
WB
204+ .bdrv_co_flush_to_disk = zeroinit_co_flush,
205+
206+ .bdrv_co_pwrite_zeroes = zeroinit_co_pwrite_zeroes,
6838f038
WB
207+ .bdrv_co_pwritev = zeroinit_co_pwritev,
208+ .bdrv_co_preadv = zeroinit_co_preadv,
209+ .bdrv_co_flush = zeroinit_co_flush,
95259824
WB
210+
211+ .is_filter = true,
95259824 212+
53e83913 213+ .bdrv_has_zero_init = zeroinit_has_zero_init,
95259824 214+
53e83913 215+ .bdrv_co_block_status = bdrv_co_block_status_from_file,
95259824 216+
53e83913 217+ .bdrv_co_pdiscard = zeroinit_co_pdiscard,
95259824 218+
53e83913
WB
219+ .bdrv_co_truncate = zeroinit_co_truncate,
220+ .bdrv_get_info = zeroinit_get_info,
95259824
WB
221+};
222+
223+static void bdrv_zeroinit_init(void)
224+{
225+ bdrv_register(&bdrv_zeroinit);
226+}
227+
228+block_init(bdrv_zeroinit_init);