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