+++ /dev/null
-From 621e6e6521a550fd3be48ee33b0d1e9a39c0ed5c Mon Sep 17 00:00:00 2001
-From: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Date: Wed, 9 Dec 2015 15:04:57 +0100
-Subject: [PATCH 15/55] backup: modify job api
-
-Introduces a BackupDump function callback and a pause_count
-for backup_start. For a dump-backup the target parameter
-can now be NULL so access to target needs to be guarded now.
----
- block/backup.c | 90 ++++++++++++++++++++++++++++++-----------------
- blockdev.c | 6 ++--
- include/block/block_int.h | 5 +++
- 3 files changed, 65 insertions(+), 36 deletions(-)
-
-diff --git a/block/backup.c b/block/backup.c
-index 370c285..c38b520 100644
---- a/block/backup.c
-+++ b/block/backup.c
-@@ -41,6 +41,7 @@ typedef struct BackupBlockJob {
- BdrvDirtyBitmap *sync_bitmap;
- MirrorSyncMode sync_mode;
- RateLimit limit;
-+ BackupDumpFunc *dump_cb;
- BlockdevOnError on_source_error;
- BlockdevOnError on_target_error;
- CoRwlock flush_rwlock;
-@@ -153,14 +154,21 @@ static int coroutine_fn backup_do_cow(BlockDriverState *bs,
- goto out;
- }
-
-+ int64_t start_sec = start * sectors_per_cluster;
- if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
-- ret = bdrv_co_write_zeroes(job->target,
-- start * sectors_per_cluster,
-- n, BDRV_REQ_MAY_UNMAP);
-+ if (job->dump_cb) {
-+ ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, NULL);
-+ }
-+ if (job->target) {
-+ ret = bdrv_co_write_zeroes(job->target, start_sec, n, BDRV_REQ_MAY_UNMAP);
-+ }
- } else {
-- ret = bdrv_co_writev(job->target,
-- start * sectors_per_cluster, n,
-- &bounce_qiov);
-+ if (job->dump_cb) {
-+ ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, bounce_buffer);
-+ }
-+ if (job->target) {
-+ ret = bdrv_co_writev(job->target, start_sec, n, &bounce_qiov);
-+ }
- }
- if (ret < 0) {
- trace_backup_do_cow_write_fail(job, start, ret);
-@@ -222,7 +230,7 @@ static void backup_iostatus_reset(BlockJob *job)
- {
- BackupBlockJob *s = container_of(job, BackupBlockJob, common);
-
-- if (s->target->blk) {
-+ if (s->target && s->target->blk) {
- blk_iostatus_reset(s->target->blk);
- }
- }
-@@ -274,9 +282,11 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
- if (read) {
- return block_job_error_action(&job->common, job->common.bs,
- job->on_source_error, true, error);
-- } else {
-+ } else if (job->target) {
- return block_job_error_action(&job->common, job->target,
- job->on_target_error, false, error);
-+ } else {
-+ return BLOCK_ERROR_ACTION_REPORT;
- }
- }
-
-@@ -404,9 +414,12 @@ static void coroutine_fn backup_run(void *opaque)
-
- job->done_bitmap = bitmap_new(end);
-
-- if (target->blk) {
-- blk_set_on_error(target->blk, on_target_error, on_target_error);
-- blk_iostatus_enable(target->blk);
-+ if (target) {
-+ bdrv_set_enable_write_cache(target, true);
-+ if (target->blk) {
-+ blk_set_on_error(target->blk, on_target_error, on_target_error);
-+ blk_iostatus_enable(target->blk);
-+ }
- }
-
- bdrv_add_before_write_notifier(bs, &before_write);
-@@ -484,10 +497,12 @@ static void coroutine_fn backup_run(void *opaque)
- qemu_co_rwlock_unlock(&job->flush_rwlock);
- g_free(job->done_bitmap);
-
-- if (target->blk) {
-- blk_iostatus_disable(target->blk);
-+ if (target) {
-+ if (target->blk) {
-+ blk_iostatus_disable(target->blk);
-+ }
-+ bdrv_op_unblock_all(target, job->common.blocker);
- }
-- bdrv_op_unblock_all(target, job->common.blocker);
-
- data = g_malloc(sizeof(*data));
- data->ret = ret;
-@@ -499,7 +514,9 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
- BdrvDirtyBitmap *sync_bitmap,
- BlockdevOnError on_source_error,
- BlockdevOnError on_target_error,
-+ BackupDumpFunc *dump_cb,
- BlockCompletionFunc *cb, void *opaque,
-+ int pause_count,
- BlockJobTxn *txn, Error **errp)
- {
- int64_t len;
-@@ -508,7 +525,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
- int ret;
-
- assert(bs);
-- assert(target);
-+ assert(target || dump_cb);
- assert(cb);
-
- if (bs == target) {
-@@ -529,7 +546,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
- return;
- }
-
-- if (!bdrv_is_inserted(target)) {
-+ if (target && !bdrv_is_inserted(target)) {
- error_setg(errp, "Device is not inserted: %s",
- bdrv_get_device_name(target));
- return;
-@@ -539,7 +556,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
- return;
- }
-
-- if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
-+ if (target && bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
- return;
- }
-
-@@ -574,6 +591,7 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
- goto error;
- }
-
-+ job->dump_cb = dump_cb;
- job->on_source_error = on_source_error;
- job->on_target_error = on_target_error;
- job->target = target;
-@@ -581,25 +599,31 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
- job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?
- sync_bitmap : NULL;
-
-- /* If there is no backing file on the target, we cannot rely on COW if our
-- * backup cluster size is smaller than the target cluster size. Even for
-- * targets with a backing file, try to avoid COW if possible. */
-- ret = bdrv_get_info(job->target, &bdi);
-- if (ret < 0 && !target->backing) {
-- error_setg_errno(errp, -ret,
-- "Couldn't determine the cluster size of the target image, "
-- "which has no backing file");
-- error_append_hint(errp,
-- "Aborting, since this may create an unusable destination image\n");
-- goto error;
-- } else if (ret < 0 && target->backing) {
-- /* Not fatal; just trudge on ahead. */
-- job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
-+ if (target) {
-+ /* If there is no backing file on the target, we cannot rely on COW if our
-+ * backup cluster size is smaller than the target cluster size. Even for
-+ * targets with a backing file, try to avoid COW if possible. */
-+ ret = bdrv_get_info(job->target, &bdi);
-+ if (ret < 0 && !target->backing) {
-+ error_setg_errno(errp, -ret,
-+ "Couldn't determine the cluster size of the target image, "
-+ "which has no backing file");
-+ error_append_hint(errp,
-+ "Aborting, since this may create an unusable destination image\n");
-+ goto error;
-+ } else if (ret < 0 && target->backing) {
-+ /* Not fatal; just trudge on ahead. */
-+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
-+ } else {
-+ job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
-+ }
-+
-+ bdrv_op_block_all(target, job->common.blocker);
- } else {
-- job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
-+ job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;
- }
-
-- bdrv_op_block_all(target, job->common.blocker);
-+ job->common.pause_count = pause_count;
- job->common.len = len;
- job->common.co = qemu_coroutine_create(backup_run);
- block_job_txn_add_job(txn, &job->common);
-diff --git a/blockdev.c b/blockdev.c
-index 260a6f5..dfc5204 100644
---- a/blockdev.c
-+++ b/blockdev.c
-@@ -3292,8 +3292,8 @@ static void do_drive_backup(const char *device, const char *target,
- }
-
- backup_start(bs, target_bs, speed, sync, bmap,
-- on_source_error, on_target_error,
-- block_job_cb, bs, txn, &local_err);
-+ on_source_error, on_target_error, NULL,
-+ block_job_cb, bs, 0, txn, &local_err);
- if (local_err != NULL) {
- bdrv_unref(target_bs);
- error_propagate(errp, local_err);
-@@ -3382,7 +3382,7 @@ void do_blockdev_backup(const char *device, const char *target,
- bdrv_ref(target_bs);
- bdrv_set_aio_context(target_bs, aio_context);
- backup_start(bs, target_bs, speed, sync, NULL, on_source_error,
-- on_target_error, block_job_cb, bs, txn, &local_err);
-+ on_target_error, NULL, block_job_cb, bs, 0, txn, &local_err);
- if (local_err != NULL) {
- bdrv_unref(target_bs);
- error_propagate(errp, local_err);
-diff --git a/include/block/block_int.h b/include/block/block_int.h
-index 10d8759..2dd866b 100644
---- a/include/block/block_int.h
-+++ b/include/block/block_int.h
-@@ -60,6 +60,9 @@
-
- #define BLOCK_PROBE_BUF_SIZE 512
-
-+typedef int BackupDumpFunc(void *opaque, BlockDriverState *bs,
-+ int64_t sector_num, int n_sectors, unsigned char *buf);
-+
- enum BdrvTrackedRequestType {
- BDRV_TRACKED_READ,
- BDRV_TRACKED_WRITE,
-@@ -703,7 +706,9 @@ void backup_start(BlockDriverState *bs, BlockDriverState *target,
- BdrvDirtyBitmap *sync_bitmap,
- BlockdevOnError on_source_error,
- BlockdevOnError on_target_error,
-+ BackupDumpFunc *dump_cb,
- BlockCompletionFunc *cb, void *opaque,
-+ int pause_count,
- BlockJobTxn *txn, Error **errp);
-
- void hmp_drive_add_node(Monitor *mon, const char *optstr);
---
-2.1.4
-