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