]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/pve/0019-PVE-block-add-the-zeroinit-block-driver-filter.patch
merge: make file locking optional also on creation
[pve-qemu.git] / debian / patches / pve / 0019-PVE-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
53e83913 4Subject: [PATCH] PVE: block: add the zeroinit block driver filter
95259824
WB
5
6---
7 block/Makefile.objs | 1 +
53e83913
WB
8 block/zeroinit.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++
9 2 files changed, 204 insertions(+)
95259824
WB
10 create mode 100644 block/zeroinit.c
11
12diff --git a/block/Makefile.objs b/block/Makefile.objs
53e83913 13index c8337bf186..c00f0b32d6 100644
95259824
WB
14--- a/block/Makefile.objs
15+++ b/block/Makefile.objs
6838f038 16@@ -4,6 +4,7 @@ block-obj-y += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
95259824 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
53e83913 22 block-obj-y += blklogwrites.o
95259824 23 block-obj-y += block-backend.o snapshot.o qapi.o
95259824
WB
24diff --git a/block/zeroinit.c b/block/zeroinit.c
25new file mode 100644
53e83913 26index 0000000000..64c49ad0e0
95259824
WB
27--- /dev/null
28+++ b/block/zeroinit.c
53e83913 29@@ -0,0 +1,203 @@
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"
53e83913 46+#include "qemu/option.h"
95259824
WB
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+
6838f038
WB
138+static int coroutine_fn zeroinit_co_preadv(BlockDriverState *bs,
139+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
95259824 140+{
6838f038 141+ return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
95259824
WB
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+
6838f038
WB
153+static int coroutine_fn zeroinit_co_pwritev(BlockDriverState *bs,
154+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
95259824
WB
155+{
156+ BDRVZeroinitState *s = bs->opaque;
6838f038 157+ int64_t extents = offset + bytes;
95259824
WB
158+ if (extents > s->extents)
159+ s->extents = extents;
6838f038 160+ return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
95259824
WB
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+
a544966d
WB
180+static int coroutine_fn zeroinit_co_pdiscard(BlockDriverState *bs,
181+ int64_t offset, int count)
95259824 182+{
53e83913 183+ return bdrv_co_pdiscard(bs->file, offset, count);
95259824
WB
184+}
185+
53e83913 186+static int zeroinit_co_truncate(BlockDriverState *bs, int64_t offset,
6838f038 187+ PreallocMode prealloc, Error **errp)
95259824 188+{
53e83913 189+ return bdrv_co_truncate(bs->file, offset, prealloc, errp);
95259824
WB
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,
67af0fa4 206+ .bdrv_child_perm = bdrv_filter_default_perms,
95259824
WB
207+ .bdrv_co_flush_to_disk = zeroinit_co_flush,
208+
209+ .bdrv_co_pwrite_zeroes = zeroinit_co_pwrite_zeroes,
6838f038
WB
210+ .bdrv_co_pwritev = zeroinit_co_pwritev,
211+ .bdrv_co_preadv = zeroinit_co_preadv,
212+ .bdrv_co_flush = zeroinit_co_flush,
95259824
WB
213+
214+ .is_filter = true,
215+ .bdrv_recurse_is_first_non_filter = zeroinit_recurse_is_first_non_filter,
216+
53e83913 217+ .bdrv_has_zero_init = zeroinit_has_zero_init,
95259824 218+
53e83913 219+ .bdrv_co_block_status = bdrv_co_block_status_from_file,
95259824 220+
53e83913 221+ .bdrv_co_pdiscard = zeroinit_co_pdiscard,
95259824 222+
53e83913
WB
223+ .bdrv_co_truncate = zeroinit_co_truncate,
224+ .bdrv_get_info = zeroinit_get_info,
95259824
WB
225+};
226+
227+static void bdrv_zeroinit_init(void)
228+{
229+ bdrv_register(&bdrv_zeroinit);
230+}
231+
232+block_init(bdrv_zeroinit_init);
233--
45169293 2342.11.0
95259824 235