]> git.proxmox.com Git - pve-qemu-kvm.git/blame - debian/patches/pve/0044-block-add-the-zeroinit-block-driver-filter.patch
bump version to 2.6.2-2
[pve-qemu-kvm.git] / debian / patches / pve / 0044-block-add-the-zeroinit-block-driver-filter.patch
CommitLineData
6fb04df7 1From b3bf300710e38fd4692f0d761c75f4ba3a7edd7e Mon Sep 17 00:00:00 2001
cb3ba970
WB
2From: Wolfgang Bumiller <w.bumiller@proxmox.com>
3Date: Thu, 17 Mar 2016 11:33:37 +0100
6fb04df7 4Subject: [PATCH 44/55] block: add the zeroinit block driver filter
cb3ba970
WB
5
6---
7 block/Makefile.objs | 1 +
8 block/zeroinit.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++
9 2 files changed, 217 insertions(+)
10 create mode 100644 block/zeroinit.c
11
12diff --git a/block/Makefile.objs b/block/Makefile.objs
6fb04df7 13index 44a5416..9e2cdbc 100644
cb3ba970
WB
14--- a/block/Makefile.objs
15+++ b/block/Makefile.objs
16@@ -4,6 +4,7 @@ block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
17 block-obj-y += qed-check.o
18 block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
19 block-obj-y += quorum.o
20+block-obj-y += zeroinit.o
b07d35a5 21 block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o
cb3ba970
WB
22 block-obj-y += block-backend.o snapshot.o qapi.o
23 block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
24diff --git a/block/zeroinit.c b/block/zeroinit.c
25new file mode 100644
26index 0000000..04a9bd0
27--- /dev/null
28+++ b/block/zeroinit.c
29@@ -0,0 +1,216 @@
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 "block/block_int.h"
41+#include "qapi/qmp/qdict.h"
42+#include "qapi/qmp/qstring.h"
43+
44+typedef struct {
45+ bool has_zero_init;
46+ int64_t extents;
47+} BDRVZeroinitState;
48+
49+/* Valid blkverify filenames look like blkverify:path/to/raw_image:path/to/image */
50+static void zeroinit_parse_filename(const char *filename, QDict *options,
51+ Error **errp)
52+{
53+ QString *raw_path;
54+
55+ /* Parse the blkverify: prefix */
56+ if (!strstart(filename, "zeroinit:", &filename)) {
57+ /* There was no prefix; therefore, all options have to be already
58+ present in the QDict (except for the filename) */
59+ return;
60+ }
61+
62+ raw_path = qstring_from_str(filename);
63+ qdict_put(options, "x-next", raw_path);
64+}
65+
66+static QemuOptsList runtime_opts = {
67+ .name = "zeroinit",
68+ .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
69+ .desc = {
70+ {
71+ .name = "x-next",
72+ .type = QEMU_OPT_STRING,
73+ .help = "[internal use only, will be removed]",
74+ },
75+ {
76+ .name = "x-zeroinit",
77+ .type = QEMU_OPT_BOOL,
78+ .help = "set has_initialized_zero flag",
79+ },
80+ { /* end of list */ }
81+ },
82+};
83+
84+static int zeroinit_open(BlockDriverState *bs, QDict *options, int flags,
85+ Error **errp)
86+{
87+ BDRVZeroinitState *s = bs->opaque;
88+ QemuOpts *opts;
89+ Error *local_err = NULL;
90+ int ret;
91+
92+ s->extents = 0;
93+
94+ opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
95+ qemu_opts_absorb_qdict(opts, options, &local_err);
96+ if (local_err) {
97+ error_propagate(errp, local_err);
98+ ret = -EINVAL;
99+ goto fail;
100+ }
101+
102+ /* Open the raw file */
103+ bs->file = bdrv_open_child(qemu_opt_get(opts, "x-next"), options, "next",
104+ bs, &child_file, false, &local_err);
105+ if (local_err) {
106+ ret = -EINVAL;
107+ error_propagate(errp, local_err);
108+ goto fail;
109+ }
110+
111+ /* set the options */
112+ s->has_zero_init = qemu_opt_get_bool(opts, "x-zeroinit", true);
113+
114+ ret = 0;
115+fail:
116+ if (ret < 0) {
117+ bdrv_unref_child(bs, bs->file);
118+ }
119+ qemu_opts_del(opts);
120+ return ret;
121+}
122+
123+static void zeroinit_close(BlockDriverState *bs)
124+{
125+ BDRVZeroinitState *s = bs->opaque;
126+ (void)s;
127+}
128+
129+static int64_t zeroinit_getlength(BlockDriverState *bs)
130+{
131+ return bdrv_getlength(bs->file->bs);
132+}
133+
134+static BlockAIOCB *zeroinit_aio_readv(BlockDriverState *bs,
135+ int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
136+ BlockCompletionFunc *cb, void *opaque)
137+{
138+ return bdrv_aio_readv(bs->file->bs, sector_num, qiov, nb_sectors,
139+ cb, opaque);
140+}
141+
142+static int coroutine_fn zeroinit_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
143+ int nb_sectors, BdrvRequestFlags flags)
144+{
145+ BDRVZeroinitState *s = bs->opaque;
146+ if (sector_num >= s->extents)
147+ return 0;
148+ return bdrv_write_zeroes(bs->file->bs, sector_num, nb_sectors, flags);
149+}
150+
151+static BlockAIOCB *zeroinit_aio_writev(BlockDriverState *bs,
152+ int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
153+ BlockCompletionFunc *cb, void *opaque)
154+{
155+ BDRVZeroinitState *s = bs->opaque;
156+ int64_t extents = sector_num + nb_sectors + 1;
157+ if (extents > s->extents)
158+ s->extents = extents;
159+ return bdrv_aio_writev(bs->file->bs, sector_num, qiov, nb_sectors,
160+ cb, opaque);
161+}
162+
163+static BlockAIOCB *zeroinit_aio_flush(BlockDriverState *bs,
164+ BlockCompletionFunc *cb,
165+ void *opaque)
166+{
167+ return bdrv_aio_flush(bs->file->bs, cb, opaque);
168+}
169+
170+static bool zeroinit_recurse_is_first_non_filter(BlockDriverState *bs,
171+ BlockDriverState *candidate)
172+{
173+ return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate);
174+}
175+
176+static coroutine_fn int zeroinit_co_flush(BlockDriverState *bs)
177+{
178+ return bdrv_co_flush(bs->file->bs);
179+}
180+
181+static int zeroinit_has_zero_init(BlockDriverState *bs)
182+{
183+ BDRVZeroinitState *s = bs->opaque;
184+ return s->has_zero_init;
185+}
186+
187+static int64_t coroutine_fn zeroinit_co_get_block_status(BlockDriverState *bs,
188+ int64_t sector_num,
189+ int nb_sectors, int *pnum)
190+{
191+ return bdrv_get_block_status(bs->file->bs, sector_num, nb_sectors, pnum);
192+}
193+
194+static coroutine_fn BlockAIOCB *zeroinit_aio_discard(BlockDriverState *bs,
195+ int64_t sector_num, int nb_sectors,
196+ BlockCompletionFunc *cb, void *opaque)
197+{
198+ return bdrv_aio_discard(bs->file->bs, sector_num, nb_sectors, cb, opaque);
199+}
200+
201+static int zeroinit_truncate(BlockDriverState *bs, int64_t offset)
202+{
203+ return bdrv_truncate(bs->file->bs, offset);
204+}
205+
206+static int zeroinit_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
207+{
208+ return bdrv_get_info(bs->file->bs, bdi);
209+}
210+
211+static BlockDriver bdrv_zeroinit = {
212+ .format_name = "zeroinit",
213+ .protocol_name = "zeroinit",
214+ .instance_size = sizeof(BDRVZeroinitState),
215+
216+ .bdrv_parse_filename = zeroinit_parse_filename,
217+ .bdrv_file_open = zeroinit_open,
218+ .bdrv_close = zeroinit_close,
219+ .bdrv_getlength = zeroinit_getlength,
220+ .bdrv_co_flush_to_disk = zeroinit_co_flush,
221+
222+ .bdrv_co_write_zeroes = zeroinit_co_write_zeroes,
223+ .bdrv_aio_writev = zeroinit_aio_writev,
224+ .bdrv_aio_readv = zeroinit_aio_readv,
225+ .bdrv_aio_flush = zeroinit_aio_flush,
226+
227+ .is_filter = true,
228+ .bdrv_recurse_is_first_non_filter = zeroinit_recurse_is_first_non_filter,
229+
230+ .bdrv_has_zero_init = zeroinit_has_zero_init,
231+
232+ .bdrv_co_get_block_status = zeroinit_co_get_block_status,
233+
234+ .bdrv_aio_discard = zeroinit_aio_discard,
235+
236+ .bdrv_truncate = zeroinit_truncate,
237+ .bdrv_get_info = zeroinit_get_info,
238+};
239+
240+static void bdrv_zeroinit_init(void)
241+{
242+ bdrv_register(&bdrv_zeroinit);
243+}
244+
245+block_init(bdrv_zeroinit_init);
246--
2472.1.4
248