block: Prepare for NULL BDS
blk_bs() will not necessarily return a non-NULL value any more (unless blk_is_available() is true or it can be assumed to otherwise, e.g. because it is called immediately after a successful blk_new_with_bs() or blk_new_open()). Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									0c3c36d651
								
							
						
					
					
						commit
						5433c24f0f
					
				
							
								
								
									
										5
									
								
								block.c
								
								
								
								
							
							
						
						
									
										5
									
								
								block.c
								
								
								
								
							| 
						 | 
				
			
			@ -2683,6 +2683,11 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
 | 
			
		|||
        blk = blk_by_name(device);
 | 
			
		||||
 | 
			
		||||
        if (blk) {
 | 
			
		||||
            if (!blk_bs(blk)) {
 | 
			
		||||
                error_setg(errp, "Device '%s' has no medium", device);
 | 
			
		||||
                return NULL;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return blk_bs(blk);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -306,12 +306,12 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
 | 
			
		|||
        info->io_status = blk_iostatus(blk);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!QLIST_EMPTY(&bs->dirty_bitmaps)) {
 | 
			
		||||
    if (bs && !QLIST_EMPTY(&bs->dirty_bitmaps)) {
 | 
			
		||||
        info->has_dirty_bitmaps = true;
 | 
			
		||||
        info->dirty_bitmaps = bdrv_query_dirty_bitmaps(bs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (bs->drv) {
 | 
			
		||||
    if (bs && bs->drv) {
 | 
			
		||||
        info->has_inserted = true;
 | 
			
		||||
        info->inserted = bdrv_block_device_info(bs, errp);
 | 
			
		||||
        if (info->inserted == NULL) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										204
									
								
								blockdev.c
								
								
								
								
							
							
						
						
									
										204
									
								
								blockdev.c
								
								
								
								
							| 
						 | 
				
			
			@ -124,15 +124,17 @@ void blockdev_mark_auto_del(BlockBackend *blk)
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
    if (bs) {
 | 
			
		||||
        aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
        aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    if (bs->job) {
 | 
			
		||||
        block_job_cancel(bs->job);
 | 
			
		||||
        if (bs->job) {
 | 
			
		||||
            block_job_cancel(bs->job);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        aio_context_release(aio_context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context_release(aio_context);
 | 
			
		||||
 | 
			
		||||
    dinfo->auto_del = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -229,8 +231,8 @@ bool drive_check_orphaned(void)
 | 
			
		|||
            dinfo->type != IF_NONE) {
 | 
			
		||||
            fprintf(stderr, "Warning: Orphaned drive without device: "
 | 
			
		||||
                    "id=%s,file=%s,if=%s,bus=%d,unit=%d\n",
 | 
			
		||||
                    blk_name(blk), blk_bs(blk)->filename, if_name[dinfo->type],
 | 
			
		||||
                    dinfo->bus, dinfo->unit);
 | 
			
		||||
                    blk_name(blk), blk_bs(blk) ? blk_bs(blk)->filename : "",
 | 
			
		||||
                    if_name[dinfo->type], dinfo->bus, dinfo->unit);
 | 
			
		||||
            rs = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1038,6 +1040,10 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
 | 
			
		|||
            monitor_printf(mon, "Device '%s' not found\n", device);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (!blk_is_available(blk)) {
 | 
			
		||||
            monitor_printf(mon, "Device '%s' has no medium\n", device);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        ret = bdrv_commit(blk_bs(blk));
 | 
			
		||||
    }
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1117,7 +1123,9 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
 | 
			
		|||
                  "Device '%s' not found", device);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    if (!has_id) {
 | 
			
		||||
        id = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1129,11 +1137,14 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
 | 
			
		|||
 | 
			
		||||
    if (!id && !name) {
 | 
			
		||||
        error_setg(errp, "Name or id must be provided");
 | 
			
		||||
        return NULL;
 | 
			
		||||
        goto out_aio_context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        error_setg(errp, "Device '%s' has no medium", device);
 | 
			
		||||
        goto out_aio_context;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, errp)) {
 | 
			
		||||
        goto out_aio_context;
 | 
			
		||||
| 
						 | 
				
			
			@ -1307,16 +1318,16 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
 | 
			
		|||
                  "Device '%s' not found", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    /* AioContext is released in .clean() */
 | 
			
		||||
    state->aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    state->aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(state->aio_context);
 | 
			
		||||
 | 
			
		||||
    if (!bdrv_is_inserted(bs)) {
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -1568,7 +1579,6 @@ typedef struct DriveBackupState {
 | 
			
		|||
static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
    BlockBackend *blk;
 | 
			
		||||
    DriveBackup *backup;
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1582,10 +1592,9 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
 | 
			
		|||
                  "Device '%s' not found", backup->device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    /* AioContext is released in .clean() */
 | 
			
		||||
    state->aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    state->aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(state->aio_context);
 | 
			
		||||
 | 
			
		||||
    qmp_drive_backup(backup->device, backup->target,
 | 
			
		||||
| 
						 | 
				
			
			@ -1602,7 +1611,7 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state->bs = bs;
 | 
			
		||||
    state->bs = blk_bs(blk);
 | 
			
		||||
    state->job = state->bs->job;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1637,8 +1646,7 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
 | 
			
		|||
{
 | 
			
		||||
    BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);
 | 
			
		||||
    BlockdevBackup *backup;
 | 
			
		||||
    BlockDriverState *bs, *target;
 | 
			
		||||
    BlockBackend *blk;
 | 
			
		||||
    BlockBackend *blk, *target;
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
 | 
			
		||||
    assert(common->action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
 | 
			
		||||
| 
						 | 
				
			
			@ -1649,18 +1657,16 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
 | 
			
		|||
        error_setg(errp, "Device '%s' not found", backup->device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    blk = blk_by_name(backup->target);
 | 
			
		||||
    if (!blk) {
 | 
			
		||||
    target = blk_by_name(backup->target);
 | 
			
		||||
    if (!target) {
 | 
			
		||||
        error_setg(errp, "Device '%s' not found", backup->target);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    target = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    /* AioContext is released in .clean() */
 | 
			
		||||
    state->aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    if (state->aio_context != bdrv_get_aio_context(target)) {
 | 
			
		||||
    state->aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    if (state->aio_context != blk_get_aio_context(target)) {
 | 
			
		||||
        state->aio_context = NULL;
 | 
			
		||||
        error_setg(errp, "Backup between two IO threads is not implemented");
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -1678,7 +1684,7 @@ static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp)
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state->bs = bs;
 | 
			
		||||
    state->bs = blk_bs(blk);
 | 
			
		||||
    state->job = state->bs->job;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1816,6 +1822,11 @@ static void eject_device(BlockBackend *blk, int force, Error **errp)
 | 
			
		|||
    BlockDriverState *bs = blk_bs(blk);
 | 
			
		||||
    AioContext *aio_context;
 | 
			
		||||
 | 
			
		||||
    if (!bs) {
 | 
			
		||||
        /* No medium inserted, so there is nothing to do */
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1882,7 +1893,8 @@ void qmp_block_passwd(bool has_device, const char *device,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* Assumes AioContext is held */
 | 
			
		||||
static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
 | 
			
		||||
static void qmp_bdrv_open_encrypted(BlockDriverState **pbs,
 | 
			
		||||
                                    const char *filename,
 | 
			
		||||
                                    int bdrv_flags, const char *format,
 | 
			
		||||
                                    const char *password, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1895,13 +1907,13 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
 | 
			
		|||
        qdict_put(options, "driver", qstring_from_str(format));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = bdrv_open(&bs, filename, NULL, options, bdrv_flags, &local_err);
 | 
			
		||||
    ret = bdrv_open(pbs, filename, NULL, options, bdrv_flags, &local_err);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        error_propagate(errp, local_err);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bdrv_add_key(bs, password, errp);
 | 
			
		||||
    bdrv_add_key(*pbs, password, errp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qmp_change_blockdev(const char *device, const char *filename,
 | 
			
		||||
| 
						 | 
				
			
			@ -1911,6 +1923,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
 | 
			
		|||
    BlockDriverState *bs;
 | 
			
		||||
    AioContext *aio_context;
 | 
			
		||||
    int bdrv_flags;
 | 
			
		||||
    bool new_bs;
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
 | 
			
		||||
    blk = blk_by_name(device);
 | 
			
		||||
| 
						 | 
				
			
			@ -1920,8 +1933,9 @@ void qmp_change_blockdev(const char *device, const char *filename,
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
    new_bs = !bs;
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    eject_device(blk, 0, &err);
 | 
			
		||||
| 
						 | 
				
			
			@ -1930,10 +1944,21 @@ void qmp_change_blockdev(const char *device, const char *filename,
 | 
			
		|||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
 | 
			
		||||
    bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
 | 
			
		||||
    bdrv_flags = blk_is_read_only(blk) ? 0 : BDRV_O_RDWR;
 | 
			
		||||
    bdrv_flags |= blk_get_root_state(blk)->open_flags & ~BDRV_O_RDWR;
 | 
			
		||||
 | 
			
		||||
    qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, format, NULL, errp);
 | 
			
		||||
    qmp_bdrv_open_encrypted(&bs, filename, bdrv_flags, format, NULL, &err);
 | 
			
		||||
    if (err) {
 | 
			
		||||
        error_propagate(errp, err);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (new_bs) {
 | 
			
		||||
        blk_insert_bs(blk, bs);
 | 
			
		||||
        /* Has been sent automatically by bdrv_open() if blk_bs(blk) was not
 | 
			
		||||
         * NULL */
 | 
			
		||||
        blk_dev_change_media_cb(blk, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    aio_context_release(aio_context);
 | 
			
		||||
| 
						 | 
				
			
			@ -1973,7 +1998,15 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
 | 
			
		|||
                  "Device '%s' not found", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
    if (!bs) {
 | 
			
		||||
        error_setg(errp, "Device '%s' has no medium", device);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memset(&cfg, 0, sizeof(cfg));
 | 
			
		||||
    cfg.buckets[THROTTLE_BPS_TOTAL].avg = bps;
 | 
			
		||||
| 
						 | 
				
			
			@ -2008,12 +2041,9 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    if (!check_throttle_config(&cfg, errp)) {
 | 
			
		||||
        return;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    if (throttle_enabled(&cfg)) {
 | 
			
		||||
        /* Enable I/O limits if they're not enabled yet, otherwise
 | 
			
		||||
         * just update the throttling group. */
 | 
			
		||||
| 
						 | 
				
			
			@ -2029,6 +2059,7 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
 | 
			
		|||
        bdrv_io_limits_disable(bs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    aio_context_release(aio_context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2141,7 +2172,6 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
 | 
			
		|||
        error_report("Device '%s' not found", id);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (!blk_legacy_dinfo(blk)) {
 | 
			
		||||
        error_report("Deleting device added with blockdev-add"
 | 
			
		||||
| 
						 | 
				
			
			@ -2149,16 +2179,19 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
 | 
			
		||||
        error_report_err(local_err);
 | 
			
		||||
        aio_context_release(aio_context);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
    if (bs) {
 | 
			
		||||
        if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
 | 
			
		||||
            error_report_err(local_err);
 | 
			
		||||
            aio_context_release(aio_context);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    bdrv_close(bs);
 | 
			
		||||
        bdrv_close(bs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* if we have a device attached to this BlockDriverState
 | 
			
		||||
     * then we need to make the drive anonymous until the device
 | 
			
		||||
| 
						 | 
				
			
			@ -2291,11 +2324,16 @@ void qmp_block_stream(const char *device,
 | 
			
		|||
                  "Device '%s' not found", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        error_setg(errp, "Device '%s' has no medium", device);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_STREAM, errp)) {
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2366,11 +2404,16 @@ void qmp_block_commit(const char *device,
 | 
			
		|||
                  "Device '%s' not found", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        error_setg(errp, "Device '%s' has no medium", device);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, errp)) {
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2476,17 +2519,17 @@ void qmp_drive_backup(const char *device, const char *target,
 | 
			
		|||
                  "Device '%s' not found", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    /* Although backup_run has this check too, we need to use bs->drv below, so
 | 
			
		||||
     * do an early check redundantly. */
 | 
			
		||||
    if (!bdrv_is_inserted(bs)) {
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (!has_format) {
 | 
			
		||||
        format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -2583,7 +2626,7 @@ void qmp_blockdev_backup(const char *device, const char *target,
 | 
			
		|||
                         BlockdevOnError on_target_error,
 | 
			
		||||
                         Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    BlockBackend *blk;
 | 
			
		||||
    BlockBackend *blk, *target_blk;
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
    BlockDriverState *target_bs;
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -2604,17 +2647,27 @@ void qmp_blockdev_backup(const char *device, const char *target,
 | 
			
		|||
        error_setg(errp, "Device '%s' not found", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    blk = blk_by_name(target);
 | 
			
		||||
    if (!blk) {
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        error_setg(errp, "Device '%s' has no medium", device);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    target_blk = blk_by_name(target);
 | 
			
		||||
    if (!target_blk) {
 | 
			
		||||
        error_setg(errp, "Device '%s' not found", target);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    target_bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (!blk_is_available(target_blk)) {
 | 
			
		||||
        error_setg(errp, "Device '%s' has no medium", target);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    target_bs = blk_bs(target_blk);
 | 
			
		||||
 | 
			
		||||
    bdrv_ref(target_bs);
 | 
			
		||||
    bdrv_set_aio_context(target_bs, aio_context);
 | 
			
		||||
| 
						 | 
				
			
			@ -2691,15 +2744,15 @@ void qmp_drive_mirror(const char *device, const char *target,
 | 
			
		|||
                  "Device '%s' not found", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    if (!bdrv_is_inserted(bs)) {
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (!has_format) {
 | 
			
		||||
        format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -2829,17 +2882,22 @@ static BlockJob *find_block_job(const char *device, AioContext **aio_context,
 | 
			
		|||
    BlockBackend *blk;
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
 | 
			
		||||
    *aio_context = NULL;
 | 
			
		||||
 | 
			
		||||
    blk = blk_by_name(device);
 | 
			
		||||
    if (!blk) {
 | 
			
		||||
        goto notfound;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    *aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    *aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(*aio_context);
 | 
			
		||||
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        goto notfound;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    if (!bs->job) {
 | 
			
		||||
        aio_context_release(*aio_context);
 | 
			
		||||
        goto notfound;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2848,7 +2906,10 @@ static BlockJob *find_block_job(const char *device, AioContext **aio_context,
 | 
			
		|||
notfound:
 | 
			
		||||
    error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
 | 
			
		||||
              "No active block job on device '%s'", device);
 | 
			
		||||
    *aio_context = NULL;
 | 
			
		||||
    if (*aio_context) {
 | 
			
		||||
        aio_context_release(*aio_context);
 | 
			
		||||
        *aio_context = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2955,11 +3016,16 @@ void qmp_change_backing_file(const char *device,
 | 
			
		|||
                  "Device '%s' not found", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    aio_context = bdrv_get_aio_context(bs);
 | 
			
		||||
    aio_context = blk_get_aio_context(blk);
 | 
			
		||||
    aio_context_acquire(aio_context);
 | 
			
		||||
 | 
			
		||||
    if (!blk_is_available(blk)) {
 | 
			
		||||
        error_setg(errp, "Device '%s' has no medium", device);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    bs = blk_bs(blk);
 | 
			
		||||
 | 
			
		||||
    image_bs = bdrv_lookup_bs(NULL, image_node_name, &local_err);
 | 
			
		||||
    if (local_err) {
 | 
			
		||||
        error_propagate(errp, local_err);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -931,9 +931,11 @@ static int blk_connect(struct XenDevice *xendev)
 | 
			
		|||
    blk_attach_dev_nofail(blkdev->blk, blkdev);
 | 
			
		||||
    blkdev->file_size = blk_getlength(blkdev->blk);
 | 
			
		||||
    if (blkdev->file_size < 0) {
 | 
			
		||||
        BlockDriverState *bs = blk_bs(blkdev->blk);
 | 
			
		||||
        const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
 | 
			
		||||
        xen_be_printf(&blkdev->xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
 | 
			
		||||
                      (int)blkdev->file_size, strerror(-blkdev->file_size),
 | 
			
		||||
                      bdrv_get_format_name(blk_bs(blkdev->blk)) ?: "-");
 | 
			
		||||
                      drv_name ?: "-");
 | 
			
		||||
        blkdev->file_size = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -808,6 +808,11 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		|||
                return -EINVAL;
 | 
			
		||||
            }
 | 
			
		||||
            bs = blk_bs(blk);
 | 
			
		||||
            if (!bs) {
 | 
			
		||||
                fprintf(stderr, "Block device %s has no medium\n",
 | 
			
		||||
                        device_name);
 | 
			
		||||
                return -EINVAL;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (bs != bs_prev) {
 | 
			
		||||
                bs_prev = bs;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4145,6 +4145,10 @@ int monitor_read_block_device_key(Monitor *mon, const char *device,
 | 
			
		|||
        monitor_printf(mon, "Device not found %s\n", device);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    if (!blk_bs(blk)) {
 | 
			
		||||
        monitor_printf(mon, "Device '%s' has no medium\n", device);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bdrv_add_key(blk_bs(blk), NULL, &err);
 | 
			
		||||
    if (err) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue