All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, benoit.canet@nodalink.com, stefanha@redhat.com,
	mreitz@redhat.com
Subject: [Qemu-devel] [PATCH v5 04/23] block: Connect BlockBackend and DriveInfo
Date: Thu,  2 Oct 2014 11:04:39 +0200	[thread overview]
Message-ID: <1412240698-21695-5-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1412240698-21695-1-git-send-email-armbru@redhat.com>

Make the BlockBackend own the DriveInfo.  Change blockdev_init() to
return the BlockBackend instead of the DriveInfo.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
 block.c                   |  2 --
 block/block-backend.c     | 38 ++++++++++++++++++++++++++
 blockdev.c                | 69 ++++++++++++++++++++++++-----------------------
 include/sysemu/blockdev.h |  4 +++
 4 files changed, 77 insertions(+), 36 deletions(-)

diff --git a/block.c b/block.c
index a25fae9..d6ab0c7 100644
--- a/block.c
+++ b/block.c
@@ -29,7 +29,6 @@
 #include "qemu/module.h"
 #include "qapi/qmp/qjson.h"
 #include "sysemu/sysemu.h"
-#include "sysemu/blockdev.h"    /* FIXME layering violation */
 #include "qemu/notify.h"
 #include "block/coroutine.h"
 #include "block/qapi.h"
@@ -2131,7 +2130,6 @@ static void bdrv_delete(BlockDriverState *bs)
     /* remove from list, if necessary */
     bdrv_make_anon(bs);
 
-    drive_info_del(drive_get_by_blockdev(bs));
     g_free(bs);
 }
 
diff --git a/block/block-backend.c b/block/block-backend.c
index a12215a..edaf73c 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -12,11 +12,13 @@
 
 #include "sysemu/block-backend.h"
 #include "block/block_int.h"
+#include "sysemu/blockdev.h"
 
 struct BlockBackend {
     char *name;
     int refcnt;
     BlockDriverState *bs;
+    DriveInfo *legacy_dinfo;
     QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
 };
 
@@ -87,6 +89,7 @@ static void blk_delete(BlockBackend *blk)
         QTAILQ_REMOVE(&blk_backends, blk, link);
     }
     g_free(blk->name);
+    drive_info_del(blk->legacy_dinfo);
     g_free(blk);
 }
 
@@ -167,6 +170,41 @@ BlockDriverState *blk_bs(BlockBackend *blk)
 }
 
 /*
+ * Return @blk's DriveInfo if any, else null.
+ */
+DriveInfo *blk_legacy_dinfo(BlockBackend *blk)
+{
+    return blk->legacy_dinfo;
+}
+
+/*
+ * Set @blk's DriveInfo to @dinfo, and return it.
+ * @blk must not have a DriveInfo set already.
+ * No other BlockBackend may have the same DriveInfo set.
+ */
+DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo)
+{
+    assert(!blk->legacy_dinfo);
+    return blk->legacy_dinfo = dinfo;
+}
+
+/*
+ * Return the BlockBackend with DriveInfo @dinfo.
+ * It must exist.
+ */
+BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
+{
+    BlockBackend *blk;
+
+    QTAILQ_FOREACH(blk, &blk_backends, link) {
+        if (blk->legacy_dinfo == dinfo) {
+            return blk;
+        }
+    }
+    abort();
+}
+
+/*
  * Hide @blk.
  * @blk must not have been hidden already.
  * Make attached BlockDriverState, if any, anonymous.
diff --git a/blockdev.c b/blockdev.c
index 494714b..3a6bbe9 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -47,8 +47,6 @@
 #include "trace.h"
 #include "sysemu/arch_init.h"
 
-static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
-
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
     [IF_IDE] = "ide",
@@ -89,7 +87,8 @@ static const int if_max_devs[IF_COUNT] = {
  */
 void blockdev_mark_auto_del(BlockDriverState *bs)
 {
-    DriveInfo *dinfo = drive_get_by_blockdev(bs);
+    BlockBackend *blk = bs->blk;
+    DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
     if (dinfo && !dinfo->enable_auto_del) {
         return;
@@ -105,7 +104,8 @@ void blockdev_mark_auto_del(BlockDriverState *bs)
 
 void blockdev_auto_del(BlockDriverState *bs)
 {
-    DriveInfo *dinfo = drive_get_by_blockdev(bs);
+    BlockBackend *blk = bs->blk;
+    DriveInfo *dinfo = blk_legacy_dinfo(blk);
 
     if (dinfo && dinfo->auto_del) {
         drive_del(dinfo);
@@ -153,15 +153,15 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
 
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
 {
+    BlockBackend *blk;
     DriveInfo *dinfo;
 
-    /* seek interface, bus and unit */
-
-    QTAILQ_FOREACH(dinfo, &drives, next) {
-        if (dinfo->type == type &&
-	    dinfo->bus == bus &&
-	    dinfo->unit == unit)
+    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+        dinfo = blk_legacy_dinfo(blk);
+        if (dinfo && dinfo->type == type
+            && dinfo->bus == bus && dinfo->unit == unit) {
             return dinfo;
+        }
     }
 
     return NULL;
@@ -177,13 +177,15 @@ DriveInfo *drive_get_by_index(BlockInterfaceType type, int index)
 int drive_get_max_bus(BlockInterfaceType type)
 {
     int max_bus;
+    BlockBackend *blk;
     DriveInfo *dinfo;
 
     max_bus = -1;
-    QTAILQ_FOREACH(dinfo, &drives, next) {
-        if(dinfo->type == type &&
-           dinfo->bus > max_bus)
+    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+        dinfo = blk_legacy_dinfo(blk);
+        if (dinfo && dinfo->type == type && dinfo->bus > max_bus) {
             max_bus = dinfo->bus;
+        }
     }
     return max_bus;
 }
@@ -200,11 +202,11 @@ DriveInfo *drive_get_next(BlockInterfaceType type)
 
 DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
 {
-    DriveInfo *dinfo;
+    BlockBackend *blk;
 
-    QTAILQ_FOREACH(dinfo, &drives, next) {
-        if (dinfo->bdrv == bs) {
-            return dinfo;
+    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+        if (blk == bs->blk) {
+            return blk_legacy_dinfo(blk);
         }
     }
     return NULL;
@@ -217,10 +219,8 @@ static void bdrv_format_print(void *opaque, const char *name)
 
 void drive_del(DriveInfo *dinfo)
 {
-    BlockBackend *blk = blk_by_name(dinfo->id);
-
     bdrv_unref(dinfo->bdrv);
-    blk_unref(blk);
+    blk_unref(blk_by_legacy_dinfo(dinfo));
 }
 
 void drive_info_del(DriveInfo *dinfo)
@@ -230,7 +230,6 @@ void drive_info_del(DriveInfo *dinfo)
     }
     qemu_opts_del(dinfo->opts);
     g_free(dinfo->id);
-    QTAILQ_REMOVE(&drives, dinfo, next);
     g_free(dinfo->serial);
     g_free(dinfo);
 }
@@ -302,8 +301,8 @@ static bool check_throttle_config(ThrottleConfig *cfg, Error **errp)
 typedef enum { MEDIA_DISK, MEDIA_CDROM } DriveMediaType;
 
 /* Takes the ownership of bs_opts */
-static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
-                                Error **errp)
+static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
+                                   Error **errp)
 {
     const char *buf;
     int ro = 0;
@@ -486,7 +485,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     dinfo = g_malloc0(sizeof(*dinfo));
     dinfo->id = g_strdup(qemu_opts_id(opts));
     dinfo->bdrv = bs;
-    QTAILQ_INSERT_TAIL(&drives, dinfo, next);
+    blk_set_legacy_dinfo(blk, dinfo);
 
     if (!file || !*file) {
         if (has_driver_specific_opts) {
@@ -494,7 +493,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
         } else {
             QDECREF(bs_opts);
             qemu_opts_del(opts);
-            return dinfo;
+            return blk;
         }
     }
     if (snapshot) {
@@ -531,7 +530,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     QDECREF(bs_opts);
     qemu_opts_del(opts);
 
-    return dinfo;
+    return blk;
 
 err:
     bdrv_unref(bs);
@@ -644,6 +643,7 @@ QemuOptsList qemu_legacy_drive_opts = {
 DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
 {
     const char *value;
+    BlockBackend *blk;
     DriveInfo *dinfo = NULL;
     QDict *bs_opts;
     QemuOpts *legacy_opts;
@@ -941,9 +941,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
     }
 
     /* Actual block device init: Functionality shared with blockdev-add */
-    dinfo = blockdev_init(filename, bs_opts, &local_err);
+    blk = blockdev_init(filename, bs_opts, &local_err);
     bs_opts = NULL;
-    if (dinfo == NULL) {
+    if (!blk) {
         if (local_err) {
             error_report("%s", error_get_pretty(local_err));
             error_free(local_err);
@@ -954,6 +954,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
     }
 
     /* Set legacy DriveInfo fields */
+    dinfo = blk_legacy_dinfo(blk);
     dinfo->enable_auto_del = true;
     dinfo->opts = all_opts;
 
@@ -1783,7 +1784,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
     }
     bs = blk_bs(blk);
 
-    dinfo = drive_get_by_blockdev(bs);
+    dinfo = blk_legacy_dinfo(blk);
     if (dinfo && !dinfo->enable_auto_del) {
         error_report("Deleting device added with blockdev-add"
                      " is not supported");
@@ -1815,7 +1816,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
         /* Further I/O must not pause the guest */
         bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
                           BLOCKDEV_ON_ERROR_REPORT);
-        /* FIXME bs->blk leaked when bs dies */
     } else {
         drive_del(dinfo);
     }
@@ -2509,7 +2509,7 @@ void qmp_change_backing_file(const char *device,
 void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
 {
     QmpOutputVisitor *ov = qmp_output_visitor_new();
-    DriveInfo *dinfo;
+    BlockBackend *blk;
     QObject *obj;
     QDict *qdict;
     Error *local_err = NULL;
@@ -2547,14 +2547,15 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
 
     qdict_flatten(qdict);
 
-    dinfo = blockdev_init(NULL, qdict, &local_err);
+    blk = blockdev_init(NULL, qdict, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
         goto fail;
     }
 
-    if (bdrv_key_required(dinfo->bdrv)) {
-        drive_del(dinfo);
+    if (bdrv_key_required(blk_bs(blk))) {
+        bdrv_unref(blk_bs(blk));
+        blk_unref(blk);
         error_setg(errp, "blockdev-add doesn't support encrypted devices");
         goto fail;
     }
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index abec381..1dc5906 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -45,6 +45,10 @@ struct DriveInfo {
     QTAILQ_ENTRY(DriveInfo) next;
 };
 
+DriveInfo *blk_legacy_dinfo(BlockBackend *blk);
+DriveInfo *blk_set_legacy_dinfo(BlockBackend *blk, DriveInfo *dinfo);
+BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo);
+
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
 int drive_get_max_bus(BlockInterfaceType type);
-- 
1.9.3

  parent reply	other threads:[~2014-10-02  9:05 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-02  9:04 [Qemu-devel] [PATCH v5 00/23] Split BlockBackend off BDS with an axe Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 01/23] block: Split bdrv_new_root() off bdrv_new() Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 02/23] block: New BlockBackend Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 03/23] block: Connect BlockBackend to BlockDriverState Markus Armbruster
2014-10-02 10:41   ` Kevin Wolf
2014-10-02 11:37     ` Markus Armbruster
2014-10-02  9:04 ` Markus Armbruster [this message]
2014-10-02 10:55   ` [Qemu-devel] [PATCH v5 04/23] block: Connect BlockBackend and DriveInfo Kevin Wolf
2014-10-02 11:42     ` Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 05/23] block: Code motion to get rid of stubs/blockdev.c Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 06/23] block: Make BlockBackend own its BlockDriverState Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 07/23] block: Eliminate bdrv_iterate(), use bdrv_next() Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 08/23] block: Eliminate BlockDriverState member device_name[] Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 09/23] block: Merge BlockBackend and BlockDriverState name spaces Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo() Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 11/23] block: Rename BlockDriverAIOCB* to BlockAIOCB* Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 12/23] block: Rename BlockDriverCompletionFunc to BlockCompletionFunc Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 13/23] virtio-blk: Drop redundant VirtIOBlock member conf Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 14/23] virtio-blk: Rename VirtIOBlkConf variables to conf Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 15/23] hw: Convert from BlockDriverState to BlockBackend, mostly Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 16/23] ide: Complete conversion from BlockDriverState to BlockBackend Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 17/23] pc87312: Drop unused members of PC87312State Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 18/23] blockdev: Drop superfluous DriveInfo member id Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 19/23] blockdev: Fix blockdev-add not to create DriveInfo Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 20/23] block/qapi: Convert qmp_query_block() to BlockBackend Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev() " Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 22/23] block: Lift device model API into BlockBackend Markus Armbruster
2014-10-02  9:04 ` [Qemu-devel] [PATCH v5 23/23] block: Make device model's references to BlockBackend strong Markus Armbruster

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=1412240698-21695-5-git-send-email-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=benoit.canet@nodalink.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.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.