Skip to content

Commit

Permalink
block: Attach non-qdev devices as well
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Markus Armbruster authored and kevmw committed Sep 6, 2011
1 parent 648fb0e commit fa879d6
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 22 deletions.
29 changes: 20 additions & 9 deletions block.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,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);
Expand All @@ -769,26 +769,37 @@ void bdrv_delete(BlockDriverState *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;
}
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;
}

/*
Expand Down
7 changes: 4 additions & 3 deletions block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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,
Expand Down
3 changes: 2 additions & 1 deletion block_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,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
Expand Down
5 changes: 2 additions & 3 deletions blockdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "qemu-option.h"
#include "qemu-config.h"
#include "sysemu.h"
#include "hw/qdev.h"
#include "block_int.h"

static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
Expand Down Expand Up @@ -738,12 +737,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));
Expand Down
1 change: 1 addition & 0 deletions hw/ide/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
exit(1);
}
bdrv_attach_dev_nofail(dinfo->bdrv, &bus->ifs[i]);
} else {
ide_reset(&bus->ifs[i]);
}
Expand Down
4 changes: 2 additions & 2 deletions hw/ide/piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ static int pci_piix3_xen_ide_unplug(DeviceState *dev)
for (; i < 3; i++) {
di = drive_get_by_index(IF_IDE, i);
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) {
bdrv_detach(di->bdrv, ds);
bdrv_detach_dev(di->bdrv, ds);
}
bdrv_close(di->bdrv);
pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;
Expand Down
1 change: 1 addition & 0 deletions hw/pflash_cfi01.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
g_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).
Expand Down
1 change: 1 addition & 0 deletions hw/pflash_cfi02.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
g_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).
Expand Down
6 changes: 3 additions & 3 deletions hw/qdev-properties.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -678,7 +678,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),
Expand Down
1 change: 1 addition & 0 deletions hw/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,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;
Expand Down
2 changes: 1 addition & 1 deletion hw/usb-msd.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,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) {
Expand Down
1 change: 1 addition & 0 deletions hw/xen_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,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) {
Expand Down

0 comments on commit fa879d6

Please sign in to comment.