summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c14
-rw-r--r--block.h1
-rw-r--r--blockdev.c25
3 files changed, 20 insertions, 20 deletions
diff --git a/block.c b/block.c
index c8e2f97614..c93ec6d418 100644
--- a/block.c
+++ b/block.c
@@ -697,14 +697,22 @@ void bdrv_close_all(void)
}
}
+/* make a BlockDriverState anonymous by removing from bdrv_state list.
+ Also, NULL terminate the device_name to prevent double remove */
+void bdrv_make_anon(BlockDriverState *bs)
+{
+ if (bs->device_name[0] != '\0') {
+ QTAILQ_REMOVE(&bdrv_states, bs, list);
+ }
+ bs->device_name[0] = '\0';
+}
+
void bdrv_delete(BlockDriverState *bs)
{
assert(!bs->peer);
/* remove from list, if necessary */
- if (bs->device_name[0] != '\0') {
- QTAILQ_REMOVE(&bdrv_states, bs, list);
- }
+ bdrv_make_anon(bs);
bdrv_close(bs);
if (bs->file != NULL) {
diff --git a/block.h b/block.h
index 5d78fc0ed7..52e9cad55c 100644
--- a/block.h
+++ b/block.h
@@ -66,6 +66,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
QEMUOptionParameter *options);
int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
BlockDriverState *bdrv_new(const char *device_name);
+void bdrv_make_anon(BlockDriverState *bs);
void bdrv_delete(BlockDriverState *bs);
int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
diff --git a/blockdev.c b/blockdev.c
index bbe92fe196..5429621f0c 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -737,8 +737,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
const char *id = qdict_get_str(qdict, "id");
BlockDriverState *bs;
- BlockDriverState **ptr;
- Property *prop;
bs = bdrv_find(id);
if (!bs) {
@@ -755,24 +753,17 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
bdrv_flush(bs);
bdrv_close(bs);
- /* clean up guest state from pointing to host resource by
- * finding and removing DeviceState "drive" property */
+ /* if we have a device associated with this BlockDriverState (bs->peer)
+ * then we need to make the drive anonymous until the device
+ * 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 (bs->peer) {
- for (prop = bs->peer->info->props; prop && prop->name; prop++) {
- if (prop->info->type == PROP_TYPE_DRIVE) {
- ptr = qdev_get_prop_ptr(bs->peer, prop);
- if (*ptr == bs) {
- bdrv_detach(bs, bs->peer);
- *ptr = NULL;
- break;
- }
- }
- }
+ bdrv_make_anon(bs);
+ } else {
+ drive_uninit(drive_get_by_blockdev(bs));
}
- /* clean up host side */
- drive_uninit(drive_get_by_blockdev(bs));
-
return 0;
}