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