[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 22/23] block: Lift device model API into BlockBacken
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PATCH 22/23] block: Lift device model API into BlockBackend |
Date: |
Wed, 10 Sep 2014 10:13:51 +0200 |
Move device model attachment / detachment and the BlockDevOps device
model callbacks and their wrappers from BlockDriverState to
BlockBackend.
Signed-off-by: Markus Armbruster <address@hidden>
---
block.c | 126 +++++------------------------------------
block/block-backend.c | 107 ++++++++++++++++++++++++++++++----
block/qapi.c | 8 +--
blockdev.c | 8 +--
include/block/block.h | 45 ---------------
include/block/block_int.h | 12 ++--
include/sysemu/block-backend.h | 35 ++++++++++++
7 files changed, 159 insertions(+), 182 deletions(-)
diff --git a/block.c b/block.c
index f71b87c..e81087f 100644
--- a/block.c
+++ b/block.c
@@ -58,9 +58,6 @@ struct BdrvDirtyBitmap {
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress
*/
-#define COROUTINE_POOL_RESERVATION 64 /* number of coroutines to reserve */
-
-static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque);
@@ -1516,7 +1513,9 @@ int bdrv_open(BlockDriverState **pbs, const char
*filename,
}
if (!bdrv_key_required(bs)) {
- bdrv_dev_change_media_cb(bs, true);
+ if (bs->blk) {
+ blk_dev_change_media_cb(bs->blk, true);
+ }
} else if (!runstate_check(RUN_STATE_PRELAUNCH)
&& !runstate_check(RUN_STATE_INMIGRATE)
&& !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
@@ -1841,7 +1840,9 @@ void bdrv_close(BlockDriverState *bs)
}
}
- bdrv_dev_change_media_cb(bs, false);
+ if (bs->blk) {
+ blk_dev_change_media_cb(bs->blk, false);
+ }
/*throttling disk I/O limits*/
if (bs->io_limits_enabled) {
@@ -1949,9 +1950,6 @@ static void bdrv_move_feature_fields(BlockDriverState
*bs_dest,
/* move some fields that need to stay attached to the device */
/* dev info */
- bs_dest->dev_ops = bs_src->dev_ops;
- bs_dest->dev_opaque = bs_src->dev_opaque;
- bs_dest->dev = bs_src->dev;
bs_dest->guest_block_size = bs_src->guest_block_size;
bs_dest->copy_on_read = bs_src->copy_on_read;
@@ -2017,7 +2015,6 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState
*bs_old)
assert(!bs_new->blk);
assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
assert(bs_new->job == NULL);
- assert(bs_new->dev == NULL);
assert(bs_new->io_limits_enabled == false);
assert(!throttle_have_timer(&bs_new->throttle_state));
@@ -2034,7 +2031,6 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState
*bs_old)
assert(!bs_new->blk);
/* Check a few fields that should remain attached to the device */
- assert(bs_new->dev == NULL);
assert(bs_new->job == NULL);
assert(bs_new->io_limits_enabled == false);
assert(!throttle_have_timer(&bs_new->throttle_state));
@@ -2073,7 +2069,6 @@ void bdrv_append(BlockDriverState *bs_new,
BlockDriverState *bs_top)
static void bdrv_delete(BlockDriverState *bs)
{
- assert(!bs->dev);
assert(!bs->job);
assert(bdrv_op_blocker_is_empty(bs));
assert(!bs->refcnt);
@@ -2087,105 +2082,6 @@ static void bdrv_delete(BlockDriverState *bs)
g_free(bs);
}
-int bdrv_attach_dev(BlockDriverState *bs, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
-{
- if (bs->dev) {
- return -EBUSY;
- }
- bs->dev = dev;
- bdrv_iostatus_reset(bs);
-
- /* We're expecting I/O from the device so bump up coroutine pool size */
- qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
- return 0;
-}
-
-/* TODO qdevified devices don't use this, remove when devices are qdevified */
-void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev)
-{
- if (bdrv_attach_dev(bs, dev) < 0) {
- abort();
- }
-}
-
-void bdrv_detach_dev(BlockDriverState *bs, void *dev)
-/* TODO change to DeviceState *dev when all users are qdevified */
-{
- assert(bs->dev == dev);
- bs->dev = NULL;
- bs->dev_ops = NULL;
- bs->dev_opaque = NULL;
- bs->guest_block_size = 512;
- qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
-}
-
-/* TODO change to return DeviceState * when all users are qdevified */
-void *bdrv_get_attached_dev(BlockDriverState *bs)
-{
- return bs->dev;
-}
-
-void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
- void *opaque)
-{
- bs->dev_ops = ops;
- bs->dev_opaque = opaque;
-}
-
-static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load)
-{
- if (bs->dev_ops && bs->dev_ops->change_media_cb) {
- bool tray_was_closed = !bdrv_dev_is_tray_open(bs);
- bs->dev_ops->change_media_cb(bs->dev_opaque, load);
- if (tray_was_closed) {
- /* tray open */
- qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
- true, &error_abort);
- }
- if (load) {
- /* tray close */
- qapi_event_send_device_tray_moved(bdrv_get_device_name(bs),
- false, &error_abort);
- }
- }
-}
-
-bool bdrv_dev_has_removable_media(BlockDriverState *bs)
-{
- return !bs->dev || (bs->dev_ops && bs->dev_ops->change_media_cb);
-}
-
-void bdrv_dev_eject_request(BlockDriverState *bs, bool force)
-{
- if (bs->dev_ops && bs->dev_ops->eject_request_cb) {
- bs->dev_ops->eject_request_cb(bs->dev_opaque, force);
- }
-}
-
-bool bdrv_dev_is_tray_open(BlockDriverState *bs)
-{
- if (bs->dev_ops && bs->dev_ops->is_tray_open) {
- return bs->dev_ops->is_tray_open(bs->dev_opaque);
- }
- return false;
-}
-
-static void bdrv_dev_resize_cb(BlockDriverState *bs)
-{
- if (bs->dev_ops && bs->dev_ops->resize_cb) {
- bs->dev_ops->resize_cb(bs->dev_opaque);
- }
-}
-
-bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
-{
- if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
- return bs->dev_ops->is_medium_locked(bs->dev_opaque);
- }
- return false;
-}
-
/*
* Run consistency checks on an image
*
@@ -3520,7 +3416,9 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
ret = drv->bdrv_truncate(bs, offset);
if (ret == 0) {
ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
- bdrv_dev_resize_cb(bs);
+ if (bs->blk) {
+ blk_dev_resize_cb(bs->blk);
+ }
}
return ret;
}
@@ -3714,8 +3612,10 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
bs->valid_key = 0;
} else if (!bs->valid_key) {
bs->valid_key = 1;
- /* call the change callback now, we skipped it on open */
- bdrv_dev_change_media_cb(bs, true);
+ if (bs->blk) {
+ /* call the change callback now, we skipped it on open */
+ blk_dev_change_media_cb(bs->blk, true);
+ }
}
return ret;
}
diff --git a/block/block-backend.c b/block/block-backend.c
index 1bac033..6c0c8f2 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -13,6 +13,10 @@
#include "sysemu/block-backend.h"
#include "block/block_int.h"
#include "sysemu/blockdev.h"
+#include "qapi-event.h"
+
+/* Number of coroutines to reserve per attached device model */
+#define COROUTINE_POOL_RESERVATION 64
struct BlockBackend {
char *name;
@@ -20,6 +24,11 @@ struct BlockBackend {
BlockDriverState *bs;
DriveInfo *legacy_dinfo;
QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
+
+ void *dev; /* attached device model, if any */
+ /* TODO change to DeviceState when all users are qdevified */
+ const BlockDevOps *dev_ops;
+ void *dev_opaque;
};
static void drive_info_del(DriveInfo *dinfo);
@@ -85,6 +94,7 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp)
static void blk_delete(BlockBackend *blk)
{
assert(!blk->refcnt);
+ assert(!blk->dev);
bdrv_unref(blk->bs);
blk_detach_bs(blk);
QTAILQ_REMOVE(&blk_backends, blk, link);
@@ -237,34 +247,109 @@ BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
assert(0);
}
-void blk_iostatus_enable(BlockBackend *blk)
-{
- bdrv_iostatus_enable(blk->bs);
-}
-
int blk_attach_dev(BlockBackend *blk, void *dev)
+/* TODO change to DeviceState *dev when all users are qdevified */
{
- return bdrv_attach_dev(blk->bs, dev);
+ if (blk->dev) {
+ return -EBUSY;
+ }
+ blk->dev = dev;
+ bdrv_iostatus_reset(blk->bs);
+
+ /* We're expecting I/O from the device so bump up coroutine pool size */
+ qemu_coroutine_adjust_pool_size(COROUTINE_POOL_RESERVATION);
+ return 0;
}
+/* TODO qdevified devices don't use this, remove when devices are qdevified */
void blk_attach_dev_nofail(BlockBackend *blk, void *dev)
{
- bdrv_attach_dev_nofail(blk->bs, dev);
+ if (blk_attach_dev(blk, dev) < 0) {
+ abort();
+ }
}
void blk_detach_dev(BlockBackend *blk, void *dev)
+/* TODO change to DeviceState *dev when all users are qdevified */
{
- bdrv_detach_dev(blk->bs, dev);
+ assert(blk->dev == dev);
+ blk->dev = NULL;
+ blk->dev_ops = NULL;
+ blk->dev_opaque = NULL;
+ bdrv_set_guest_block_size(blk->bs, 512);
+ qemu_coroutine_adjust_pool_size(-COROUTINE_POOL_RESERVATION);
}
+/* TODO change to return DeviceState * when all users are qdevified */
void *blk_get_attached_dev(BlockBackend *blk)
{
- return bdrv_get_attached_dev(blk->bs);
+ return blk->dev;
}
-void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque)
+void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops,
+ void *opaque)
{
- bdrv_set_dev_ops(blk->bs, ops, opaque);
+ blk->dev_ops = ops;
+ blk->dev_opaque = opaque;
+}
+
+void blk_dev_change_media_cb(BlockBackend *blk, bool load)
+{
+ if (blk->dev_ops && blk->dev_ops->change_media_cb) {
+ bool tray_was_closed = !blk_dev_is_tray_open(blk);
+
+ blk->dev_ops->change_media_cb(blk->dev_opaque, load);
+ if (tray_was_closed) {
+ /* tray open */
+ qapi_event_send_device_tray_moved(blk_name(blk),
+ true, &error_abort);
+ }
+ if (load) {
+ /* tray close */
+ qapi_event_send_device_tray_moved(blk_name(blk),
+ false, &error_abort);
+ }
+ }
+}
+
+bool blk_dev_has_removable_media(BlockBackend *blk)
+{
+ return !blk->dev || (blk->dev_ops && blk->dev_ops->change_media_cb);
+}
+
+void blk_dev_eject_request(BlockBackend *blk, bool force)
+{
+ if (blk->dev_ops && blk->dev_ops->eject_request_cb) {
+ blk->dev_ops->eject_request_cb(blk->dev_opaque, force);
+ }
+}
+
+bool blk_dev_is_tray_open(BlockBackend *blk)
+{
+ if (blk->dev_ops && blk->dev_ops->is_tray_open) {
+ return blk->dev_ops->is_tray_open(blk->dev_opaque);
+ }
+ return false;
+}
+
+void blk_dev_resize_cb(BlockBackend *blk)
+{
+ if (blk->dev_ops && blk->dev_ops->resize_cb) {
+ blk->dev_ops->resize_cb(blk->dev_opaque);
+ }
+}
+
+bool blk_dev_is_medium_locked(BlockBackend *blk)
+{
+ if (blk->dev_ops && blk->dev_ops->is_medium_locked) {
+ return blk->dev_ops->is_medium_locked(blk->dev_opaque);
+ }
+ return false;
+}
+
+void blk_iostatus_enable(BlockBackend *blk)
+{
+ bdrv_iostatus_enable(blk->bs);
}
int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
diff --git a/block/qapi.c b/block/qapi.c
index 02121b2..921e620 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -275,12 +275,12 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo
**p_info,
Error *local_err = NULL;
info->device = g_strdup(blk_name(blk));
info->type = g_strdup("unknown");
- info->locked = bdrv_dev_is_medium_locked(bs);
- info->removable = bdrv_dev_has_removable_media(bs);
+ info->locked = blk_dev_is_medium_locked(blk);
+ info->removable = blk_dev_has_removable_media(blk);
- if (bdrv_dev_has_removable_media(bs)) {
+ if (blk_dev_has_removable_media(blk)) {
info->has_tray_open = true;
- info->tray_open = bdrv_dev_is_tray_open(bs);
+ info->tray_open = blk_dev_is_tray_open(blk);
}
if (bdrv_iostatus_is_enabled(bs)) {
diff --git a/blockdev.c b/blockdev.c
index 6286c0e..6dc405b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1508,14 +1508,14 @@ static void eject_device(BlockBackend *blk, int force,
Error **errp)
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
return;
}
- if (!bdrv_dev_has_removable_media(bs)) {
+ if (!blk_dev_has_removable_media(blk)) {
error_setg(errp, "Device '%s' is not removable",
bdrv_get_device_name(bs));
return;
}
- if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) {
- bdrv_dev_eject_request(bs, force);
+ if (blk_dev_is_medium_locked(blk) && !blk_dev_is_tray_open(blk)) {
+ blk_dev_eject_request(blk, force);
if (!force) {
error_setg(errp, "Device '%s' is locked",
bdrv_get_device_name(bs));
@@ -1746,7 +1746,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict,
QObject **ret_data)
* can be removed. If this is a drive with no device backing
* then we can just get rid of the block driver state right here.
*/
- if (bdrv_get_attached_dev(bs)) {
+ if (blk_get_attached_dev(blk)) {
blk_make_anon(blk);
/* Further I/O must not pause the guest */
bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
diff --git a/include/block/block.h b/include/block/block.h
index 15a5290..3252039 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -47,41 +47,6 @@ typedef struct BlockFragInfo {
uint64_t compressed_clusters;
} BlockFragInfo;
-/* Callbacks for block device models */
-typedef struct BlockDevOps {
- /*
- * Runs when virtual media changed (monitor commands eject, change)
- * Argument load is true on load and false on eject.
- * Beware: doesn't run when a host device's physical media
- * changes. Sure would be useful if it did.
- * Device models with removable media must implement this callback.
- */
- void (*change_media_cb)(void *opaque, bool load);
- /*
- * Runs when an eject request is issued from the monitor, the tray
- * is closed, and the medium is locked.
- * Device models that do not implement is_medium_locked will not need
- * this callback. Device models that can lock the medium or tray might
- * want to implement the callback and unlock the tray when "force" is
- * true, even if they do not support eject requests.
- */
- void (*eject_request_cb)(void *opaque, bool force);
- /*
- * Is the virtual tray open?
- * Device models implement this only when the device has a tray.
- */
- bool (*is_tray_open)(void *opaque);
- /*
- * Is the virtual medium locked into the device?
- * Device models implement this only when device has such a lock.
- */
- bool (*is_medium_locked)(void *opaque);
- /*
- * Runs when the size changed (e.g. monitor command block_resize)
- */
- void (*resize_cb)(void *opaque);
-} BlockDevOps;
-
typedef enum {
BDRV_REQ_COPY_ON_READ = 0x1,
BDRV_REQ_ZERO_WRITE = 0x2,
@@ -228,16 +193,6 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state);
void bdrv_reopen_abort(BDRVReopenState *reopen_state);
void bdrv_close(BlockDriverState *bs);
void bdrv_add_close_notifier(BlockDriverState *bs, Notifier *notify);
-int bdrv_attach_dev(BlockDriverState *bs, void *dev);
-void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev);
-void bdrv_detach_dev(BlockDriverState *bs, void *dev);
-void *bdrv_get_attached_dev(BlockDriverState *bs);
-void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
- void *opaque);
-void bdrv_dev_eject_request(BlockDriverState *bs, bool force);
-bool bdrv_dev_has_removable_media(BlockDriverState *bs);
-bool bdrv_dev_is_tray_open(BlockDriverState *bs);
-bool bdrv_dev_is_medium_locked(BlockDriverState *bs);
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors);
int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index b3246e7..3b20031 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -325,11 +325,6 @@ struct BlockDriverState {
BlockBackend *blk; /* owning backend, if any */
- void *dev; /* attached device model, if any */
- /* TODO change to DeviceState when all users are qdevified */
- const BlockDevOps *dev_ops;
- void *dev_opaque;
-
AioContext *aio_context; /* event loop used for fd handlers, timers, etc */
/* long-running tasks intended to always use the same AioContext as this
* BDS may register themselves in this list to be notified of changes
@@ -587,4 +582,11 @@ void backup_start(BlockDriverState *bs, BlockDriverState
*target,
BlockCompletionFunc *cb, void *opaque,
Error **errp);
+void blk_dev_change_media_cb(BlockBackend *blk, bool load);
+bool blk_dev_has_removable_media(BlockBackend *blk);
+void blk_dev_eject_request(BlockBackend *blk, bool force);
+bool blk_dev_is_tray_open(BlockBackend *blk);
+bool blk_dev_is_medium_locked(BlockBackend *blk);
+void blk_dev_resize_cb(BlockBackend *blk);
+
#endif /* BLOCK_INT_H */
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 73f9325..d8734bb 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -25,6 +25,41 @@
*/
#include "block/block.h"
+/* Callbacks for block device models */
+typedef struct BlockDevOps {
+ /*
+ * Runs when virtual media changed (monitor commands eject, change)
+ * Argument load is true on load and false on eject.
+ * Beware: doesn't run when a host device's physical media
+ * changes. Sure would be useful if it did.
+ * Device models with removable media must implement this callback.
+ */
+ void (*change_media_cb)(void *opaque, bool load);
+ /*
+ * Runs when an eject request is issued from the monitor, the tray
+ * is closed, and the medium is locked.
+ * Device models that do not implement is_medium_locked will not need
+ * this callback. Device models that can lock the medium or tray might
+ * want to implement the callback and unlock the tray when "force" is
+ * true, even if they do not support eject requests.
+ */
+ void (*eject_request_cb)(void *opaque, bool force);
+ /*
+ * Is the virtual tray open?
+ * Device models implement this only when the device has a tray.
+ */
+ bool (*is_tray_open)(void *opaque);
+ /*
+ * Is the virtual medium locked into the device?
+ * Device models implement this only when device has such a lock.
+ */
+ bool (*is_medium_locked)(void *opaque);
+ /*
+ * Runs when the size changed (e.g. monitor command block_resize)
+ */
+ void (*resize_cb)(void *opaque);
+} BlockDevOps;
+
BlockBackend *blk_new(const char *name, Error **errp);
BlockBackend *blk_new_with_bs(const char *name, Error **errp);
void blk_ref(BlockBackend *blk);
--
1.9.3
- [Qemu-devel] [PATCH 13/23] virtio-blk: Rename VirtIOBlkConf variables to conf, (continued)
- [Qemu-devel] [PATCH 13/23] virtio-blk: Rename VirtIOBlkConf variables to conf, Markus Armbruster, 2014/09/10
- [Qemu-devel] [PATCH 20/23] block/qapi: Convert qmp_query_block() to BlockBackend, Markus Armbruster, 2014/09/10
- [Qemu-devel] [PATCH 17/23] blockdev: Drop superfluous DriveInfo member id, Markus Armbruster, 2014/09/10
- [Qemu-devel] [PATCH 18/23] blockdev: Fix blockdev-add not to create IDE drive (0, 0), Markus Armbruster, 2014/09/10
- [Qemu-devel] [PATCH 23/23] block: Make device model's references to BlockBackend strong, Markus Armbruster, 2014/09/10
- [Qemu-devel] [PATCH 21/23] blockdev: Convert qmp_eject(), qmp_change_blockdev() to BlockBackend, Markus Armbruster, 2014/09/10
- [Qemu-devel] [PATCH 16/23] pc87312: Drop unused members of PC87312State, Markus Armbruster, 2014/09/10
- [Qemu-devel] [PATCH 11/23] block: Rename BlockDriverAIOCB* to BlockAIOCB*, Markus Armbruster, 2014/09/10
- [Qemu-devel] [PATCH 22/23] block: Lift device model API into BlockBackend,
Markus Armbruster <=
- [Qemu-devel] [PATCH 14/23] hw: Convert from BlockDriverState to BlockBackend, mostly, Markus Armbruster, 2014/09/10
- Re: [Qemu-devel] [PATCH 00/23] Split BlockBackend off BDS with an axe, Markus Armbruster, 2014/09/11