diff mbox series

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

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

Commit Message

Max Reitz Feb. 18, 2020, 12:42 p.m. UTC
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.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@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

Kevin Wolf May 6, 2020, 4:37 p.m. UTC | #1
Am 18.02.2020 um 13:42 hat Max Reitz geschrieben:
> 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.
> 
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> Reviewed-by: Eric Blake <eblake@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(-)
> 
> diff --git a/block.c b/block.c
> index 43df38ca30..31affcb4ee 100644
> --- a/block.c
> +++ b/block.c
> @@ -2770,6 +2770,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;
> +    }
> +}

bdrv_mirror_top and bdrv_commit_top don't set .is_filter, so it will
return the wrong role for them. (They also don't set .supports_backing,
so grepping for that wouldn't help...)

>  /*
>   * 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().
> @@ -2797,8 +2811,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). */
> @@ -2895,7 +2909,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);

Wouldn't it be more consistent to use bdrv_backing_role() here, too?

Kevin
Max Reitz May 7, 2020, 9:28 a.m. UTC | #2
On 06.05.20 18:37, Kevin Wolf wrote:
> Am 18.02.2020 um 13:42 hat Max Reitz geschrieben:
>> 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.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> Reviewed-by: Eric Blake <eblake@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(-)
>>
>> diff --git a/block.c b/block.c
>> index 43df38ca30..31affcb4ee 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -2770,6 +2770,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;
>> +    }
>> +}
> 
> bdrv_mirror_top and bdrv_commit_top don't set .is_filter, so it will
> return the wrong role for them. (They also don't set .supports_backing,
> so grepping for that wouldn't help...)

I’ll pull in “block: Mark commit and mirror as filter drivers” from the
main series then.

>>  /*
>>   * 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().
>> @@ -2797,8 +2811,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). */
>> @@ -2895,7 +2909,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);
> 
> Wouldn't it be more consistent to use bdrv_backing_role() here, too?

It’d be indeed.

Max
diff mbox series

Patch

diff --git a/block.c b/block.c
index 43df38ca30..31affcb4ee 100644
--- a/block.c
+++ b/block.c
@@ -2770,6 +2770,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().
@@ -2797,8 +2811,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). */
@@ -2895,7 +2909,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: ");
@@ -3731,8 +3745,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);
@@ -6679,7 +6693,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 9dd89c2fde..c173e61250 100644
--- a/block/backup-top.c
+++ b/block/backup-top.c
@@ -142,7 +142,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 a945eeb635..8f4ff5a97e 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -3221,7 +3221,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);