Revision 14bafc54

b/blockdev.c
17 17

  
18 18
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
19 19

  
20
/*
21
 * We automatically delete the drive when a device using it gets
22
 * unplugged.  Questionable feature, but we can't just drop it.
23
 * Device models call blockdev_mark_auto_del() to schedule the
24
 * automatic deletion, and generic qdev code calls blockdev_auto_del()
25
 * when deletion is actually safe.
26
 */
27
void blockdev_mark_auto_del(BlockDriverState *bs)
28
{
29
    DriveInfo *dinfo = drive_get_by_blockdev(bs);
30

  
31
    dinfo->auto_del = 1;
32
}
33

  
34
void blockdev_auto_del(BlockDriverState *bs)
35
{
36
    DriveInfo *dinfo = drive_get_by_blockdev(bs);
37

  
38
    if (dinfo->auto_del) {
39
        drive_uninit(dinfo);
40
    }
41
}
42

  
20 43
QemuOpts *drive_add(const char *file, const char *fmt, ...)
21 44
{
22 45
    va_list ap;
b/blockdev.h
13 13
#include "block.h"
14 14
#include "qemu-queue.h"
15 15

  
16
void blockdev_mark_auto_del(BlockDriverState *bs);
17
void blockdev_auto_del(BlockDriverState *bs);
18

  
16 19
typedef enum {
17 20
    IF_NONE,
18 21
    IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
......
28 31
    BlockInterfaceType type;
29 32
    int bus;
30 33
    int unit;
34
    int auto_del;               /* see blockdev_mark_auto_del() */
31 35
    QemuOpts *opts;
32 36
    char serial[BLOCK_SERIAL_STRLEN + 1];
33 37
    QTAILQ_ENTRY(DriveInfo) next;
b/hw/qdev-properties.c
313 313
    return 0;
314 314
}
315 315

  
316
static void free_drive(DeviceState *dev, Property *prop)
317
{
318
    DriveInfo **ptr = qdev_get_prop_ptr(dev, prop);
319

  
320
    if (*ptr) {
321
        blockdev_auto_del((*ptr)->bdrv);
322
    }
323
}
324

  
316 325
static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
317 326
{
318 327
    DriveInfo **ptr = qdev_get_prop_ptr(dev, prop);
......
325 334
    .size  = sizeof(DriveInfo*),
326 335
    .parse = parse_drive,
327 336
    .print = print_drive,
337
    .free  = free_drive,
328 338
};
329 339

  
330 340
/* --- character device --- */
b/hw/scsi-disk.c
1043 1043
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1044 1044

  
1045 1045
    scsi_disk_purge_requests(s);
1046
    drive_uninit(s->qdev.conf.dinfo);
1046
    blockdev_mark_auto_del(s->qdev.conf.dinfo->bdrv);
1047 1047
}
1048 1048

  
1049 1049
static int scsi_disk_initfn(SCSIDevice *dev)
b/hw/scsi-generic.c
453 453
        r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
454 454
        scsi_remove_request(r);
455 455
    }
456
    drive_uninit(s->qdev.conf.dinfo);
456
    blockdev_mark_auto_del(s->qdev.conf.dinfo->bdrv);
457 457
}
458 458

  
459 459
static int scsi_generic_initfn(SCSIDevice *dev)
b/hw/usb-msd.c
522 522
static int usb_msd_initfn(USBDevice *dev)
523 523
{
524 524
    MSDState *s = DO_UPCAST(MSDState, dev, dev);
525
    DriveInfo *dinfo = s->conf.dinfo;
525 526

  
526
    if (!s->conf.dinfo || !s->conf.dinfo->bdrv) {
527
    if (!dinfo || !dinfo->bdrv) {
527 528
        error_report("usb-msd: drive property not set");
528 529
        return -1;
529 530
    }
530 531

  
532
    /*
533
     * Hack alert: this pretends to be a block device, but it's really
534
     * a SCSI bus that can serve only a single device, which it
535
     * creates automatically.  Two drive properties pointing to the
536
     * same drive is not good: free_drive() dies for the second one.
537
     * Zap the one we're not going to use.
538
     *
539
     * The hack is probably a bad idea.
540
     */
541
    s->conf.dinfo = NULL;
542

  
531 543
    s->dev.speed = USB_SPEED_FULL;
532 544
    scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete);
533
    s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->conf.dinfo, 0);
545
    s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, dinfo, 0);
534 546
    if (!s->scsi_dev) {
535 547
        return -1;
536 548
    }
537 549
    s->bus.qbus.allow_hotplug = 0;
538 550
    usb_msd_handle_reset(dev);
539 551

  
540
    if (bdrv_key_required(s->conf.dinfo->bdrv)) {
552
    if (bdrv_key_required(dinfo->bdrv)) {
541 553
        if (cur_mon) {
542
            monitor_read_bdrv_key_start(cur_mon, s->conf.dinfo->bdrv,
554
            monitor_read_bdrv_key_start(cur_mon, dinfo->bdrv,
543 555
                                        usb_msd_password_cb, s);
544 556
            s->dev.auto_attach = 0;
545 557
        } else {
b/hw/virtio-pci.c
571 571
{
572 572
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
573 573

  
574
    drive_uninit(proxy->block.dinfo);
574
    blockdev_mark_auto_del(proxy->block.dinfo->bdrv);
575 575
    return virtio_exit_pci(pci_dev);
576 576
}
577 577

  

Also available in: Unified diff