qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Hanna Reitz <hreitz@redhat.com>
To: qemu-block@nongnu.org
Cc: qemu-devel@nongnu.org, Hanna Reitz <hreitz@redhat.com>,
	Kevin Wolf <kwolf@redhat.com>, Eric Blake <eblake@redhat.com>,
	Markus Armbruster <armbru@redhat.com>
Subject: [PATCH v2 06/12] block/qapi: Let bdrv_query_image_info() recurse
Date: Mon, 20 Jun 2022 18:26:58 +0200	[thread overview]
Message-ID: <20220620162704.80987-7-hreitz@redhat.com> (raw)
In-Reply-To: <20220620162704.80987-1-hreitz@redhat.com>

There is no real reason why bdrv_query_image_info() should generally not
recurse.  The ImageInfo struct has a pointer to the backing image, so it
should generally be filled, unless the caller explicitly opts out.

This moves the recursing code from bdrv_block_device_info() into
bdrv_query_image_info().

Signed-off-by: Hanna Reitz <hreitz@redhat.com>
---
 include/block/qapi.h |  2 +
 block/qapi.c         | 94 +++++++++++++++++++++++++++-----------------
 2 files changed, 59 insertions(+), 37 deletions(-)

diff --git a/include/block/qapi.h b/include/block/qapi.h
index 22198dcd0c..2174bf8fa2 100644
--- a/include/block/qapi.h
+++ b/include/block/qapi.h
@@ -40,6 +40,8 @@ void bdrv_query_block_node_info(BlockDriverState *bs,
                                 Error **errp);
 void bdrv_query_image_info(BlockDriverState *bs,
                            ImageInfo **p_info,
+                           bool flat,
+                           bool skip_implicit_filters,
                            Error **errp);
 
 void bdrv_snapshot_dump(QEMUSnapshotInfo *sn);
diff --git a/block/qapi.c b/block/qapi.c
index ad88bf9b38..5d0a8d2ce3 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -47,8 +47,10 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
                                         Error **errp)
 {
     ImageInfo **p_image_info;
+    ImageInfo *backing_info;
     BlockDriverState *bs0, *backing;
     BlockDeviceInfo *info;
+    ERRP_GUARD();
 
     if (!bs->drv) {
         error_setg(errp, "Block device %s is ejected", bs->node_name);
@@ -149,38 +151,21 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
     bs0 = bs;
     p_image_info = &info->image;
     info->backing_file_depth = 0;
-    while (1) {
-        Error *local_err = NULL;
-        bdrv_query_image_info(bs0, p_image_info, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            qapi_free_BlockDeviceInfo(info);
-            return NULL;
-        }
-
-        /* stop gathering data for flat output */
-        if (flat) {
-            break;
-        }
 
-        if (bs0->drv && bdrv_filter_or_cow_child(bs0)) {
-            /*
-             * Put any filtered child here (for backwards compatibility to when
-             * we put bs0->backing here, which might be any filtered child).
-             */
-            info->backing_file_depth++;
-            bs0 = bdrv_filter_or_cow_bs(bs0);
-            (*p_image_info)->has_backing_image = true;
-            p_image_info = &((*p_image_info)->backing_image);
-        } else {
-            break;
-        }
+    /*
+     * Skip automatically inserted nodes that the user isn't aware of for
+     * query-block (blk != NULL), but not for query-named-block-nodes
+     */
+    bdrv_query_image_info(bs0, p_image_info, flat, blk != NULL, errp);
+    if (*errp) {
+        qapi_free_BlockDeviceInfo(info);
+        return NULL;
+    }
 
-        /* Skip automatically inserted nodes that the user isn't aware of for
-         * query-block (blk != NULL), but not for query-named-block-nodes */
-        if (blk) {
-            bs0 = bdrv_skip_implicit_filters(bs0);
-        }
+    backing_info = info->image->backing_image;
+    while (backing_info) {
+        info->backing_file_depth++;
+        backing_info = backing_info->backing_image;
     }
 
     return info;
@@ -363,19 +348,28 @@ void bdrv_query_block_node_info(BlockDriverState *bs,
  * bdrv_query_image_info:
  * @bs: block node to examine
  * @p_info: location to store image information
+ * @flat: skip backing node information
+ * @skip_implicit_filters: skip implicit filters in the backing chain
  * @errp: location to store error information
  *
- * Store "flat" image information in @p_info.
+ * Store image information in @p_info, potentially recursively covering the
+ * backing chain.
  *
- * "Flat" means it does *not* query backing image information,
- * i.e. (*pinfo)->has_backing_image will be set to false and
- * (*pinfo)->backing_image to NULL even when the image does in fact have
- * a backing image.
+ * If @flat is true, do not query backing image information, i.e.
+ * (*p_info)->has_backing_image will be set to false and
+ * (*p_info)->backing_image to NULL even when the image does in fact have a
+ * backing image.
+ *
+ * If @skip_implicit_filters is true, implicit filter nodes in the backing chain
+ * will be skipped when querying backing image information.
+ * (@skip_implicit_filters is ignored when @flat is true.)
  *
  * @p_info will be set only on success. On error, store error in @errp.
  */
 void bdrv_query_image_info(BlockDriverState *bs,
                            ImageInfo **p_info,
+                           bool flat,
+                           bool skip_implicit_filters,
                            Error **errp)
 {
     ImageInfo *info;
@@ -384,11 +378,37 @@ void bdrv_query_image_info(BlockDriverState *bs,
     info = g_new0(ImageInfo, 1);
     bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp);
     if (*errp) {
-        qapi_free_ImageInfo(info);
-        return;
+        goto fail;
+    }
+
+    if (!flat) {
+        BlockDriverState *backing;
+
+        /*
+         * Use any filtered child here (for backwards compatibility to when
+         * we always took bs->backing, which might be any filtered child).
+         */
+        backing = bdrv_filter_or_cow_bs(bs);
+        if (skip_implicit_filters) {
+            backing = bdrv_skip_implicit_filters(backing);
+        }
+
+        if (backing) {
+            bdrv_query_image_info(backing, &info->backing_image, false,
+                                  skip_implicit_filters, errp);
+            if (*errp) {
+                goto fail;
+            }
+            info->has_backing_image = true;
+        }
     }
 
     *p_info = info;
+    return;
+
+fail:
+    assert(*errp);
+    qapi_free_ImageInfo(info);
 }
 
 /* @p_info will be set only on success. */
-- 
2.35.3



  parent reply	other threads:[~2022-06-20 16:33 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-20 16:26 [PATCH v2 00/12] qemu-img info: Show protocol-level information Hanna Reitz
2022-06-20 16:26 ` [PATCH v2 01/12] block: Improve empty format-specific info dump Hanna Reitz
2023-01-19 14:00   ` Kevin Wolf
2023-01-20 13:35     ` Hanna Czenczek
2023-01-20 14:08       ` Kevin Wolf
2022-06-20 16:26 ` [PATCH v2 02/12] block/file: Add file-specific image info Hanna Reitz
2023-01-27 23:00   ` Eric Blake
2022-06-20 16:26 ` [PATCH v2 03/12] block/vmdk: Change extent info type Hanna Reitz
2023-01-19 15:20   ` Kevin Wolf
2023-01-20 13:43     ` Hanna Czenczek
2023-01-27 23:06     ` Eric Blake
2023-01-30 10:56       ` Kevin Wolf
2022-06-20 16:26 ` [PATCH v2 04/12] block: Split BlockNodeInfo off of ImageInfo Hanna Reitz
2022-06-20 16:26 ` [PATCH v2 05/12] qemu-img: Use BlockNodeInfo Hanna Reitz
2022-06-20 16:26 ` Hanna Reitz [this message]
2022-06-20 16:26 ` [PATCH v2 07/12] block/qapi: Introduce BlockGraphInfo Hanna Reitz
2022-06-20 16:27 ` [PATCH v2 08/12] block/qapi: Add indentation to bdrv_node_info_dump() Hanna Reitz
2022-06-20 16:27 ` [PATCH v2 09/12] iotests: Filter child node information Hanna Reitz
2022-06-20 16:27 ` [PATCH v2 10/12] iotests/106, 214, 308: Read only one size line Hanna Reitz
2022-06-20 16:27 ` [PATCH v2 11/12] qemu-img: Let info print block graph Hanna Reitz
2022-06-20 16:27 ` [PATCH v2 12/12] qemu-img: Change info key names for protocol nodes Hanna Reitz
2022-12-08 12:24 ` [PATCH v2 00/12] qemu-img info: Show protocol-level information Hanna Reitz
2023-01-19 20:12   ` Kevin Wolf
2023-01-20 13:44     ` Hanna Czenczek

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=20220620162704.80987-7-hreitz@redhat.com \
    --to=hreitz@redhat.com \
    --cc=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).