X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/4c55b1d0bad8a703f0499fe62e3761a0cd288da3..c0e9067902a35f4b5cc24b0bc84dbc5872e9cf86:/blockdev.c diff --git a/blockdev.c b/blockdev.c index 64282065d8..f92dcf24bf 100644 --- a/blockdev.c +++ b/blockdev.c @@ -334,8 +334,9 @@ static bool parse_stats_intervals(BlockAcctStats *stats, QList *intervals, 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 { @@ -527,7 +528,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, 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; @@ -595,7 +596,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, 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); @@ -903,10 +904,8 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) 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"); @@ -1030,7 +1029,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) 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); } @@ -1067,7 +1066,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) 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"); @@ -1077,7 +1076,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type) 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 */ @@ -1364,12 +1363,10 @@ out_aio_context: 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"); @@ -1385,29 +1382,17 @@ static BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node, 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 */ @@ -1737,10 +1722,9 @@ static void external_snapshot_prepare(BlkActionState *common, 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; } @@ -1794,7 +1778,7 @@ static void external_snapshot_commit(BlkActionState *common) /* 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); } @@ -1806,7 +1790,11 @@ static void external_snapshot_abort(BlkActionState *common) DO_UPCAST(ExternalSnapshotState, common, common); if (state->new_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 */ } } } @@ -2024,7 +2012,6 @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common, state->bitmap = block_dirty_bitmap_lookup(action->node, action->name, &state->bs, - &state->aio_context, errp); if (!state->bitmap) { return; @@ -2579,11 +2566,10 @@ void qmp_blockdev_change_medium(bool has_device, const char *device, 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); @@ -2733,7 +2719,6 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, bool has_granularity, uint32_t granularity, Error **errp) { - AioContext *aio_context; BlockDriverState *bs; if (!name || name[0] == '\0') { @@ -2746,14 +2731,11 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, 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: */ @@ -2761,19 +2743,15 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, } 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; } @@ -2782,13 +2760,10 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, 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); } /** @@ -2798,11 +2773,10 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, 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; } @@ -2811,18 +2785,15 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name, 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) @@ -2927,29 +2898,9 @@ void qmp_block_resize(bool has_device, const char *device, 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); @@ -3174,6 +3125,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn, Error *local_err = NULL; int flags; int64_t size; + bool set_backing_hd = false; if (!backup->has_speed) { backup->speed = 0; @@ -3224,6 +3176,8 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn, } if (backup->sync == MIRROR_SYNC_MODE_NONE) { source = bs; + flags |= BDRV_O_NO_BACKING; + set_backing_hd = true; } size = bdrv_getlength(bs); @@ -3250,8 +3204,10 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn, } 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); @@ -3261,6 +3217,14 @@ static BlockJob *do_drive_backup(DriveBackup *backup, BlockJobTxn *txn, 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) { @@ -3555,10 +3519,10 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) 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 @@ -3726,7 +3690,6 @@ void qmp_block_job_resume(const char *device, Error **errp) } trace_qmp_block_job_resume(job); - block_job_iostatus_reset(job); block_job_user_resume(job); aio_context_release(aio_context); }