diff mbox series

[v2,22/33] block: Make backing files child_of_bds children

Message ID 20200204170848.614480-23-mreitz@redhat.com (mailing list archive)
State New, archived
Headers show
Series block: Introduce real BdrvChildRole | expand

Commit Message

Max Reitz Feb. 4, 2020, 5:08 p.m. UTC
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c                 | 26 ++++++++++++++++++++------
 block/backup-top.c      |  2 +-
 block/vvfat.c           |  3 ++-
 tests/test-bdrv-drain.c | 13 +++++++------
 4 files changed, 30 insertions(+), 14 deletions(-)

Comments

Eric Blake Feb. 5, 2020, 10:45 p.m. UTC | #1
On 2/4/20 11:08 AM, Max Reitz wrote:
> Signed-off-by: Max Reitz <mreitz@redhat.com>

Another sparse commit message (a recurring theme of this series). The 
subject line says 'what', and the patch appears to be faithful to that, 
but if a future bisection lands here, even a one-sentence 'why' would be 
handy; maybe:

This is part of a larger series of unifying block device relationships 
via child_of_bds.

to at least hint that searching nearby commits gives a better why.

> ---
>   block.c                 | 26 ++++++++++++++++++++------
>   block/backup-top.c      |  2 +-
>   block/vvfat.c           |  3 ++-
>   tests/test-bdrv-drain.c | 13 +++++++------
>   4 files changed, 30 insertions(+), 14 deletions(-)
> 
> diff --git a/block.c b/block.c
> index 77755f0c6c..6b705ee23a 100644
> --- a/block.c
> +++ b/block.c
> @@ -2748,6 +2748,20 @@ static bool bdrv_inherits_from_recursive(BlockDriverState *child,
>       return child != NULL;
>   }
>   
> +/*
> + * Return the BdrvChildRole for @bs's backing child.  bs->backing is
> + * mostly used for COW backing children (role = COW), but also for
> + * filtered children (role = FILTERED | PRIMARY).
> + */
> +static BdrvChildRole bdrv_backing_role(BlockDriverState *bs)
> +{
> +    if (bs->drv && bs->drv->is_filter) {
> +        return BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY;

And here's the first point (that I've spotted at least) in this series 
where you are definitely returning a non-BdrvChildRole through a return 
type of BdrvChildRole, rather than me just guessing you might (the 
integer formed by bitwise-or of two enum values is not itself an enum 
value).  Repeating what I said earlier, the C language is loose enough 
to allow your usage, and your usage is somewhat better self-documenting 
than using an unsigned int; but it would not fly in other languages.

So I won't insist you change it, but at least think about it. (And the 
latter has already happened if you read my paragraph - so can we call 
that enough thought on the matter? ;)

> +    } else {
> +        return BDRV_CHILD_COW;
> +    }
> +}
> +
Reviewed-by: Eric Blake <eblake@redhat.com>
Max Reitz Feb. 6, 2020, 11:33 a.m. UTC | #2
On 05.02.20 23:45, Eric Blake wrote:
> On 2/4/20 11:08 AM, Max Reitz wrote:
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
> 
> Another sparse commit message (a recurring theme of this series). The
> subject line says 'what', and the patch appears to be faithful to that,
> but if a future bisection lands here, even a one-sentence 'why' would be
> handy; maybe:
> 
> This is part of a larger series of unifying block device relationships
> via child_of_bds.

Sure, works for me.  Or maybe:

Make all parents of backing files pass the appropriate BdrvChildRole.
By doing so, we can switch their BdrvChildClass over to the generic
child_of_bds, which will do the right thing when given a correct
BdrvChildRole.

(Because actually the point of this series is not child_of_bds, but the
BdrvChildRole, which allows the “Deal with filters” series to implement
the child access functions in a more obvious way.  I hope.)

Max
Eric Blake Feb. 11, 2020, 3:39 p.m. UTC | #3
On 2/6/20 5:33 AM, Max Reitz wrote:
> On 05.02.20 23:45, Eric Blake wrote:
>> On 2/4/20 11:08 AM, Max Reitz wrote:
>>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>>
>> Another sparse commit message (a recurring theme of this series). The
>> subject line says 'what', and the patch appears to be faithful to that,
>> but if a future bisection lands here, even a one-sentence 'why' would be
>> handy; maybe:
>>
>> This is part of a larger series of unifying block device relationships
>> via child_of_bds.
> 
> Sure, works for me.  Or maybe:
> 
> Make all parents of backing files pass the appropriate BdrvChildRole.
> By doing so, we can switch their BdrvChildClass over to the generic
> child_of_bds, which will do the right thing when given a correct
> BdrvChildRole.

Sounds good.

> 
> (Because actually the point of this series is not child_of_bds, but the
> BdrvChildRole, which allows the “Deal with filters” series to implement
> the child access functions in a more obvious way.  I hope.)

And hopefully I finish my review of the rest of the series today, to see 
if we met that goal.
diff mbox series

Patch

diff --git a/block.c b/block.c
index 77755f0c6c..6b705ee23a 100644
--- a/block.c
+++ b/block.c
@@ -2748,6 +2748,20 @@  static bool bdrv_inherits_from_recursive(BlockDriverState *child,
     return child != NULL;
 }
 
+/*
+ * Return the BdrvChildRole for @bs's backing child.  bs->backing is
+ * mostly used for COW backing children (role = COW), but also for
+ * filtered children (role = FILTERED | PRIMARY).
+ */
+static BdrvChildRole bdrv_backing_role(BlockDriverState *bs)
+{
+    if (bs->drv && bs->drv->is_filter) {
+        return BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY;
+    } else {
+        return BDRV_CHILD_COW;
+    }
+}
+
 /*
  * Sets the backing file link of a BDS. A new reference is created; callers
  * which don't need their own reference any more must call bdrv_unref().
@@ -2775,8 +2789,8 @@  void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
         goto out;
     }
 
-    bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_backing,
-                                    0, errp);
+    bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_of_bds,
+                                    bdrv_backing_role(bs), errp);
     /* If backing_hd was already part of bs's backing chain, and
      * inherits_from pointed recursively to bs then let's update it to
      * point directly to bs (else it will become NULL). */
@@ -2873,7 +2887,7 @@  int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
     }
 
     backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs,
-                                   &child_backing, 0, errp);
+                                   &child_of_bds, BDRV_CHILD_COW, errp);
     if (!backing_hd) {
         bs->open_flags |= BDRV_O_NO_BACKING;
         error_prepend(errp, "Could not open backing file: ");
@@ -3709,8 +3723,8 @@  int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
         if (state->replace_backing_bs && state->new_backing_bs) {
             uint64_t nperm, nshared;
             bdrv_child_perm(state->bs, state->new_backing_bs,
-                            NULL, &child_backing, 0, bs_queue,
-                            state->perm, state->shared_perm,
+                            NULL, &child_of_bds, bdrv_backing_role(state->bs),
+                            bs_queue, state->perm, state->shared_perm,
                             &nperm, &nshared);
             ret = bdrv_check_update_perm(state->new_backing_bs, NULL,
                                          nperm, nshared, NULL, NULL, errp);
@@ -6656,7 +6670,7 @@  void bdrv_refresh_filename(BlockDriverState *bs)
         drv->bdrv_gather_child_options(bs, opts, backing_overridden);
     } else {
         QLIST_FOREACH(child, &bs->children, next) {
-            if (child->klass == &child_backing && !backing_overridden) {
+            if (child == bs->backing && !backing_overridden) {
                 /* We can skip the backing BDS if it has not been overridden */
                 continue;
             }
diff --git a/block/backup-top.c b/block/backup-top.c
index 36ed71413b..8ac7009852 100644
--- a/block/backup-top.c
+++ b/block/backup-top.c
@@ -138,7 +138,7 @@  static void backup_top_child_perm(BlockDriverState *bs, BdrvChild *c,
         return;
     }
 
-    if (child_class == &child_file) {
+    if (!(role & BDRV_CHILD_FILTERED)) {
         /*
          * Target child
          *
diff --git a/block/vvfat.c b/block/vvfat.c
index 3bcf860af7..2bc5812dc5 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -3228,7 +3228,8 @@  static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c,
 {
     BDRVVVFATState *s = bs->opaque;
 
-    assert(c == s->qcow || child_class == &child_backing);
+    assert(c == s->qcow ||
+           (child_class == &child_of_bds && (role & BDRV_CHILD_COW)));
 
     if (c == s->qcow) {
         /* This is a private node, nobody should try to attach to it */
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
index b3d7960bd0..15393a0140 100644
--- a/tests/test-bdrv-drain.c
+++ b/tests/test-bdrv-drain.c
@@ -96,7 +96,7 @@  static void bdrv_test_child_perm(BlockDriverState *bs, BdrvChild *c,
      * bdrv_format_default_perms() accepts only these two, so disguise
      * detach_by_driver_cb_parent as one of them.
      */
-    if (child_class != &child_file && child_class != &child_backing) {
+    if (child_class != &child_file && child_class != &child_of_bds) {
         child_class = &child_file;
     }
 
@@ -1399,8 +1399,8 @@  static void test_detach_indirect(bool by_parent_cb)
     bdrv_ref(a);
     child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_file, 0,
                                 &error_abort);
-    child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_backing, 0,
-                                &error_abort);
+    child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds,
+                                BDRV_CHILD_COW, &error_abort);
 
     bdrv_ref(a);
     bdrv_attach_child(parent_a, a, "PA-A",
@@ -1793,7 +1793,7 @@  static void test_drop_intermediate_poll(void)
     int i;
     int ret;
 
-    chain_child_class = child_backing;
+    chain_child_class = child_of_bds;
     chain_child_class.update_filename = drop_intermediate_poll_update_filename;
 
     for (i = 0; i < 3; i++) {
@@ -1816,7 +1816,7 @@  static void test_drop_intermediate_poll(void)
             /* Takes the reference to chain[i - 1] */
             chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1],
                                                   "chain", &chain_child_class,
-                                                  0, &error_abort);
+                                                  BDRV_CHILD_COW, &error_abort);
         }
     }
 
@@ -2034,7 +2034,8 @@  static void do_test_replace_child_mid_drain(int old_drain_count,
 
     bdrv_ref(old_child_bs);
     parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child",
-                                           &child_backing, 0, &error_abort);
+                                           &child_of_bds, BDRV_CHILD_COW,
+                                           &error_abort);
 
     for (i = 0; i < old_drain_count; i++) {
         bdrv_drained_begin(old_child_bs);