]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/pve/0018-PVE-block-add-the-zeroinit-block-driver-filter.patch
update submodule and patches for 4.2.0
[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: Tue, 10 Mar 2020 12:55:15 +0100
4 Subject: [PATCH 18/32] PVE: block: add the zeroinit block driver filter
5
6 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
7 ---
8 block/Makefile.objs | 1 +
9 block/zeroinit.c | 204 ++++++++++++++++++++++++++++++++++++++++++++
10 2 files changed, 205 insertions(+)
11 create mode 100644 block/zeroinit.c
12
13 diff --git a/block/Makefile.objs b/block/Makefile.objs
14 index e394fe0b6c..a10ceabf5b 100644
15 --- a/block/Makefile.objs
16 +++ b/block/Makefile.objs
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
19 block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
20 block-obj-y += quorum.o
21 +block-obj-y += zeroinit.o
22 block-obj-y += blkdebug.o blkverify.o blkreplay.o
23 block-obj-$(CONFIG_PARALLELS) += parallels.o
24 block-obj-y += blklogwrites.o
25 diff --git a/block/zeroinit.c b/block/zeroinit.c
26 new file mode 100644
27 index 0000000000..b74a78ece6
28 --- /dev/null
29 +++ b/block/zeroinit.c
30 @@ -0,0 +1,204 @@
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"
47 +#include "qemu/option.h"
48 +#include "qemu/module.h"
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",
110 + bs, &child_file, false, &local_err);
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 +
140 +static int coroutine_fn zeroinit_co_preadv(BlockDriverState *bs,
141 + uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
142 +{
143 + return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
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 +
155 +static int coroutine_fn zeroinit_co_pwritev(BlockDriverState *bs,
156 + uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
157 +{
158 + BDRVZeroinitState *s = bs->opaque;
159 + int64_t extents = offset + bytes;
160 + if (extents > s->extents)
161 + s->extents = extents;
162 + return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
163 +}
164 +
165 +static bool zeroinit_recurse_is_first_non_filter(BlockDriverState *bs,
166 + BlockDriverState *candidate)
167 +{
168 + return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
169 +}
170 +
171 +static coroutine_fn int zeroinit_co_flush(BlockDriverState *bs)
172 +{
173 + return bdrv_co_flush(bs->file->bs);
174 +}
175 +
176 +static int zeroinit_has_zero_init(BlockDriverState *bs)
177 +{
178 + BDRVZeroinitState *s = bs->opaque;
179 + return s->has_zero_init;
180 +}
181 +
182 +static int coroutine_fn zeroinit_co_pdiscard(BlockDriverState *bs,
183 + int64_t offset, int count)
184 +{
185 + return bdrv_co_pdiscard(bs->file, offset, count);
186 +}
187 +
188 +static int zeroinit_co_truncate(BlockDriverState *bs, int64_t offset,
189 + _Bool exact, PreallocMode prealloc, Error **errp)
190 +{
191 + return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
192 +}
193 +
194 +static int zeroinit_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
195 +{
196 + return bdrv_get_info(bs->file->bs, bdi);
197 +}
198 +
199 +static BlockDriver bdrv_zeroinit = {
200 + .format_name = "zeroinit",
201 + .protocol_name = "zeroinit",
202 + .instance_size = sizeof(BDRVZeroinitState),
203 +
204 + .bdrv_parse_filename = zeroinit_parse_filename,
205 + .bdrv_file_open = zeroinit_open,
206 + .bdrv_close = zeroinit_close,
207 + .bdrv_getlength = zeroinit_getlength,
208 + .bdrv_child_perm = bdrv_filter_default_perms,
209 + .bdrv_co_flush_to_disk = zeroinit_co_flush,
210 +
211 + .bdrv_co_pwrite_zeroes = zeroinit_co_pwrite_zeroes,
212 + .bdrv_co_pwritev = zeroinit_co_pwritev,
213 + .bdrv_co_preadv = zeroinit_co_preadv,
214 + .bdrv_co_flush = zeroinit_co_flush,
215 +
216 + .is_filter = true,
217 + .bdrv_recurse_is_first_non_filter = zeroinit_recurse_is_first_non_filter,
218 +
219 + .bdrv_has_zero_init = zeroinit_has_zero_init,
220 +
221 + .bdrv_co_block_status = bdrv_co_block_status_from_file,
222 +
223 + .bdrv_co_pdiscard = zeroinit_co_pdiscard,
224 +
225 + .bdrv_co_truncate = zeroinit_co_truncate,
226 + .bdrv_get_info = zeroinit_get_info,
227 +};
228 +
229 +static void bdrv_zeroinit_init(void)
230 +{
231 + bdrv_register(&bdrv_zeroinit);
232 +}
233 +
234 +block_init(bdrv_zeroinit_init);