[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 17/64] block: Add child access functions
From: |
Kevin Wolf |
Subject: |
[PULL 17/64] block: Add child access functions |
Date: |
Mon, 7 Sep 2020 13:08:49 +0200 |
From: Max Reitz <mreitz@redhat.com>
There are BDS children that the general block layer code can access,
namely bs->file and bs->backing. Since the introduction of filters and
external data files, their meaning is not quite clear. bs->backing can
be a COW source, or it can be a filtered child; bs->file can be a
filtered child, it can be data and metadata storage, or it can be just
metadata storage.
This overloading really is not helpful. This patch adds functions that
retrieve the correct child for each exact purpose. Later patches in
this series will make use of them. Doing so will allow us to handle
filter nodes in a meaningful way.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
include/block/block_int.h | 44 +++++++++++++++++--
block.c | 91 +++++++++++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+), 3 deletions(-)
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 9da7a42927..f280a95b26 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -92,9 +92,17 @@ struct BlockDriver {
int instance_size;
/* set to true if the BlockDriver is a block filter. Block filters pass
- * certain callbacks that refer to data (see block.c) to their bs->file if
- * the driver doesn't implement them. Drivers that do not wish to forward
- * must implement them and return -ENOTSUP.
+ * certain callbacks that refer to data (see block.c) to their bs->file
+ * or bs->backing (whichever one exists) if the driver doesn't implement
+ * them. Drivers that do not wish to forward must implement them and return
+ * -ENOTSUP.
+ * Note that filters are not allowed to modify data.
+ *
+ * Filters generally cannot have more than a single filtered child,
+ * because the data they present must at all times be the same as
+ * that on their filtered child. That would be impossible to
+ * achieve for multiple filtered children.
+ * (And this filtered child must then be bs->file or bs->backing.)
*/
bool is_filter;
/*
@@ -1382,4 +1390,34 @@ BdrvDirtyBitmap *block_dirty_bitmap_remove(const char
*node, const char *name,
BlockDriverState **bitmap_bs,
Error **errp);
+BdrvChild *bdrv_cow_child(BlockDriverState *bs);
+BdrvChild *bdrv_filter_child(BlockDriverState *bs);
+BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs);
+BdrvChild *bdrv_primary_child(BlockDriverState *bs);
+
+static inline BlockDriverState *child_bs(BdrvChild *child)
+{
+ return child ? child->bs : NULL;
+}
+
+static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs)
+{
+ return child_bs(bdrv_cow_child(bs));
+}
+
+static inline BlockDriverState *bdrv_filter_bs(BlockDriverState *bs)
+{
+ return child_bs(bdrv_filter_child(bs));
+}
+
+static inline BlockDriverState *bdrv_filter_or_cow_bs(BlockDriverState *bs)
+{
+ return child_bs(bdrv_filter_or_cow_child(bs));
+}
+
+static inline BlockDriverState *bdrv_primary_bs(BlockDriverState *bs)
+{
+ return child_bs(bdrv_primary_child(bs));
+}
+
#endif /* BLOCK_INT_H */
diff --git a/block.c b/block.c
index b204b93a2e..9f866e8676 100644
--- a/block.c
+++ b/block.c
@@ -6943,3 +6943,94 @@ int bdrv_make_empty(BdrvChild *c, Error **errp)
return 0;
}
+
+/*
+ * Return the child that @bs acts as an overlay for, and from which data may be
+ * copied in COW or COR operations. Usually this is the backing file.
+ */
+BdrvChild *bdrv_cow_child(BlockDriverState *bs)
+{
+ if (!bs || !bs->drv) {
+ return NULL;
+ }
+
+ if (bs->drv->is_filter) {
+ return NULL;
+ }
+
+ if (!bs->backing) {
+ return NULL;
+ }
+
+ assert(bs->backing->role & BDRV_CHILD_COW);
+ return bs->backing;
+}
+
+/*
+ * If @bs acts as a filter for exactly one of its children, return
+ * that child.
+ */
+BdrvChild *bdrv_filter_child(BlockDriverState *bs)
+{
+ BdrvChild *c;
+
+ if (!bs || !bs->drv) {
+ return NULL;
+ }
+
+ if (!bs->drv->is_filter) {
+ return NULL;
+ }
+
+ /* Only one of @backing or @file may be used */
+ assert(!(bs->backing && bs->file));
+
+ c = bs->backing ?: bs->file;
+ if (!c) {
+ return NULL;
+ }
+
+ assert(c->role & BDRV_CHILD_FILTERED);
+ return c;
+}
+
+/*
+ * Return either the result of bdrv_cow_child() or bdrv_filter_child(),
+ * whichever is non-NULL.
+ *
+ * Return NULL if both are NULL.
+ */
+BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs)
+{
+ BdrvChild *cow_child = bdrv_cow_child(bs);
+ BdrvChild *filter_child = bdrv_filter_child(bs);
+
+ /* Filter nodes cannot have COW backing files */
+ assert(!(cow_child && filter_child));
+
+ return cow_child ?: filter_child;
+}
+
+/*
+ * Return the primary child of this node: For filters, that is the
+ * filtered child. For other nodes, that is usually the child storing
+ * metadata.
+ * (A generally more helpful description is that this is (usually) the
+ * child that has the same filename as @bs.)
+ *
+ * Drivers do not necessarily have a primary child; for example quorum
+ * does not.
+ */
+BdrvChild *bdrv_primary_child(BlockDriverState *bs)
+{
+ BdrvChild *c, *found = NULL;
+
+ QLIST_FOREACH(c, &bs->children, next) {
+ if (c->role & BDRV_CHILD_PRIMARY) {
+ assert(!found);
+ found = c;
+ }
+ }
+
+ return found;
+}
--
2.25.4
- [PULL 07/64] block/nvme: Use common error path in nvme_add_io_queue(), (continued)
- [PULL 07/64] block/nvme: Use common error path in nvme_add_io_queue(), Kevin Wolf, 2020/09/07
- [PULL 05/64] block/nvme: Define INDEX macros to ease code review, Kevin Wolf, 2020/09/07
- [PULL 09/64] block/nvme: Use union of NvmeIdCtrl / NvmeIdNs structures, Kevin Wolf, 2020/09/07
- [PULL 10/64] block/nvme: Replace qemu_try_blockalign0 by qemu_try_blockalign/memset, Kevin Wolf, 2020/09/07
- [PULL 11/64] block/nvme: Replace qemu_try_blockalign(bs) by qemu_try_memalign(pg_sz), Kevin Wolf, 2020/09/07
- [PULL 12/64] block/nvme: Simplify nvme_init_queue() arguments, Kevin Wolf, 2020/09/07
- [PULL 13/64] block/nvme: Replace BDRV_POLL_WHILE by AIO_WAIT_WHILE, Kevin Wolf, 2020/09/07
- [PULL 08/64] block/nvme: Rename local variable, Kevin Wolf, 2020/09/07
- [PULL 14/64] block/nvme: Simplify nvme_create_queue_pair() arguments, Kevin Wolf, 2020/09/07
- [PULL 15/64] block/nvme: Extract nvme_poll_queue(), Kevin Wolf, 2020/09/07
- [PULL 17/64] block: Add child access functions,
Kevin Wolf <=
- [PULL 18/64] block: Add chain helper functions, Kevin Wolf, 2020/09/07
- [PULL 19/64] block: bdrv_cow_child() for bdrv_has_zero_init(), Kevin Wolf, 2020/09/07
- [PULL 16/64] block/nvme: Use an array of EventNotifier, Kevin Wolf, 2020/09/07
- [PULL 20/64] block: bdrv_set_backing_hd() is about bs->backing, Kevin Wolf, 2020/09/07
- [PULL 21/64] block: Include filters when freezing backing chain, Kevin Wolf, 2020/09/07
- [PULL 23/64] block: Add bdrv_supports_compressed_writes(), Kevin Wolf, 2020/09/07
- [PULL 24/64] throttle: Support compressed writes, Kevin Wolf, 2020/09/07
- [PULL 26/64] block: Use bdrv_filter_(bs|child) where obvious, Kevin Wolf, 2020/09/07
- [PULL 22/64] block: Drop bdrv_is_encrypted(), Kevin Wolf, 2020/09/07
- [PULL 27/64] block: Use CAFs in block status functions, Kevin Wolf, 2020/09/07