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