block: Attach non-qdev devices as well

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 <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Markus Armbruster 2011-08-03 15:07:40 +02:00 committed by Kevin Wolf
parent 648fb0ea5e
commit fa879d62eb
12 changed files with 39 additions and 22 deletions

29
block.c
View File

@ -755,7 +755,7 @@ void bdrv_make_anon(BlockDriverState *bs)
void bdrv_delete(BlockDriverState *bs) void bdrv_delete(BlockDriverState *bs)
{ {
assert(!bs->peer); assert(!bs->dev);
/* remove from list, if necessary */ /* remove from list, if necessary */
bdrv_make_anon(bs); bdrv_make_anon(bs);
@ -769,26 +769,37 @@ void bdrv_delete(BlockDriverState *bs)
g_free(bs); g_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; return -EBUSY;
} }
bs->peer = qdev; bs->dev = dev;
return 0; 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); if (bdrv_attach_dev(bs, dev) < 0) {
bs->peer = NULL; 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_cb = NULL;
bs->change_opaque = 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;
} }
/* /*

View File

@ -74,9 +74,10 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
int bdrv_open(BlockDriverState *bs, const char *filename, int flags, int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
BlockDriver *drv); BlockDriver *drv);
void bdrv_close(BlockDriverState *bs); void bdrv_close(BlockDriverState *bs);
int bdrv_attach(BlockDriverState *bs, DeviceState *qdev); int bdrv_attach_dev(BlockDriverState *bs, void *dev);
void bdrv_detach(BlockDriverState *bs, DeviceState *qdev); void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev);
DeviceState *bdrv_get_attached(BlockDriverState *bs); void bdrv_detach_dev(BlockDriverState *bs, void *dev);
void *bdrv_get_attached_dev(BlockDriverState *bs);
int bdrv_read(BlockDriverState *bs, int64_t sector_num, int bdrv_read(BlockDriverState *bs, int64_t sector_num,
uint8_t *buf, int nb_sectors); uint8_t *buf, int nb_sectors);
int bdrv_write(BlockDriverState *bs, int64_t sector_num, int bdrv_write(BlockDriverState *bs, int64_t sector_num,

View File

@ -168,7 +168,8 @@ struct BlockDriverState {
BlockDriver *drv; /* NULL means no media */ BlockDriver *drv; /* NULL means no media */
void *opaque; void *opaque;
DeviceState *peer; void *dev; /* attached device model, if any */
/* TODO change to DeviceState when all users are qdevified */
char filename[1024]; char filename[1024];
char backing_file[1024]; /* if non zero, the image is a diff of char backing_file[1024]; /* if non zero, the image is a diff of

View File

@ -14,7 +14,6 @@
#include "qemu-option.h" #include "qemu-option.h"
#include "qemu-config.h" #include "qemu-config.h"
#include "sysemu.h" #include "sysemu.h"
#include "hw/qdev.h"
#include "block_int.h" #include "block_int.h"
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives); static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
@ -738,12 +737,12 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
bdrv_flush(bs); bdrv_flush(bs);
bdrv_close(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 * then we need to make the drive anonymous until the device
* can be removed. If this is a drive with no device backing * 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. * 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); bdrv_make_anon(bs);
} else { } else {
drive_uninit(drive_get_by_blockdev(bs)); drive_uninit(drive_get_by_blockdev(bs));

View File

@ -1890,6 +1890,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
error_report("Can't set up IDE drive %s", dinfo->id); error_report("Can't set up IDE drive %s", dinfo->id);
exit(1); exit(1);
} }
bdrv_attach_dev_nofail(dinfo->bdrv, &bus->ifs[i]);
} else { } else {
ide_reset(&bus->ifs[i]); ide_reset(&bus->ifs[i]);
} }

View File

@ -177,9 +177,9 @@ static int pci_piix3_xen_ide_unplug(DeviceState *dev)
for (; i < 3; i++) { for (; i < 3; i++) {
di = drive_get_by_index(IF_IDE, i); di = drive_get_by_index(IF_IDE, i);
if (di != NULL && di->bdrv != NULL && !di->bdrv->removable) { if (di != NULL && di->bdrv != NULL && !di->bdrv->removable) {
DeviceState *ds = bdrv_get_attached(di->bdrv); DeviceState *ds = bdrv_get_attached_dev(di->bdrv);
if (ds) { if (ds) {
bdrv_detach(di->bdrv, ds); bdrv_detach_dev(di->bdrv, ds);
} }
bdrv_close(di->bdrv); bdrv_close(di->bdrv);
pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;

View File

@ -620,6 +620,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
g_free(pfl); g_free(pfl);
return NULL; return NULL;
} }
bdrv_attach_dev_nofail(pfl->bs, pfl);
} }
#if 0 /* XXX: there should be a bit to set up read-only, #if 0 /* XXX: there should be a bit to set up read-only,
* the same way the hardware does (with WP pin). * the same way the hardware does (with WP pin).

View File

@ -643,6 +643,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
g_free(pfl); g_free(pfl);
return NULL; return NULL;
} }
bdrv_attach_dev_nofail(pfl->bs, pfl);
} }
#if 0 /* XXX: there should be a bit to set up read-only, #if 0 /* XXX: there should be a bit to set up read-only,
* the same way the hardware does (with WP pin). * the same way the hardware does (with WP pin).

View File

@ -312,7 +312,7 @@ static int parse_drive(DeviceState *dev, Property *prop, const char *str)
bs = bdrv_find(str); bs = bdrv_find(str);
if (bs == NULL) if (bs == NULL)
return -ENOENT; return -ENOENT;
if (bdrv_attach(bs, dev) < 0) if (bdrv_attach_dev(bs, dev) < 0)
return -EEXIST; return -EEXIST;
*ptr = bs; *ptr = bs;
return 0; return 0;
@ -323,7 +323,7 @@ static void free_drive(DeviceState *dev, Property *prop)
BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
if (*ptr) { if (*ptr) {
bdrv_detach(*ptr, dev); bdrv_detach_dev(*ptr, dev);
blockdev_auto_del(*ptr); blockdev_auto_del(*ptr);
} }
} }
@ -678,7 +678,7 @@ int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *va
{ {
int res; int res;
res = bdrv_attach(value, dev); res = bdrv_attach_dev(value, dev);
if (res < 0) { if (res < 0) {
error_report("Can't attach drive %s to %s.%s: %s", error_report("Can't attach drive %s to %s.%s: %s",
bdrv_get_device_name(value), bdrv_get_device_name(value),

View File

@ -449,6 +449,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi)
sd->enable = 1; sd->enable = 1;
sd_reset(sd, bs); sd_reset(sd, bs);
if (sd->bdrv) { if (sd->bdrv) {
bdrv_attach_dev_nofail(sd->bdrv, sd);
bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd); bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd);
} }
return sd; return sd;

View File

@ -518,7 +518,7 @@ static int usb_msd_initfn(USBDevice *dev)
* *
* The hack is probably a bad idea. * The hack is probably a bad idea.
*/ */
bdrv_detach(bs, &s->dev.qdev); bdrv_detach_dev(bs, &s->dev.qdev);
s->conf.bs = NULL; s->conf.bs = NULL;
if (!s->serial) { if (!s->serial) {

View File

@ -697,6 +697,7 @@ static int blk_init(struct XenDevice *xendev)
xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
blkdev->bs = blkdev->dinfo->bdrv; blkdev->bs = blkdev->dinfo->bdrv;
} }
bdrv_attach_dev_nofail(blkdev->bs, blkdev);
blkdev->file_blk = BLOCK_SIZE; blkdev->file_blk = BLOCK_SIZE;
blkdev->file_size = bdrv_getlength(blkdev->bs); blkdev->file_size = bdrv_getlength(blkdev->bs);
if (blkdev->file_size < 0) { if (blkdev->file_size < 0) {