All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
	Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	qemu-devel@nongnu.org, Max Reitz <mreitz@redhat.com>
Subject: [PATCH v7 01/47] block: Add child access functions
Date: Thu, 25 Jun 2020 17:21:29 +0200	[thread overview]
Message-ID: <20200625152215.941773-2-mreitz@redhat.com> (raw)
In-Reply-To: <20200625152215.941773-1-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>
---
 include/block/block_int.h | 44 +++++++++++++++++--
 block.c                   | 90 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 131 insertions(+), 3 deletions(-)

diff --git a/include/block/block_int.h b/include/block/block_int.h
index 1b86b59af1..bb3457c5e8 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -90,9 +90,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;
     /*
@@ -1370,4 +1378,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 144f52e413..5a42ef49fd 100644
--- a/block.c
+++ b/block.c
@@ -6918,3 +6918,93 @@ 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;
+
+    QLIST_FOREACH(c, &bs->children, next) {
+        if (c->role & BDRV_CHILD_PRIMARY) {
+            return c;
+        }
+    }
+
+    return NULL;
+}
-- 
2.26.2



  reply	other threads:[~2020-06-25 15:24 UTC|newest]

Thread overview: 173+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-25 15:21 [PATCH v7 00/47] block: Deal with filters Max Reitz
2020-06-25 15:21 ` Max Reitz [this message]
2020-07-08 17:22   ` [PATCH v7 01/47] block: Add child access functions Andrey Shinkevich
2020-07-13  9:06   ` Vladimir Sementsov-Ogievskiy
2020-07-16 14:46     ` Max Reitz
2020-07-28 16:09     ` Christophe de Dinechin
2020-08-07  9:33       ` Vladimir Sementsov-Ogievskiy
2020-07-13  9:57   ` Vladimir Sementsov-Ogievskiy
2020-06-25 15:21 ` [PATCH v7 02/47] block: Add chain helper functions Max Reitz
2020-07-08 17:20   ` Andrey Shinkevich
2020-07-09  8:24     ` Max Reitz
2020-07-09  9:07       ` Andrey Shinkevich
2020-07-13 10:18   ` Vladimir Sementsov-Ogievskiy
2020-07-16 14:50     ` Max Reitz
2020-07-16 15:24       ` Vladimir Sementsov-Ogievskiy
2020-06-25 15:21 ` [PATCH v7 03/47] block: bdrv_cow_child() for bdrv_has_zero_init() Max Reitz
2020-07-08 17:23   ` Andrey Shinkevich
2020-08-07  9:37   ` Vladimir Sementsov-Ogievskiy
2020-06-25 15:21 ` [PATCH v7 04/47] block: bdrv_set_backing_hd() is about bs->backing Max Reitz
2020-07-08 17:24   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 05/47] block: Include filters when freezing backing chain Max Reitz
2020-07-08 17:25   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 06/47] block: Drop bdrv_is_encrypted() Max Reitz
2020-07-08 17:41   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 07/47] block: Add bdrv_supports_compressed_writes() Max Reitz
2020-07-08 17:48   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 08/47] throttle: Support compressed writes Max Reitz
2020-07-08 17:52   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 09/47] copy-on-read: " Max Reitz
2020-07-08 17:54   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 10/47] mirror-top: " Max Reitz
2020-07-08 17:58   ` Andrey Shinkevich
2020-08-18 10:27   ` Kevin Wolf
2020-08-19 15:35     ` Max Reitz
2020-08-19 16:00       ` Kevin Wolf
2020-06-25 15:21 ` [PATCH v7 11/47] backup-top: " Max Reitz
2020-07-08 17:59   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 12/47] block: Use bdrv_filter_(bs|child) where obvious Max Reitz
2020-07-08 18:24   ` Andrey Shinkevich
2020-07-09  8:59     ` Max Reitz
2020-07-09  9:11       ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 13/47] block: Use CAFs in block status functions Max Reitz
2020-07-08 19:13   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 14/47] stream: Deal with filters Max Reitz
2020-07-09 14:52   ` Andrey Shinkevich
2020-07-09 15:27     ` Andrey Shinkevich
2020-07-10 15:24     ` Max Reitz
2020-07-10 17:41       ` Andrey Shinkevich
2020-07-16 14:59         ` Max Reitz
2020-08-07 10:29           ` Vladimir Sementsov-Ogievskiy
2020-08-10  8:12             ` Max Reitz
2020-08-10 11:04               ` Vladimir Sementsov-Ogievskiy
2020-08-14 15:18                 ` Andrey Shinkevich
2020-08-18 20:45                 ` Andrey Shinkevich
2020-08-19 12:39                 ` Max Reitz
2020-08-19 13:18                   ` Vladimir Sementsov-Ogievskiy
2020-07-09 15:13   ` Andrey Shinkevich
2020-07-10 15:27     ` Max Reitz
2020-08-18 14:28   ` Kevin Wolf
2020-08-19 14:47     ` Max Reitz
2020-08-19 15:16       ` Kevin Wolf
2020-08-20  8:31         ` Max Reitz
2020-08-20  9:22           ` Max Reitz
2020-08-20 10:49             ` Vladimir Sementsov-Ogievskiy
2020-08-20 11:43               ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 15/47] block: Use CAFs when working with backing chains Max Reitz
2020-07-10 15:28   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 16/47] block: Use bdrv_cow_child() in bdrv_co_truncate() Max Reitz
2020-07-10 15:54   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 17/47] block: Re-evaluate backing file handling in reopen Max Reitz
2020-07-10 19:42   ` Andrey Shinkevich
2020-07-16 15:04     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 18/47] block: Flush all children in generic code Max Reitz
2020-07-14 12:52   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 19/47] vmdk: Drop vmdk_co_flush() Max Reitz
2020-07-14 14:52   ` Andrey Shinkevich
2020-07-16 15:08     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 20/47] block: Iterate over children in refresh_limits Max Reitz
2020-07-14 18:37   ` Andrey Shinkevich
2020-07-16 15:14     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 21/47] block: Use CAFs in bdrv_refresh_filename() Max Reitz
2020-07-15 12:52   ` Andrey Shinkevich
2020-07-15 12:58     ` Andrey Shinkevich
2020-07-16 15:21     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 22/47] block: Use CAF in bdrv_co_rw_vmstate() Max Reitz
2020-07-15 13:39   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 23/47] block/snapshot: Fix fallback Max Reitz
2020-07-15 21:22   ` Andrey Shinkevich
2020-07-15 22:18     ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 24/47] block: Use CAFs for debug breakpoints Max Reitz
2020-07-15 21:43   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 25/47] block: Def. impl.s for get_allocated_file_size Max Reitz
2020-07-15 22:56   ` Andrey Shinkevich
2020-08-19 10:57   ` Kevin Wolf
2020-08-19 15:53     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 26/47] block: Improve get_allocated_file_size's default Max Reitz
2020-07-20 15:12   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 27/47] blkverify: Use bdrv_sum_allocated_file_size() Max Reitz
2020-07-20 15:10   ` Andrey Shinkevich
2020-08-19 10:46   ` Kevin Wolf
2020-08-19 15:50     ` Max Reitz
2020-06-25 15:21 ` [PATCH v7 28/47] block/null: Implement bdrv_get_allocated_file_size Max Reitz
2020-07-20 15:10   ` Andrey Shinkevich
2020-07-24  8:58     ` Max Reitz
2020-07-24  9:49       ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 29/47] blockdev: Use CAF in external_snapshot_prepare() Max Reitz
2020-07-20 16:08   ` Andrey Shinkevich
2020-07-24  9:23     ` Max Reitz
2020-07-24 10:37       ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 30/47] block: Report data child for query-blockstats Max Reitz
2020-07-21 11:48   ` Andrey Shinkevich
2020-06-25 15:21 ` [PATCH v7 31/47] block: Use child access functions for QAPI queries Max Reitz
2020-07-21 12:30   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 32/47] block-copy: Use CAF to find sync=top base Max Reitz
2020-07-21 12:42   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 33/47] mirror: Deal with filters Max Reitz
2020-07-22 18:31   ` Andrey Shinkevich
2020-07-24  9:49     ` Max Reitz
2020-07-24 10:27       ` Andrey Shinkevich
2020-08-19 16:50   ` Kevin Wolf
2020-08-20 10:28     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 34/47] backup: " Max Reitz
2020-07-23 15:51   ` Andrey Shinkevich
2020-07-24  9:55     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 35/47] commit: " Max Reitz
2020-07-23 17:15   ` Andrey Shinkevich
2020-07-24 10:36     ` Andrey Shinkevich
2020-08-19 17:58   ` Kevin Wolf
2020-08-20 11:27     ` Max Reitz
2020-08-20 13:47       ` Kevin Wolf
2020-06-25 15:22 ` [PATCH v7 36/47] nbd: Use CAF when looking for dirty bitmap Max Reitz
2020-07-23 17:21   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 37/47] qemu-img: Use child access functions Max Reitz
2020-07-24 15:51   ` Andrey Shinkevich
2020-08-21 15:29   ` Kevin Wolf
2020-08-24 12:42     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 38/47] block: Drop backing_bs() Max Reitz
2020-07-24 15:55   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 39/47] blockdev: Fix active commit choice Max Reitz
2020-08-21 15:50   ` Kevin Wolf
2020-08-24 13:18     ` Max Reitz
2020-08-24 14:07       ` Kevin Wolf
2020-08-24 14:41         ` Max Reitz
2020-08-24 15:06           ` Kevin Wolf
2020-06-25 15:22 ` [PATCH v7 40/47] block: Inline bdrv_co_block_status_from_*() Max Reitz
2020-07-24 18:00   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 41/47] block: Leave BDS.backing_file constant Max Reitz
2020-07-27 12:27   ` Andrey Shinkevich
2020-07-28 14:10     ` Max Reitz
2020-08-24 13:14   ` Kevin Wolf
2020-08-24 14:29     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 42/47] iotests: Test that qcow2's data-file is flushed Max Reitz
2020-07-27 13:28   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 43/47] iotests: Let complete_and_wait() work with commit Max Reitz
2020-07-27 13:35   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 44/47] iotests: Add filter commit test cases Max Reitz
2020-07-27 17:45   ` Andrey Shinkevich
2020-07-28 14:00     ` Max Reitz
2020-06-25 15:22 ` [PATCH v7 45/47] iotests: Add filter mirror " Max Reitz
2020-08-02 11:05   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 46/47] iotests: Add test for commit in sub directory Max Reitz
2020-08-02 12:13   ` Andrey Shinkevich
2020-06-25 15:22 ` [PATCH v7 47/47] iotests: Test committing to overridden backing Max Reitz
2020-08-02 11:43   ` Andrey Shinkevich
2020-07-08 17:20 ` [PATCH v7 00/47] block: Deal with filters Andrey Shinkevich
2020-07-08 17:32   ` Eric Blake
2020-07-08 19:46     ` Andrey Shinkevich
2020-07-08 20:37       ` Eric Blake
2020-07-09  8:19         ` Max Reitz
2020-07-08 20:47   ` Eric Blake
2020-07-09  8:20     ` Max Reitz
2020-07-09  9:04       ` Andrey Shinkevich
2020-08-24 15:15 ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200625152215.941773-2-mreitz@redhat.com \
    --to=mreitz@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.