From 0927138234bfd9a86869874acfd2216ffdbd6130 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 4 Oct 2011 16:24:18 +0200 Subject: [PATCH 43/76] block: Attach non-qdev devices as well RH-Author: Markus Armbruster Message-id: <1317745491-18401-36-git-send-email-armbru@redhat.com> Patchwork-id: 33625 O-Subject: [PATCH RHEL-6.2 qemu-kvm 35/68] block: Attach non-qdev devices as well Bugzilla: 742458 RH-Acked-by: Paolo Bonzini RH-Acked-by: Amit Shah RH-Acked-by: Juan Quintela For now, this just protects against programming errors like having the same drive back multiple non-qdev devices, or untimely bdrv_delete(). Later commits will add other interesting uses. While there, rename BlockDriverState member peer to dev, bdrv_attach() to bdrv_attach_dev(), bdrv_detach() to bdrv_detach_dev(), and bdrv_get_attached() to bdrv_get_attached_dev(). Signed-off-by: Markus Armbruster Signed-off-by: Kevin Wolf (cherry picked from commit fa879d62eb51253d00b6920ce1d1d9d261370a49) Conflicts: hw/ide/piix.c Conflicts because we don't have commit 679f4f8b xen: implement unplug protocol in xen_platform. Drop conflicting hunk. --- block.c | 29 ++++++++++++++++++++--------- block.h | 7 ++++--- block_int.h | 3 ++- blockdev.c | 5 ++--- hw/ide/core.c | 1 + hw/pflash_cfi01.c | 1 + hw/pflash_cfi02.c | 1 + hw/qdev-properties.c | 6 +++--- hw/sd.c | 1 + hw/usb-msd.c | 2 +- hw/xen_disk.c | 1 + 11 files changed, 37 insertions(+), 20 deletions(-) Signed-off-by: Michal Novotny --- block.c | 29 ++++++++++++++++++++--------- block.h | 7 ++++--- block_int.h | 3 ++- blockdev.c | 5 ++--- hw/ide/core.c | 1 + hw/pflash_cfi01.c | 1 + hw/pflash_cfi02.c | 1 + hw/qdev-properties.c | 6 +++--- hw/sd.c | 1 + hw/usb-msd.c | 2 +- hw/xen_disk.c | 1 + 11 files changed, 37 insertions(+), 20 deletions(-) diff --git a/block.c b/block.c index 90dea44..b5477d1 100644 --- a/block.c +++ b/block.c @@ -691,7 +691,7 @@ void bdrv_make_anon(BlockDriverState *bs) void bdrv_delete(BlockDriverState *bs) { - assert(!bs->peer); + assert(!bs->dev); /* remove from list, if necessary */ bdrv_make_anon(bs); @@ -705,26 +705,37 @@ void bdrv_delete(BlockDriverState *bs) qemu_free(bs); } -int bdrv_attach(BlockDriverState *bs, DeviceState *qdev) +int bdrv_attach_dev(BlockDriverState *bs, void *dev) +/* TODO change to DeviceState *dev when all users are qdevified */ { - if (bs->peer) { + if (bs->dev) { return -EBUSY; } - bs->peer = qdev; + bs->dev = dev; return 0; } -void bdrv_detach(BlockDriverState *bs, DeviceState *qdev) +/* TODO qdevified devices don't use this, remove when devices are qdevified */ +void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev) { - assert(bs->peer == qdev); - bs->peer = NULL; + 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->change_cb = NULL; bs->change_opaque = NULL; } -DeviceState *bdrv_get_attached(BlockDriverState *bs) +/* TODO change to return DeviceState * when all users are qdevified */ +void *bdrv_get_attached_dev(BlockDriverState *bs) { - return bs->peer; + return bs->dev; } /* diff --git a/block.h b/block.h index 1594049..73a3c49 100644 --- a/block.h +++ b/block.h @@ -77,9 +77,10 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags); int bdrv_open(BlockDriverState *bs, const char *filename, int flags, BlockDriver *drv); void bdrv_close(BlockDriverState *bs); -int bdrv_attach(BlockDriverState *bs, DeviceState *qdev); -void bdrv_detach(BlockDriverState *bs, DeviceState *qdev); -DeviceState *bdrv_get_attached(BlockDriverState *bs); +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); int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors); int bdrv_write(BlockDriverState *bs, int64_t sector_num, diff --git a/block_int.h b/block_int.h index d8a2962..ab7fa1a 100644 --- a/block_int.h +++ b/block_int.h @@ -161,7 +161,8 @@ struct BlockDriverState { BlockDriver *drv; /* NULL means no media */ void *opaque; - DeviceState *peer; + void *dev; /* attached device model, if any */ + /* TODO change to DeviceState when all users are qdevified */ char filename[1024]; char backing_file[1024]; /* if non zero, the image is a diff of diff --git a/blockdev.c b/blockdev.c index 0578a58..4c0e24e 100644 --- a/blockdev.c +++ b/blockdev.c @@ -14,7 +14,6 @@ #include "qemu-option.h" #include "qemu-config.h" #include "sysemu.h" -#include "hw/qdev.h" #include "block_int.h" #include "qjson.h" @@ -1013,12 +1012,12 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) bdrv_flush(bs); bdrv_close(bs); - /* if we have a device associated with this BlockDriverState (bs->peer) + /* if we have a device attached to this BlockDriverState * 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) { + if (bdrv_get_attached_dev(bs)) { bdrv_make_anon(bs); } else { drive_uninit(drive_get_by_blockdev(bs)); diff --git a/hw/ide/core.c b/hw/ide/core.c index dce943f..b40db8c 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -1852,6 +1852,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, error_report("Can't set up IDE drive %s", dinfo->id); exit(1); } + bdrv_attach_dev_nofail(dinfo->bdrv, &bus->ifs[i]); } else { ide_reset(&bus->ifs[i]); } diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c index dfdced9..9b829fa 100644 --- a/hw/pflash_cfi01.c +++ b/hw/pflash_cfi01.c @@ -538,6 +538,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off, qemu_free(pfl); return NULL; } + bdrv_attach_dev_nofail(pfl->bs, pfl); } #if 0 /* XXX: there should be a bit to set up read-only, * the same way the hardware does (with WP pin). diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index 135c850..ef8ccc1 100644 --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -575,6 +575,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off, qemu_free(pfl); return NULL; } + bdrv_attach_dev_nofail(pfl->bs, pfl); } #if 0 /* XXX: there should be a bit to set up read-only, * the same way the hardware does (with WP pin). diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index e625fd0..0851d31 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -312,7 +312,7 @@ static int parse_drive(DeviceState *dev, Property *prop, const char *str) bs = bdrv_find(str); if (bs == NULL) return -ENOENT; - if (bdrv_attach(bs, dev) < 0) + if (bdrv_attach_dev(bs, dev) < 0) return -EEXIST; *ptr = bs; return 0; @@ -323,7 +323,7 @@ static void free_drive(DeviceState *dev, Property *prop) BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); if (*ptr) { - bdrv_detach(*ptr, dev); + bdrv_detach_dev(*ptr, dev); blockdev_auto_del(*ptr); } } @@ -675,7 +675,7 @@ int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *va { int res; - res = bdrv_attach(value, dev); + res = bdrv_attach_dev(value, dev); if (res < 0) { error_report("Can't attach drive %s to %s.%s: %s", bdrv_get_device_name(value), diff --git a/hw/sd.c b/hw/sd.c index b827a4c..785bd3c 100644 --- a/hw/sd.c +++ b/hw/sd.c @@ -451,6 +451,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi) sd->enable = 1; sd_reset(sd, bs); if (sd->bdrv) { + bdrv_attach_dev_nofail(sd->bdrv, sd); bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd); } return sd; diff --git a/hw/usb-msd.c b/hw/usb-msd.c index ed7e0fa..30e103b 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -526,7 +526,7 @@ static int usb_msd_initfn(USBDevice *dev) * * The hack is probably a bad idea. */ - bdrv_detach(bs, &s->dev.qdev); + bdrv_detach_dev(bs, &s->dev.qdev); s->conf.bs = NULL; if (!s->serial) { diff --git a/hw/xen_disk.c b/hw/xen_disk.c index 1201198..66f35ed 100644 --- a/hw/xen_disk.c +++ b/hw/xen_disk.c @@ -647,6 +647,7 @@ static int blk_init(struct XenDevice *xendev) xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); blkdev->bs = blkdev->dinfo->bdrv; } + bdrv_attach_dev_nofail(blkdev->bs, blkdev); blkdev->file_blk = BLOCK_SIZE; blkdev->file_size = bdrv_getlength(blkdev->bs); if (blkdev->file_size < 0) { -- 1.7.4.4