1 Index: new/block/backup.c
2 ===================================================================
3 --- new.orig/block/backup.c 2013-12-05 08:18:53.000000000 +0100
4 +++ new/block/backup.c 2013-12-05 13:16:21.000000000 +0100
6 BlockDriverState *target;
7 MirrorSyncMode sync_mode;
9 + BackupDumpFunc *dump_cb;
10 BlockdevOnError on_source_error;
11 BlockdevOnError on_target_error;
12 CoRwlock flush_rwlock;
17 + int64_t start_sec = start * BACKUP_SECTORS_PER_CLUSTER;
18 if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
19 - ret = bdrv_co_write_zeroes(job->target,
20 - start * BACKUP_SECTORS_PER_CLUSTER, n);
22 + ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, NULL);
25 + ret = bdrv_co_write_zeroes(job->target, start_sec, n);
28 - ret = bdrv_co_writev(job->target,
29 - start * BACKUP_SECTORS_PER_CLUSTER, n,
32 + ret = job->dump_cb(job->common.opaque, job->target, start_sec, n, bounce_buffer);
35 + ret = bdrv_co_writev(job->target, start_sec, n, &bounce_qiov);
39 trace_backup_do_cow_write_fail(job, start, ret);
42 BackupBlockJob *s = container_of(job, BackupBlockJob, common);
44 - bdrv_iostatus_reset(s->target);
46 + bdrv_iostatus_reset(s->target);
50 static const BlockJobDriver backup_job_driver = {
53 return block_job_error_action(&job->common, job->common.bs,
54 job->on_source_error, true, error);
56 + } else if (job->target) {
57 return block_job_error_action(&job->common, job->target,
58 job->on_target_error, false, error);
60 + return BDRV_ACTION_REPORT;
66 job->bitmap = hbitmap_alloc(end, 0);
68 - bdrv_set_enable_write_cache(target, true);
69 - bdrv_set_on_error(target, on_target_error, on_target_error);
70 - bdrv_iostatus_enable(target);
72 + bdrv_set_enable_write_cache(target, true);
73 + bdrv_set_on_error(target, on_target_error, on_target_error);
74 + bdrv_iostatus_enable(target);
77 bdrv_add_before_write_notifier(bs, &before_write);
81 hbitmap_free(job->bitmap);
83 - bdrv_iostatus_disable(target);
86 + bdrv_iostatus_disable(target);
90 block_job_completed(&job->common, ret);
93 int64_t speed, MirrorSyncMode sync_mode,
94 BlockdevOnError on_source_error,
95 BlockdevOnError on_target_error,
96 + BackupDumpFunc *dump_cb,
97 BlockDriverCompletionFunc *cb, void *opaque,
105 + assert(target || dump_cb);
108 if ((on_source_error == BLOCKDEV_ON_ERROR_STOP ||
109 @@ -376,10 +395,12 @@
113 + job->dump_cb = dump_cb;
114 job->on_source_error = on_source_error;
115 job->on_target_error = on_target_error;
116 job->target = target;
117 job->sync_mode = sync_mode;
118 + job->common.paused = paused;
119 job->common.len = len;
120 job->common.co = qemu_coroutine_create(backup_run);
121 qemu_coroutine_enter(job->common.co, job);
122 Index: new/blockdev.c
123 ===================================================================
124 --- new.orig/blockdev.c 2013-12-05 08:18:53.000000000 +0100
125 +++ new/blockdev.c 2013-12-05 13:07:43.000000000 +0100
126 @@ -1932,7 +1932,7 @@
129 backup_start(bs, target_bs, speed, sync, on_source_error, on_target_error,
130 - block_job_cb, bs, &local_err);
131 + NULL, block_job_cb, bs, false, &local_err);
132 if (local_err != NULL) {
133 bdrv_unref(target_bs);
134 error_propagate(errp, local_err);
135 Index: new/include/block/block_int.h
136 ===================================================================
137 --- new.orig/include/block/block_int.h 2013-12-05 08:18:53.000000000 +0100
138 +++ new/include/block/block_int.h 2013-12-05 13:16:53.000000000 +0100
140 #define BLOCK_OPT_LAZY_REFCOUNTS "lazy_refcounts"
141 #define BLOCK_OPT_ADAPTER_TYPE "adapter_type"
143 +typedef int BackupDumpFunc(void *opaque, BlockDriverState *bs,
144 + int64_t sector_num, int n_sectors, unsigned char *buf);
146 typedef struct BdrvTrackedRequest {
147 BlockDriverState *bs;
150 int64_t speed, MirrorSyncMode sync_mode,
151 BlockdevOnError on_source_error,
152 BlockdevOnError on_target_error,
153 + BackupDumpFunc *dump_cb,
154 BlockDriverCompletionFunc *cb, void *opaque,
158 #endif /* BLOCK_INT_H */