提交 18e46a03 编写于 作者: M Markus Armbruster 提交者: Kevin Wolf

block: Connect BlockBackend and DriveInfo

Make the BlockBackend own the DriveInfo.  Change blockdev_init() to
return the BlockBackend instead of the DriveInfo.
Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
Reviewed-by: NMax Reitz <mreitz@redhat.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 7e7d56d9
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "qemu/module.h" #include "qemu/module.h"
#include "qapi/qmp/qjson.h" #include "qapi/qmp/qjson.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/blockdev.h" /* FIXME layering violation */
#include "qemu/notify.h" #include "qemu/notify.h"
#include "block/coroutine.h" #include "block/coroutine.h"
#include "block/qapi.h" #include "block/qapi.h"
...@@ -2131,7 +2130,6 @@ static void bdrv_delete(BlockDriverState *bs) ...@@ -2131,7 +2130,6 @@ static void bdrv_delete(BlockDriverState *bs)
/* remove from list, if necessary */ /* remove from list, if necessary */
bdrv_make_anon(bs); bdrv_make_anon(bs);
drive_info_del(drive_get_by_blockdev(bs));
g_free(bs); g_free(bs);
} }
......
...@@ -12,11 +12,13 @@ ...@@ -12,11 +12,13 @@
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
#include "block/block_int.h" #include "block/block_int.h"
#include "sysemu/blockdev.h"
struct BlockBackend { struct BlockBackend {
char *name; char *name;
int refcnt; int refcnt;
BlockDriverState *bs; BlockDriverState *bs;
DriveInfo *legacy_dinfo;
QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */ QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
}; };
...@@ -87,6 +89,7 @@ static void blk_delete(BlockBackend *blk) ...@@ -87,6 +89,7 @@ static void blk_delete(BlockBackend *blk)
QTAILQ_REMOVE(&blk_backends, blk, link); QTAILQ_REMOVE(&blk_backends, blk, link);
} }
g_free(blk->name); g_free(blk->name);
drive_info_del(blk->legacy_dinfo);
g_free(blk); g_free(blk);
} }
...@@ -166,6 +169,41 @@ BlockDriverState *blk_bs(BlockBackend *blk) ...@@ -166,6 +169,41 @@ BlockDriverState *blk_bs(BlockBackend *blk)
return blk->bs; return blk->bs;
} }
/*
* 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. * Hide @blk.
* @blk must not have been hidden already. * @blk must not have been hidden already.
......
...@@ -47,8 +47,6 @@ ...@@ -47,8 +47,6 @@
#include "trace.h" #include "trace.h"
#include "sysemu/arch_init.h" #include "sysemu/arch_init.h"
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
static const char *const if_name[IF_COUNT] = { static const char *const if_name[IF_COUNT] = {
[IF_NONE] = "none", [IF_NONE] = "none",
[IF_IDE] = "ide", [IF_IDE] = "ide",
...@@ -86,13 +84,15 @@ static int if_max_devs[IF_COUNT] = { ...@@ -86,13 +84,15 @@ static int if_max_devs[IF_COUNT] = {
*/ */
void override_max_devs(BlockInterfaceType type, int max_devs) void override_max_devs(BlockInterfaceType type, int max_devs)
{ {
BlockBackend *blk;
DriveInfo *dinfo; DriveInfo *dinfo;
if (max_devs <= 0) { if (max_devs <= 0) {
return; return;
} }
QTAILQ_FOREACH(dinfo, &drives, next) { for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
dinfo = blk_legacy_dinfo(blk);
if (dinfo->type == type) { if (dinfo->type == type) {
fprintf(stderr, "Cannot override units-per-bus property of" fprintf(stderr, "Cannot override units-per-bus property of"
" the %s interface, because a drive of that type has" " the %s interface, because a drive of that type has"
...@@ -113,7 +113,8 @@ void override_max_devs(BlockInterfaceType type, int max_devs) ...@@ -113,7 +113,8 @@ void override_max_devs(BlockInterfaceType type, int max_devs)
*/ */
void blockdev_mark_auto_del(BlockDriverState *bs) 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) { if (dinfo && !dinfo->enable_auto_del) {
return; return;
...@@ -129,7 +130,8 @@ void blockdev_mark_auto_del(BlockDriverState *bs) ...@@ -129,7 +130,8 @@ void blockdev_mark_auto_del(BlockDriverState *bs)
void blockdev_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) { if (dinfo && dinfo->auto_del) {
drive_del(dinfo); drive_del(dinfo);
...@@ -194,15 +196,15 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file, ...@@ -194,15 +196,15 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit) DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
{ {
BlockBackend *blk;
DriveInfo *dinfo; DriveInfo *dinfo;
/* seek interface, bus and unit */ for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
dinfo = blk_legacy_dinfo(blk);
QTAILQ_FOREACH(dinfo, &drives, next) { if (dinfo && dinfo->type == type
if (dinfo->type == type && && dinfo->bus == bus && dinfo->unit == unit) {
dinfo->bus == bus &&
dinfo->unit == unit)
return dinfo; return dinfo;
}
} }
return NULL; return NULL;
...@@ -210,10 +212,12 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit) ...@@ -210,10 +212,12 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
bool drive_check_orphaned(void) bool drive_check_orphaned(void)
{ {
BlockBackend *blk;
DriveInfo *dinfo; DriveInfo *dinfo;
bool rs = false; bool rs = false;
QTAILQ_FOREACH(dinfo, &drives, next) { for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
dinfo = blk_legacy_dinfo(blk);
/* If dinfo->bdrv->dev is NULL, it has no device attached. */ /* If dinfo->bdrv->dev is NULL, it has no device attached. */
/* Unless this is a default drive, this may be an oversight. */ /* Unless this is a default drive, this may be an oversight. */
if (!dinfo->bdrv->dev && !dinfo->is_default && if (!dinfo->bdrv->dev && !dinfo->is_default &&
...@@ -239,13 +243,15 @@ DriveInfo *drive_get_by_index(BlockInterfaceType type, int index) ...@@ -239,13 +243,15 @@ DriveInfo *drive_get_by_index(BlockInterfaceType type, int index)
int drive_get_max_bus(BlockInterfaceType type) int drive_get_max_bus(BlockInterfaceType type)
{ {
int max_bus; int max_bus;
BlockBackend *blk;
DriveInfo *dinfo; DriveInfo *dinfo;
max_bus = -1; max_bus = -1;
QTAILQ_FOREACH(dinfo, &drives, next) { for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
if(dinfo->type == type && dinfo = blk_legacy_dinfo(blk);
dinfo->bus > max_bus) if (dinfo && dinfo->type == type && dinfo->bus > max_bus) {
max_bus = dinfo->bus; max_bus = dinfo->bus;
}
} }
return max_bus; return max_bus;
} }
...@@ -262,14 +268,7 @@ DriveInfo *drive_get_next(BlockInterfaceType type) ...@@ -262,14 +268,7 @@ DriveInfo *drive_get_next(BlockInterfaceType type)
DriveInfo *drive_get_by_blockdev(BlockDriverState *bs) DriveInfo *drive_get_by_blockdev(BlockDriverState *bs)
{ {
DriveInfo *dinfo; return bs->blk ? blk_legacy_dinfo(bs->blk) : NULL;
QTAILQ_FOREACH(dinfo, &drives, next) {
if (dinfo->bdrv == bs) {
return dinfo;
}
}
return NULL;
} }
static void bdrv_format_print(void *opaque, const char *name) static void bdrv_format_print(void *opaque, const char *name)
...@@ -292,7 +291,6 @@ void drive_info_del(DriveInfo *dinfo) ...@@ -292,7 +291,6 @@ void drive_info_del(DriveInfo *dinfo)
} }
qemu_opts_del(dinfo->opts); qemu_opts_del(dinfo->opts);
g_free(dinfo->id); g_free(dinfo->id);
QTAILQ_REMOVE(&drives, dinfo, next);
g_free(dinfo->serial); g_free(dinfo->serial);
g_free(dinfo); g_free(dinfo);
} }
...@@ -364,8 +362,8 @@ static bool check_throttle_config(ThrottleConfig *cfg, Error **errp) ...@@ -364,8 +362,8 @@ static bool check_throttle_config(ThrottleConfig *cfg, Error **errp)
typedef enum { MEDIA_DISK, MEDIA_CDROM } DriveMediaType; typedef enum { MEDIA_DISK, MEDIA_CDROM } DriveMediaType;
/* Takes the ownership of bs_opts */ /* Takes the ownership of bs_opts */
static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
Error **errp) Error **errp)
{ {
const char *buf; const char *buf;
int ro = 0; int ro = 0;
...@@ -548,7 +546,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, ...@@ -548,7 +546,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
dinfo = g_malloc0(sizeof(*dinfo)); dinfo = g_malloc0(sizeof(*dinfo));
dinfo->id = g_strdup(qemu_opts_id(opts)); dinfo->id = g_strdup(qemu_opts_id(opts));
dinfo->bdrv = bs; dinfo->bdrv = bs;
QTAILQ_INSERT_TAIL(&drives, dinfo, next); blk_set_legacy_dinfo(blk, dinfo);
if (!file || !*file) { if (!file || !*file) {
if (has_driver_specific_opts) { if (has_driver_specific_opts) {
...@@ -556,7 +554,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, ...@@ -556,7 +554,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
} else { } else {
QDECREF(bs_opts); QDECREF(bs_opts);
qemu_opts_del(opts); qemu_opts_del(opts);
return dinfo; return blk;
} }
} }
if (snapshot) { if (snapshot) {
...@@ -593,7 +591,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, ...@@ -593,7 +591,7 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
QDECREF(bs_opts); QDECREF(bs_opts);
qemu_opts_del(opts); qemu_opts_del(opts);
return dinfo; return blk;
err: err:
bdrv_unref(bs); bdrv_unref(bs);
...@@ -710,6 +708,7 @@ QemuOptsList qemu_legacy_drive_opts = { ...@@ -710,6 +708,7 @@ QemuOptsList qemu_legacy_drive_opts = {
DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
{ {
const char *value; const char *value;
BlockBackend *blk;
DriveInfo *dinfo = NULL; DriveInfo *dinfo = NULL;
QDict *bs_opts; QDict *bs_opts;
QemuOpts *legacy_opts; QemuOpts *legacy_opts;
...@@ -1007,9 +1006,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) ...@@ -1007,9 +1006,9 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
} }
/* Actual block device init: Functionality shared with blockdev-add */ /* 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; bs_opts = NULL;
if (dinfo == NULL) { if (!blk) {
if (local_err) { if (local_err) {
error_report("%s", error_get_pretty(local_err)); error_report("%s", error_get_pretty(local_err));
error_free(local_err); error_free(local_err);
...@@ -1020,6 +1019,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) ...@@ -1020,6 +1019,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
} }
/* Set legacy DriveInfo fields */ /* Set legacy DriveInfo fields */
dinfo = blk_legacy_dinfo(blk);
dinfo->enable_auto_del = true; dinfo->enable_auto_del = true;
dinfo->opts = all_opts; dinfo->opts = all_opts;
...@@ -1849,7 +1849,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) ...@@ -1849,7 +1849,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
} }
bs = blk_bs(blk); bs = blk_bs(blk);
dinfo = drive_get_by_blockdev(bs); dinfo = blk_legacy_dinfo(blk);
if (dinfo && !dinfo->enable_auto_del) { if (dinfo && !dinfo->enable_auto_del) {
error_report("Deleting device added with blockdev-add" error_report("Deleting device added with blockdev-add"
" is not supported"); " is not supported");
...@@ -2574,7 +2574,7 @@ void qmp_change_backing_file(const char *device, ...@@ -2574,7 +2574,7 @@ void qmp_change_backing_file(const char *device,
void qmp_blockdev_add(BlockdevOptions *options, Error **errp) void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
{ {
QmpOutputVisitor *ov = qmp_output_visitor_new(); QmpOutputVisitor *ov = qmp_output_visitor_new();
DriveInfo *dinfo; BlockBackend *blk;
QObject *obj; QObject *obj;
QDict *qdict; QDict *qdict;
Error *local_err = NULL; Error *local_err = NULL;
...@@ -2612,14 +2612,15 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp) ...@@ -2612,14 +2612,15 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
qdict_flatten(qdict); qdict_flatten(qdict);
dinfo = blockdev_init(NULL, qdict, &local_err); blk = blockdev_init(NULL, qdict, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto fail; goto fail;
} }
if (bdrv_key_required(dinfo->bdrv)) { if (bdrv_key_required(blk_bs(blk))) {
drive_del(dinfo); bdrv_unref(blk_bs(blk));
blk_unref(blk);
error_setg(errp, "blockdev-add doesn't support encrypted devices"); error_setg(errp, "blockdev-add doesn't support encrypted devices");
goto fail; goto fail;
} }
......
...@@ -46,6 +46,10 @@ struct DriveInfo { ...@@ -46,6 +46,10 @@ struct DriveInfo {
QTAILQ_ENTRY(DriveInfo) next; 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);
void override_max_devs(BlockInterfaceType type, int max_devs); void override_max_devs(BlockInterfaceType type, int max_devs);
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit); DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册