Subject: [PATCH] PVE: block: add the zeroinit block driver filter
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-[FE: adapt to changed function signatures]
+[FE: adapt to changed function signatures
+ adhere to block graph lock requirements]
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
block/meson.build | 1 +
- block/zeroinit.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 201 insertions(+)
+ block/zeroinit.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 215 insertions(+)
create mode 100644 block/zeroinit.c
diff --git a/block/meson.build b/block/meson.build
-index 529fc172c6..1833c71ce9 100644
+index 59ff6d380c..8ded0dc18b 100644
--- a/block/meson.build
+++ b/block/meson.build
-@@ -40,6 +40,7 @@ block_ss.add(files(
- 'throttle-groups.c',
+@@ -39,6 +39,7 @@ block_ss.add(files(
'throttle.c',
+ 'throttle-groups.c',
'write-threshold.c',
+ 'zeroinit.c',
), zstd, zlib, gnutls)
system_ss.add(when: 'CONFIG_TCG', if_true: files('blkreplay.c'))
diff --git a/block/zeroinit.c b/block/zeroinit.c
new file mode 100644
-index 0000000000..1257342724
+index 0000000000..1f2032bf99
--- /dev/null
+++ b/block/zeroinit.c
-@@ -0,0 +1,200 @@
+@@ -0,0 +1,214 @@
+/*
+ * Filter to fake a zero-initialized block device.
+ *
+#include "qapi/error.h"
+#include "block/block_int.h"
+#include "block/block-io.h"
++#include "block/graph-lock.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qstring.h"
+#include "qemu/cutils.h"
+ Error **errp)
+{
+ BDRVZeroinitState *s = bs->opaque;
++ BdrvChild *file = NULL;
+ QemuOpts *opts;
+ Error *local_err = NULL;
+ int ret;
+ }
+
+ /* Open the raw file */
-+ bs->file = bdrv_open_child(qemu_opt_get(opts, "x-next"), options, "next",
-+ bs, &child_of_bds,
-+ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
-+ false, &local_err);
++ file = bdrv_open_child(qemu_opt_get(opts, "x-next"), options, "next", bs,
++ &child_of_bds,
++ BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false,
++ &local_err);
++ bdrv_graph_wrlock(bs);
++ bs->file = file;
++ bdrv_graph_wrunlock(bs);
+ if (local_err) {
+ ret = -EINVAL;
+ error_propagate(errp, local_err);
+ ret = 0;
+fail:
+ if (ret < 0) {
++ bdrv_graph_wrlock(bs);
+ bdrv_unref_child(bs, bs->file);
++ bdrv_graph_wrunlock(bs);
+ }
+ qemu_opts_del(opts);
+ return ret;
+ (void)s;
+}
+
-+static coroutine_fn int64_t zeroinit_co_getlength(BlockDriverState *bs)
++static coroutine_fn int64_t GRAPH_RDLOCK
++zeroinit_co_getlength(BlockDriverState *bs)
+{
+ return bdrv_co_getlength(bs->file->bs);
+}
+
-+static int coroutine_fn zeroinit_co_preadv(BlockDriverState *bs,
-+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
++static int coroutine_fn GRAPH_RDLOCK
++zeroinit_co_preadv(BlockDriverState *bs, int64_t offset, int64_t bytes,
++ QEMUIOVector *qiov, BdrvRequestFlags flags)
+{
+ return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
+}
+
-+static int coroutine_fn zeroinit_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
-+ int64_t bytes, BdrvRequestFlags flags)
++static int coroutine_fn GRAPH_RDLOCK
++zeroinit_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes,
++ BdrvRequestFlags flags)
+{
+ BDRVZeroinitState *s = bs->opaque;
+ if (offset >= s->extents)
+ return bdrv_pwrite_zeroes(bs->file, offset, bytes, flags);
+}
+
-+static int coroutine_fn zeroinit_co_pwritev(BlockDriverState *bs,
-+ int64_t offset, int64_t bytes, QEMUIOVector *qiov, BdrvRequestFlags flags)
++static int coroutine_fn GRAPH_RDLOCK
++zeroinit_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes,
++ QEMUIOVector *qiov, BdrvRequestFlags flags)
+{
+ BDRVZeroinitState *s = bs->opaque;
+ int64_t extents = offset + bytes;
+ return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
+}
+
-+static coroutine_fn int zeroinit_co_flush(BlockDriverState *bs)
++static coroutine_fn int GRAPH_RDLOCK
++zeroinit_co_flush(BlockDriverState *bs)
+{
+ return bdrv_co_flush(bs->file->bs);
+}
+
-+static int zeroinit_has_zero_init(BlockDriverState *bs)
++static int GRAPH_RDLOCK
++zeroinit_has_zero_init(BlockDriverState *bs)
+{
+ BDRVZeroinitState *s = bs->opaque;
+ return s->has_zero_init;
+}
+
-+static int coroutine_fn zeroinit_co_pdiscard(BlockDriverState *bs,
-+ int64_t offset, int64_t bytes)
++static int coroutine_fn GRAPH_RDLOCK
++zeroinit_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes)
+{
+ return bdrv_co_pdiscard(bs->file, offset, bytes);
+}
+
-+static int zeroinit_co_truncate(BlockDriverState *bs, int64_t offset,
-+ _Bool exact, PreallocMode prealloc,
-+ BdrvRequestFlags req_flags, Error **errp)
++static int GRAPH_RDLOCK
++zeroinit_co_truncate(BlockDriverState *bs, int64_t offset, _Bool exact,
++ PreallocMode prealloc, BdrvRequestFlags req_flags,
++ Error **errp)
+{
+ return bdrv_co_truncate(bs->file, offset, exact, prealloc, req_flags, errp);
+}
+
-+static coroutine_fn int zeroinit_co_get_info(BlockDriverState *bs,
-+ BlockDriverInfo *bdi)
++static coroutine_fn int GRAPH_RDLOCK
++zeroinit_co_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+ return bdrv_co_get_info(bs->file->bs, bdi);
+}