break;
}
- case QTYPE_QINT: {
- int64_t length = qint_get_int(qobject_to_qint(entry->value));
+ case QTYPE_QNUM: {
+ int64_t length = qnum_get_int(qobject_to_qnum(entry->value));
+
if (length > 0 && length <= UINT_MAX) {
block_acct_add_interval(stats, (unsigned) length);
} else {
error_setg(errp, "Cannot specify both 'driver' and 'format'");
goto early_err;
}
- qdict_put(bs_opts, "driver", qstring_from_str(buf));
+ qdict_put_str(bs_opts, "driver", buf);
}
on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
autostart = 0;
}
- block_acct_init(blk_get_stats(blk), account_invalid, account_failed);
+ block_acct_setup(blk_get_stats(blk), account_invalid, account_failed);
if (!parse_stats_intervals(blk_get_stats(blk), interval_list, errp)) {
blk_unref(blk);
copy_on_read = false;
}
- qdict_put(bs_opts, BDRV_OPT_READ_ONLY,
- qstring_from_str(read_only ? "on" : "off"));
- qdict_put(bs_opts, "copy-on-read",
- qstring_from_str(copy_on_read ? "on" :"off"));
+ qdict_put_str(bs_opts, BDRV_OPT_READ_ONLY, read_only ? "on" : "off");
+ qdict_put_str(bs_opts, "copy-on-read", copy_on_read ? "on" : "off");
/* Controller type */
value = qemu_opt_get(legacy_opts, "if");
new_id = g_strdup_printf("%s%s%i", if_name[type],
mediastr, unit_id);
}
- qdict_put(bs_opts, "id", qstring_from_str(new_id));
+ qdict_put_str(bs_opts, "id", new_id);
g_free(new_id);
}
error_report("werror is not supported by this bus type");
goto fail;
}
- qdict_put(bs_opts, "werror", qstring_from_str(werror));
+ qdict_put_str(bs_opts, "werror", werror);
}
rerror = qemu_opt_get(legacy_opts, "rerror");
error_report("rerror is not supported by this bus type");
goto fail;
}
- qdict_put(bs_opts, "rerror", qstring_from_str(rerror));
+ qdict_put_str(bs_opts, "rerror", rerror);
}
/* Actual block device init: Functionality shared with blockdev-add */
static BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
const char *name,
BlockDriverState **pbs,
- AioContext **paio,
Error **errp)
{
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
- AioContext *aio_context;
if (!node) {
error_setg(errp, "Node cannot be NULL");
return NULL;
}
- aio_context = bdrv_get_aio_context(bs);
- aio_context_acquire(aio_context);
-
bitmap = bdrv_find_dirty_bitmap(bs, name);
if (!bitmap) {
error_setg(errp, "Dirty bitmap '%s' not found", name);
- goto fail;
+ return NULL;
}
if (pbs) {
*pbs = bs;
}
- if (paio) {
- *paio = aio_context;
- } else {
- aio_context_release(aio_context);
- }
return bitmap;
-
- fail:
- aio_context_release(aio_context);
- return NULL;
}
/* New and old BlockDriverState structs for atomic group operations */
BlockDriverState *old_bs;
BlockDriverState *new_bs;
AioContext *aio_context;
+ bool overlay_appended;
} ExternalSnapshotState;
static void external_snapshot_prepare(BlkActionState *common,
bdrv_img_create(new_image_file, format,
state->old_bs->filename,
state->old_bs->drv->format_name,
- NULL, size, flags, &local_err, false);
+ NULL, size, flags, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
options = qdict_new();
if (s->has_snapshot_node_name) {
- qdict_put(options, "node-name",
- qstring_from_str(snapshot_node_name));
+ qdict_put_str(options, "node-name", snapshot_node_name);
}
- qdict_put(options, "driver", qstring_from_str(format));
+ qdict_put_str(options, "driver", format);
flags |= BDRV_O_NO_BACKING;
}
return;
}
+ bdrv_set_aio_context(state->new_bs, state->aio_context);
+
/* This removes our old bs and adds the new bs. This is an operation that
* can fail, so we need to do it in .prepare; undoing it for abort is
* always possible. */
error_propagate(errp, local_err);
return;
}
+ state->overlay_appended = true;
}
static void external_snapshot_commit(BlkActionState *common)
ExternalSnapshotState *state =
DO_UPCAST(ExternalSnapshotState, common, common);
- bdrv_set_aio_context(state->new_bs, state->aio_context);
-
/* We don't need (or want) to use the transactional
* bdrv_reopen_multiple() across all the entries at once, because we
* don't want to abort all of them if one of them fails the reopen */
- if (!state->old_bs->copy_on_read) {
+ if (!atomic_read(&state->old_bs->copy_on_read)) {
bdrv_reopen(state->old_bs, state->old_bs->open_flags & ~BDRV_O_RDWR,
NULL);
}
ExternalSnapshotState *state =
DO_UPCAST(ExternalSnapshotState, common, common);
if (state->new_bs) {
- if (state->new_bs->backing) {
- bdrv_replace_in_backing_chain(state->new_bs, state->old_bs);
+ if (state->overlay_appended) {
+ bdrv_ref(state->old_bs); /* we can't let bdrv_set_backind_hd()
+ close state->old_bs; we need it */
+ bdrv_set_backing_hd(state->new_bs, NULL, &error_abort);
+ bdrv_replace_node(state->new_bs, state->old_bs, &error_abort);
+ bdrv_unref(state->old_bs); /* bdrv_replace_node() ref'ed old_bs */
}
}
}
state->bitmap = block_dirty_bitmap_lookup(action->node,
action->name,
&state->bs,
- &state->aio_context,
errp);
if (!state->bitmap) {
return;
BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
common, common);
- bdrv_undo_clear_dirty_bitmap(state->bitmap, state->backup);
+ if (state->backup) {
+ bdrv_undo_clear_dirty_bitmap(state->bitmap, state->backup);
+ }
}
static void block_dirty_bitmap_clear_commit(BlkActionState *common)
options = qdict_new();
detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
- qdict_put(options, "detect-zeroes",
- qstring_from_str(detect_zeroes ? "on" : "off"));
+ qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
if (has_format) {
- qdict_put(options, "driver", qstring_from_str(format));
+ qdict_put_str(options, "driver", format);
}
medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
bool has_granularity, uint32_t granularity,
Error **errp)
{
- AioContext *aio_context;
BlockDriverState *bs;
if (!name || name[0] == '\0') {
return;
}
- aio_context = bdrv_get_aio_context(bs);
- aio_context_acquire(aio_context);
-
if (has_granularity) {
if (granularity < 512 || !is_power_of_2(granularity)) {
error_setg(errp, "Granularity must be power of 2 "
"and at least 512");
- goto out;
+ return;
}
} else {
/* Default to cluster size, if available: */
}
bdrv_create_dirty_bitmap(bs, granularity, name, errp);
-
- out:
- aio_context_release(aio_context);
}
void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
Error **errp)
{
- AioContext *aio_context;
BlockDriverState *bs;
BdrvDirtyBitmap *bitmap;
- bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp);
+ bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
if (!bitmap || !bs) {
return;
}
error_setg(errp,
"Bitmap '%s' is currently frozen and cannot be removed",
name);
- goto out;
+ return;
}
bdrv_dirty_bitmap_make_anon(bitmap);
bdrv_release_dirty_bitmap(bs, bitmap);
-
- out:
- aio_context_release(aio_context);
}
/**
void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
Error **errp)
{
- AioContext *aio_context;
BdrvDirtyBitmap *bitmap;
BlockDriverState *bs;
- bitmap = block_dirty_bitmap_lookup(node, name, &bs, &aio_context, errp);
+ bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
if (!bitmap || !bs) {
return;
}
error_setg(errp,
"Bitmap '%s' is currently frozen and cannot be modified",
name);
- goto out;
+ return;
} else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
error_setg(errp,
"Bitmap '%s' is currently disabled and cannot be cleared",
name);
- goto out;
+ return;
}
bdrv_clear_dirty_bitmap(bitmap, NULL);
-
- out:
- aio_context_release(aio_context);
}
void hmp_drive_del(Monitor *mon, const QDict *qdict)
bs = bdrv_find_node(id);
if (bs) {
- qmp_x_blockdev_del(id, &local_err);
+ qmp_blockdev_del(id, &local_err);
if (local_err) {
error_report_err(local_err);
}
goto out;
}
- /* complete all in-flight operations before resizing the device */
- bdrv_drain_all();
-
- ret = blk_truncate(blk, size);
- switch (ret) {
- case 0:
- break;
- case -ENOMEDIUM:
- error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
- break;
- case -ENOTSUP:
- error_setg(errp, QERR_UNSUPPORTED);
- break;
- case -EACCES:
- error_setg(errp, "Device '%s' is read only", device);
- break;
- case -EBUSY:
- error_setg(errp, QERR_DEVICE_IN_USE, device);
- break;
- default:
- error_setg_errno(errp, -ret, "Could not resize");
- break;
- }
+ bdrv_drained_begin(bs);
+ ret = blk_truncate(blk, size, errp);
+ bdrv_drained_end(bs);
out:
blk_unref(blk);
}
commit_active_start(has_job_id ? job_id : NULL, bs, base_bs,
BLOCK_JOB_DEFAULT, speed, on_error,
- filter_node_name, NULL, NULL, &local_err, false);
+ filter_node_name, NULL, NULL, false, &local_err);
} else {
BlockDriverState *overlay_bs = bdrv_find_overlay(bs, top_bs);
if (bdrv_op_is_blocked(overlay_bs, BLOCK_OP_TYPE_COMMIT_TARGET, errp)) {
Error *local_err = NULL;
int flags;
int64_t size;
+ bool set_backing_hd = false;
if (!backup->has_speed) {
backup->speed = 0;
}
if (backup->sync == MIRROR_SYNC_MODE_NONE) {
source = bs;
+ flags |= BDRV_O_NO_BACKING;
+ set_backing_hd = true;
}
size = bdrv_getlength(bs);
if (source) {
bdrv_img_create(backup->target, backup->format, source->filename,
source->drv->format_name, NULL,
- size, flags, &local_err, false);
+ size, flags, false, &local_err);
} else {
bdrv_img_create(backup->target, backup->format, NULL, NULL, NULL,
- size, flags, &local_err, false);
+ size, flags, false, &local_err);
}
}
}
if (backup->format) {
- options = qdict_new();
- qdict_put(options, "driver", qstring_from_str(backup->format));
+ if (!options) {
+ options = qdict_new();
+ }
+ qdict_put_str(options, "driver", backup->format);
}
target_bs = bdrv_open(backup->target, NULL, options, flags, errp);
bdrv_set_aio_context(target_bs, aio_context);
+ if (set_backing_hd) {
+ bdrv_set_backing_hd(target_bs, source, &local_err);
+ if (local_err) {
+ bdrv_unref(target_bs);
+ goto out;
+ }
+ }
+
if (backup->has_bitmap) {
bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
if (!bmap) {
/* create new image w/o backing file */
assert(format);
bdrv_img_create(arg->target, format,
- NULL, NULL, NULL, size, flags, &local_err, false);
+ NULL, NULL, NULL, size, flags, false, &local_err);
} else {
switch (arg->mode) {
case NEW_IMAGE_MODE_EXISTING:
bdrv_img_create(arg->target, format,
source->filename,
source->drv->format_name,
- NULL, size, flags, &local_err, false);
+ NULL, size, flags, false, &local_err);
break;
default:
abort();
options = qdict_new();
if (arg->has_node_name) {
- qdict_put(options, "node-name", qstring_from_str(arg->node_name));
+ qdict_put_str(options, "node-name", arg->node_name);
}
if (format) {
- qdict_put(options, "driver", qstring_from_str(format));
+ qdict_put_str(options, "driver", format);
}
/* Mirroring takes care of copy-on-write using the source's backing
}
trace_qmp_block_job_resume(job);
- block_job_iostatus_reset(job);
block_job_user_resume(job);
aio_context_release(aio_context);
}
visit_free(v);
}
-void qmp_x_blockdev_del(const char *node_name, Error **errp)
+void qmp_blockdev_del(const char *node_name, Error **errp)
{
AioContext *aio_context;
BlockDriverState *bs;