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:
		
							parent
							
								
									648fb0ea5e
								
							
						
					
					
						commit
						fa879d62eb
					
				
							
								
								
									
										29
									
								
								block.c
								
								
								
								
							
							
						
						
									
										29
									
								
								block.c
								
								
								
								
							| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								block.h
								
								
								
								
							
							
						
						
									
										7
									
								
								block.h
								
								
								
								
							| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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).
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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).
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								hw/sd.c
								
								
								
								
							
							
						
						
									
										1
									
								
								hw/sd.c
								
								
								
								
							| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue