[pve-devel] [PATCH pve-qemu 2/3] update patches for 4.2

Stefan Reiter s.reiter at proxmox.com
Thu Feb 27 16:47:15 CET 2020


Changes aside from the general rebasing, renaming changed symbols and dropping
upstreamed extra/ patches:

* Backup code got split up to backup-top.c, block-copy.c, etc... so adjust ours
  to follow pace
* Patch "0036-avoid-calling-dump_cb-with-NULL-data-pointer-for-sma.patch" is
  removed, since that part of the code had to be rewritten entirely, and is
  replaced by "0049-call-dump_cb-with-NULL-for-empty-blocks.patch"
* Changes from "0041-PVE-backup-consider-source-cluster-size-as-well.patch" are
  now directly in "0021-PVE-Deprecated-adding-old-vma-files.patch", since it
  didn't apply cleanly and I wanted to avoid intentionally writing the code
  wrong again just to rebase the fix on my new incorrect code
* Patch "0050-fixup-backup-for-4.2.patch" fixes backups - the rebase alone makes
  it build, but it still crashes on backup without some API changes - this is
  probably the change to review the closest

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---

Explicitly tested with backups, snapshots and live-migration on LVM, ZFS, Ceph
RBD and CephFS with Linux and Windows VMs as well as nested configurations so
far.

I've also been using it on my workstation for a couple days now, and haven't had
any issues.


 ...sume-monitor-when-clearing-its-queue.patch |  45 ---
 ...ule-virtio_notify_config-to-run-on-m.patch |  76 ----
 ...k-file-change-locking-default-to-off.patch |   6 +-
 ...djust-network-script-path-to-etc-kvm.patch |   4 +-
 ...he-CPU-model-to-kvm64-32-instead-of-.patch |   4 +-
 ...ui-spice-default-to-pve-certificates.patch |   2 +-
 .../0005-PVE-Config-smm_available-false.patch |   4 +-
 ...erfs-no-default-logfile-if-daemonize.patch |   2 +-
 ...lock-rbd-disable-rbd_cache_writethro.patch |   4 +-
 .../0008-PVE-Up-qmp-add-get_link_status.patch |   8 +-
 ...PVE-Up-glusterfs-allow-partial-reads.patch |   6 +-
 ...return-success-on-info-without-snaps.patch |   4 +-
 ...dd-add-osize-and-read-from-to-stdin-.patch |  16 +-
 ...E-Up-qemu-img-dd-add-isize-parameter.patch |  12 +-
 ...PVE-Up-qemu-img-dd-add-n-skip_create.patch |  10 +-
 ...virtio-balloon-improve-query-balloon.patch |  10 +-
 .../0015-PVE-qapi-modify-query-machines.patch |  16 +-
 .../0016-PVE-qapi-modify-spice-query.patch    |   4 +-
 .../0017-PVE-internal-snapshot-async.patch    |  55 +--
 ...add-the-zeroinit-block-driver-filter.patch |   8 +-
 .../pve/0019-PVE-backup-modify-job-api.patch  |  53 ++-
 ...-backup-introduce-vma-archive-format.patch |  72 ++--
 ...-PVE-Deprecated-adding-old-vma-files.patch | 360 +++++++++---------
 ...-Add-dummy-id-command-line-parameter.patch |  10 +-
 ...t-target-i386-disable-LINT0-after-re.patch |   6 +-
 ...le-posix-make-locking-optiono-on-cre.patch |  20 +-
 ...c-kick-AIO-wait-on-block-state-write.patch |   4 +-
 ...ve-snapshot-cleanup-into-bottom-half.patch |   6 +-
 ...0-PVE-monitor-disable-oob-capability.patch |   4 +-
 ...ackup-related-code-inside-coroutines.patch |  75 ++--
 ...-CoMutex-to-protect-access-to-backup.patch |  46 +--
 ...ob_create-pass-cluster-size-for-dump.patch |  78 ++--
 ...mp_cb-with-NULL-data-pointer-for-sma.patch |  31 --
 ...to_vma-into-pvebackup_co_add_config.patch} |  10 +-
 ...p_co_dump_cb-do-not-call-job-cancel.patch} |   4 +-
 ...h => 0038-fix-backup-job-completion.patch} |   6 +-
 ...e_cb-avoid-poll-loop-if-already-ins.patch} |   6 +-
 ...ol.patch => 0040-PVE-fixup-vma-tool.patch} |   0
 ...consider-source-cluster-size-as-well.patch |  28 --
 ...v-pvebackup-integration-fix-blockjo.patch} |   6 +-
 ...xt-before-calling-block_job_add_bdr.patch} |   6 +-
 ...ed-balloon-qemu-4-0-config-size-fal.patch} |   4 +-
 ...-Allow-version-code-in-machine-type.patch} |  29 +-
 ...backup-cmd-for-not-initialized-back.patch} |   7 +-
 ...parate-CoRwlock-for-data-accessed-b.patch} |  43 +--
 ..._on_coroutine_wrapper-call-aio_wait.patch} |   7 +-
 ...backup_state.cancel-to-backup_state.patch} |   7 +-
 ...l-dump_cb-with-NULL-for-empty-blocks.patch |  40 ++
 .../pve/0050-fixup-backup-for-4.2.patch       | 285 ++++++++++++++
 debian/patches/series                         |  32 +-
 50 files changed, 846 insertions(+), 735 deletions(-)
 delete mode 100644 debian/patches/extra/0001-monitor-qmp-resume-monitor-when-clearing-its-queue.patch
 delete mode 100644 debian/patches/extra/0002-virtio-blk-schedule-virtio_notify_config-to-run-on-m.patch
 delete mode 100644 debian/patches/pve/0036-avoid-calling-dump_cb-with-NULL-data-pointer-for-sma.patch
 rename debian/patches/pve/{0037-rename-config_to_vma-into-pvebackup_co_add_config.patch => 0036-rename-config_to_vma-into-pvebackup_co_add_config.patch} (91%)
 rename debian/patches/pve/{0038-pvebackup_co_dump_cb-do-not-call-job-cancel.patch => 0037-pvebackup_co_dump_cb-do-not-call-job-cancel.patch} (90%)
 rename debian/patches/pve/{0039-fix-backup-job-completion.patch => 0038-fix-backup-job-completion.patch} (87%)
 rename debian/patches/pve/{0040-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch => 0039-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch} (88%)
 rename debian/patches/pve/{0042-PVE-fixup-vma-tool.patch => 0040-PVE-fixup-vma-tool.patch} (100%)
 delete mode 100644 debian/patches/pve/0041-PVE-backup-consider-source-cluster-size-as-well.patch
 rename debian/patches/pve/{0043-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch => 0041-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch} (95%)
 rename debian/patches/pve/{0044-Acquire-aio_context-before-calling-block_job_add_bdr.patch => 0042-Acquire-aio_context-before-calling-block_job_add_bdr.patch} (88%)
 rename debian/patches/pve/{0045-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch => 0043-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch} (95%)
 rename debian/patches/pve/{0046-PVE-Allow-version-code-in-machine-type.patch => 0044-PVE-Allow-version-code-in-machine-type.patch} (79%)
 rename debian/patches/pve/{0047-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch => 0045-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch} (87%)
 rename debian/patches/pve/{0048-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch => 0046-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch} (91%)
 rename debian/patches/pve/{0049-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch => 0047-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch} (80%)
 rename debian/patches/pve/{0050-PVE-backup-move-backup_state.cancel-to-backup_state.patch => 0048-PVE-backup-move-backup_state.cancel-to-backup_state.patch} (95%)
 create mode 100644 debian/patches/pve/0049-call-dump_cb-with-NULL-for-empty-blocks.patch
 create mode 100644 debian/patches/pve/0050-fixup-backup-for-4.2.patch

diff --git a/debian/patches/extra/0001-monitor-qmp-resume-monitor-when-clearing-its-queue.patch b/debian/patches/extra/0001-monitor-qmp-resume-monitor-when-clearing-its-queue.patch
deleted file mode 100644
index d07c251..0000000
--- a/debian/patches/extra/0001-monitor-qmp-resume-monitor-when-clearing-its-queue.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Wolfgang Bumiller <w.bumiller at proxmox.com>
-Date: Wed, 2 Oct 2019 10:30:03 +0200
-Subject: [PATCH] monitor/qmp: resume monitor when clearing its queue
-
-When a monitor's queue is filled up in handle_qmp_command()
-it gets suspended. It's the dispatcher bh's job currently to
-resume the monitor, which it does after processing an event
-from the queue. However, it is possible for a
-CHR_EVENT_CLOSED event to be processed before before the bh
-is scheduled, which will clear the queue without resuming
-the monitor, thereby preventing the dispatcher from reaching
-the resume() call.
-Fix this by resuming the monitor when clearing a queue which
-was filled up.
-
-Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
----
- monitor/qmp.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/monitor/qmp.c b/monitor/qmp.c
-index e1b196217d..fb3e66c62a 100644
---- a/monitor/qmp.c
-+++ b/monitor/qmp.c
-@@ -70,9 +70,19 @@ static void qmp_request_free(QMPRequest *req)
- /* Caller must hold mon->qmp.qmp_queue_lock */
- static void monitor_qmp_cleanup_req_queue_locked(MonitorQMP *mon)
- {
-+    bool need_resume = (!qmp_oob_enabled(mon) && mon->qmp_requests->length > 0)
-+        || mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX;
-     while (!g_queue_is_empty(mon->qmp_requests)) {
-         qmp_request_free(g_queue_pop_head(mon->qmp_requests));
-     }
-+    if (need_resume) {
-+        /*
-+         * Pairs with the monitor_suspend() in handle_qmp_command() in case the
-+         * queue gets cleared from a CH_EVENT_CLOSED event before the dispatch
-+         * bh got scheduled.
-+         */
-+        monitor_resume(&mon->common);
-+    }
- }
- 
- static void monitor_qmp_cleanup_queues(MonitorQMP *mon)
diff --git a/debian/patches/extra/0002-virtio-blk-schedule-virtio_notify_config-to-run-on-m.patch b/debian/patches/extra/0002-virtio-blk-schedule-virtio_notify_config-to-run-on-m.patch
deleted file mode 100644
index f20c7d7..0000000
--- a/debian/patches/extra/0002-virtio-blk-schedule-virtio_notify_config-to-run-on-m.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Sergio Lopez <slp at redhat.com>
-Date: Mon, 16 Sep 2019 13:24:12 +0200
-Subject: [PATCH] virtio-blk: schedule virtio_notify_config to run on main
- context
-
-virtio_notify_config() needs to acquire the global mutex, which isn't
-allowed from an iothread, and may lead to a deadlock like this:
-
- - main thead
-  * Has acquired: qemu_global_mutex.
-  * Is trying the acquire: iothread AioContext lock via
-    AIO_WAIT_WHILE (after aio_poll).
-
- - iothread
-  * Has acquired: AioContext lock.
-  * Is trying to acquire: qemu_global_mutex (via
-    virtio_notify_config->prepare_mmio_access).
-
-If virtio_blk_resize() is called from an iothread, schedule
-virtio_notify_config() to be run in the main context BH.
-
-[Removed unnecessary newline as suggested by Kevin Wolf
-<kwolf at redhat.com>.
---Stefan]
-
-Signed-off-by: Sergio Lopez <slp at redhat.com>
-Reviewed-by: Kevin Wolf <kwolf at redhat.com>
-Message-id: 20190916112411.21636-1-slp at redhat.com
-Message-Id: <20190916112411.21636-1-slp at redhat.com>
-Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
----
- hw/block/virtio-blk.c | 16 +++++++++++++++-
- 1 file changed, 15 insertions(+), 1 deletion(-)
-
-diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
-index cbb3729158..0d9adcdaff 100644
---- a/hw/block/virtio-blk.c
-+++ b/hw/block/virtio-blk.c
-@@ -16,6 +16,7 @@
- #include "qemu/iov.h"
- #include "qemu/module.h"
- #include "qemu/error-report.h"
-+#include "qemu/main-loop.h"
- #include "trace.h"
- #include "hw/block/block.h"
- #include "sysemu/blockdev.h"
-@@ -1082,11 +1083,24 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
-     return 0;
- }
- 
-+static void virtio_resize_cb(void *opaque)
-+{
-+    VirtIODevice *vdev = opaque;
-+
-+    assert(qemu_get_current_aio_context() == qemu_get_aio_context());
-+    virtio_notify_config(vdev);
-+}
-+
- static void virtio_blk_resize(void *opaque)
- {
-     VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
- 
--    virtio_notify_config(vdev);
-+    /*
-+     * virtio_notify_config() needs to acquire the global mutex,
-+     * so it can't be called from an iothread. Instead, schedule
-+     * it to be run in the main context BH.
-+     */
-+    aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev);
- }
- 
- static const BlockDevOps virtio_block_ops = {
--- 
-2.20.1
-
diff --git a/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch b/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
index a14d8c6..81ab870 100644
--- a/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
+++ b/debian/patches/pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/block/file-posix.c b/block/file-posix.c
-index 2184aa980c..71aa45ce5d 100644
+index 1b805bd938..44b49265ae 100644
 --- a/block/file-posix.c
 +++ b/block/file-posix.c
-@@ -444,7 +444,7 @@ static QemuOptsList raw_runtime_opts = {
+@@ -449,7 +449,7 @@ static QemuOptsList raw_runtime_opts = {
          {
              .name = "locking",
              .type = QEMU_OPT_STRING,
@@ -26,7 +26,7 @@ index 2184aa980c..71aa45ce5d 100644
          },
          {
              .name = "pr-manager",
-@@ -533,7 +533,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
+@@ -538,7 +538,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
          s->use_lock = false;
          break;
      case ON_OFF_AUTO_AUTO:
diff --git a/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch b/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
index a3630b7..3cc6e34 100644
--- a/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
+++ b/debian/patches/pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 3 insertions(+), 2 deletions(-)
 
 diff --git a/include/net/net.h b/include/net/net.h
-index acf0451fc4..4a64633577 100644
+index e175ba9677..5b9f099d21 100644
 --- a/include/net/net.h
 +++ b/include/net/net.h
-@@ -209,8 +209,9 @@ void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp);
+@@ -208,8 +208,9 @@ void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp);
  int net_hub_id_for_client(NetClientState *nc, int *id);
  NetClientState *net_hub_port_find(int hub_id);
  
diff --git a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
index 45decdf..84528ac 100644
--- a/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
+++ b/debian/patches/pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
@@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/target/i386/cpu.h b/target/i386/cpu.h
-index 8b3dc5533e..1fea162e02 100644
+index cde2a16b94..3e73104bf9 100644
 --- a/target/i386/cpu.h
 +++ b/target/i386/cpu.h
-@@ -1725,9 +1725,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
+@@ -1940,9 +1940,9 @@ uint64_t cpu_get_tsc(CPUX86State *env);
  #define CPU_RESOLVING_TYPE TYPE_X86_CPU
  
  #ifdef TARGET_X86_64
diff --git a/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch b/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
index 8f76010..7c6a756 100644
--- a/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
+++ b/debian/patches/pve/0004-PVE-Config-ui-spice-default-to-pve-certificates.patch
@@ -9,7 +9,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 9 insertions(+), 6 deletions(-)
 
 diff --git a/ui/spice-core.c b/ui/spice-core.c
-index 2ffc3335f0..c95bbd6c77 100644
+index ecc2ec2c55..ca04965ead 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
 @@ -668,32 +668,35 @@ void qemu_spice_init(void)
diff --git a/debian/patches/pve/0005-PVE-Config-smm_available-false.patch b/debian/patches/pve/0005-PVE-Config-smm_available-false.patch
index daf2e19..e519e9e 100644
--- a/debian/patches/pve/0005-PVE-Config-smm_available-false.patch
+++ b/debian/patches/pve/0005-PVE-Config-smm_available-false.patch
@@ -10,10 +10,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/hw/i386/pc.c b/hw/i386/pc.c
-index d011733ff7..e20e189a5f 100644
+index ac08e63604..4bd9ab52a0 100644
 --- a/hw/i386/pc.c
 +++ b/hw/i386/pc.c
-@@ -2723,7 +2723,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms)
+@@ -2040,7 +2040,7 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms)
      if (tcg_enabled() || qtest_enabled()) {
          smm_available = true;
      } else if (kvm_enabled()) {
diff --git a/debian/patches/pve/0006-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch b/debian/patches/pve/0006-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch
index f3c098b..22e6c1a 100644
--- a/debian/patches/pve/0006-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch
+++ b/debian/patches/pve/0006-PVE-Config-glusterfs-no-default-logfile-if-daemonize.patch
@@ -9,7 +9,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 11 insertions(+), 4 deletions(-)
 
 diff --git a/block/gluster.c b/block/gluster.c
-index f64dc5b01e..061cab48c0 100644
+index 4fa4a77a47..bfb57ba098 100644
 --- a/block/gluster.c
 +++ b/block/gluster.c
 @@ -42,7 +42,7 @@
diff --git a/debian/patches/pve/0007-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch b/debian/patches/pve/0007-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
index ca452d8..71114ef 100644
--- a/debian/patches/pve/0007-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
+++ b/debian/patches/pve/0007-PVE-Config-rbd-block-rbd-disable-rbd_cache_writethro.patch
@@ -18,10 +18,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+)
 
 diff --git a/block/rbd.c b/block/rbd.c
-index 59757b3120..d00c9d2d12 100644
+index 027cbcc695..3ac7ff7bd5 100644
 --- a/block/rbd.c
 +++ b/block/rbd.c
-@@ -636,6 +636,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
+@@ -637,6 +637,8 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
          rados_conf_set(*cluster, "rbd_cache", "false");
      }
  
diff --git a/debian/patches/pve/0008-PVE-Up-qmp-add-get_link_status.patch b/debian/patches/pve/0008-PVE-Up-qmp-add-get_link_status.patch
index ab31e94..21f1417 100644
--- a/debian/patches/pve/0008-PVE-Up-qmp-add-get_link_status.patch
+++ b/debian/patches/pve/0008-PVE-Up-qmp-add-get_link_status.patch
@@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  3 files changed, 43 insertions(+)
 
 diff --git a/net/net.c b/net/net.c
-index 7d4098254f..c6d5e66bfc 100644
+index 84aa6d8d00..f548202ec6 100644
 --- a/net/net.c
 +++ b/net/net.c
-@@ -1347,6 +1347,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
+@@ -1349,6 +1349,33 @@ void hmp_info_network(Monitor *mon, const QDict *qdict)
      }
  }
  
@@ -49,7 +49,7 @@ index 7d4098254f..c6d5e66bfc 100644
  {
      NetClientState *nc;
 diff --git a/qapi/net.json b/qapi/net.json
-index 728990f4fb..d53c66320b 100644
+index 335295be50..7f3ea194c8 100644
 --- a/qapi/net.json
 +++ b/qapi/net.json
 @@ -34,6 +34,21 @@
@@ -75,7 +75,7 @@ index 728990f4fb..d53c66320b 100644
  # @netdev_add:
  #
 diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
-index 38af54d6b3..d6a4177935 100644
+index 9751b11f8f..a449f158e1 100644
 --- a/qapi/qapi-schema.json
 +++ b/qapi/qapi-schema.json
 @@ -61,6 +61,7 @@
diff --git a/debian/patches/pve/0009-PVE-Up-glusterfs-allow-partial-reads.patch b/debian/patches/pve/0009-PVE-Up-glusterfs-allow-partial-reads.patch
index 4da3e7f..3d6c764 100644
--- a/debian/patches/pve/0009-PVE-Up-glusterfs-allow-partial-reads.patch
+++ b/debian/patches/pve/0009-PVE-Up-glusterfs-allow-partial-reads.patch
@@ -16,7 +16,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 9 insertions(+), 1 deletion(-)
 
 diff --git a/block/gluster.c b/block/gluster.c
-index 061cab48c0..0ed1ec5856 100644
+index bfb57ba098..81fff09c6c 100644
 --- a/block/gluster.c
 +++ b/block/gluster.c
 @@ -57,6 +57,7 @@ typedef struct GlusterAIOCB {
@@ -59,7 +59,7 @@ index 061cab48c0..0ed1ec5856 100644
          ret = glfs_preadv_async(s->fd, qiov->iov, qiov->niov, offset, 0,
                                  gluster_finish_aiocb, &acb);
      }
-@@ -1279,6 +1285,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
+@@ -1280,6 +1286,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
      acb.ret = 0;
      acb.coroutine = qemu_coroutine_self();
      acb.aio_context = bdrv_get_aio_context(bs);
@@ -67,7 +67,7 @@ index 061cab48c0..0ed1ec5856 100644
  
      ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb);
      if (ret < 0) {
-@@ -1325,6 +1332,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
+@@ -1326,6 +1333,7 @@ static coroutine_fn int qemu_gluster_co_pdiscard(BlockDriverState *bs,
      acb.ret = 0;
      acb.coroutine = qemu_coroutine_self();
      acb.aio_context = bdrv_get_aio_context(bs);
diff --git a/debian/patches/pve/0010-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch b/debian/patches/pve/0010-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
index 17a3e61..1468b43 100644
--- a/debian/patches/pve/0010-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
+++ b/debian/patches/pve/0010-PVE-Up-qemu-img-return-success-on-info-without-snaps.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/qemu-img.c b/qemu-img.c
-index 79983772de..c64f260876 100644
+index 95a24b9762..12211bed76 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -2773,7 +2773,8 @@ static int img_info(int argc, char **argv)
+@@ -2791,7 +2791,8 @@ static int img_info(int argc, char **argv)
      list = collect_image_info_list(image_opts, filename, fmt, chain,
                                     force_share);
      if (!list) {
diff --git a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
index 0c5a9c0..6c2578d 100644
--- a/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
+++ b/debian/patches/pve/0011-PVE-Up-qemu-img-dd-add-osize-and-read-from-to-stdin-.patch
@@ -53,10 +53,10 @@ index 1c93e6d185..8094abb3ee 100644
  
  DEF("info", img_info,
 diff --git a/qemu-img.c b/qemu-img.c
-index c64f260876..8129677d7a 100644
+index 12211bed76..d2516968c6 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4413,10 +4413,12 @@ out:
+@@ -4405,10 +4405,12 @@ out:
  #define C_IF      04
  #define C_OF      010
  #define C_SKIP    020
@@ -69,7 +69,7 @@ index c64f260876..8129677d7a 100644
  };
  
  struct DdIo {
-@@ -4495,6 +4497,20 @@ static int img_dd_skip(const char *arg,
+@@ -4487,6 +4489,20 @@ static int img_dd_skip(const char *arg,
      return 0;
  }
  
@@ -90,7 +90,7 @@ index c64f260876..8129677d7a 100644
  static int img_dd(int argc, char **argv)
  {
      int ret = 0;
-@@ -4535,6 +4551,7 @@ static int img_dd(int argc, char **argv)
+@@ -4527,6 +4543,7 @@ static int img_dd(int argc, char **argv)
          { "if", img_dd_if, C_IF },
          { "of", img_dd_of, C_OF },
          { "skip", img_dd_skip, C_SKIP },
@@ -98,7 +98,7 @@ index c64f260876..8129677d7a 100644
          { NULL, NULL, 0 }
      };
      const struct option long_options[] = {
-@@ -4613,8 +4630,13 @@ static int img_dd(int argc, char **argv)
+@@ -4605,8 +4622,13 @@ static int img_dd(int argc, char **argv)
          arg = NULL;
      }
  
@@ -114,7 +114,7 @@ index c64f260876..8129677d7a 100644
          ret = -1;
          goto out;
      }
-@@ -4626,85 +4648,101 @@ static int img_dd(int argc, char **argv)
+@@ -4618,85 +4640,101 @@ static int img_dd(int argc, char **argv)
          goto out;
      }
  
@@ -280,7 +280,7 @@ index c64f260876..8129677d7a 100644
      }
  
      if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
-@@ -4722,11 +4760,17 @@ static int img_dd(int argc, char **argv)
+@@ -4714,11 +4752,17 @@ static int img_dd(int argc, char **argv)
  
      for (out_pos = 0; in_pos < size; block_count++) {
          int in_ret, out_ret;
@@ -302,7 +302,7 @@ index c64f260876..8129677d7a 100644
          }
          if (in_ret < 0) {
              error_report("error while reading from input image file: %s",
-@@ -4736,9 +4780,13 @@ static int img_dd(int argc, char **argv)
+@@ -4728,9 +4772,13 @@ static int img_dd(int argc, char **argv)
          }
          in_pos += in_ret;
  
diff --git a/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-isize-parameter.patch b/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-isize-parameter.patch
index dfd592f..c6f7621 100644
--- a/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-isize-parameter.patch
+++ b/debian/patches/pve/0012-PVE-Up-qemu-img-dd-add-isize-parameter.patch
@@ -15,10 +15,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 26 insertions(+), 3 deletions(-)
 
 diff --git a/qemu-img.c b/qemu-img.c
-index 8129677d7a..1b7f211368 100644
+index d2516968c6..8da1ea3951 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4414,11 +4414,13 @@ out:
+@@ -4406,11 +4406,13 @@ out:
  #define C_OF      010
  #define C_SKIP    020
  #define C_OSIZE   040
@@ -32,7 +32,7 @@ index 8129677d7a..1b7f211368 100644
  };
  
  struct DdIo {
-@@ -4511,6 +4513,20 @@ static int img_dd_osize(const char *arg,
+@@ -4503,6 +4505,20 @@ static int img_dd_osize(const char *arg,
      return 0;
  }
  
@@ -53,7 +53,7 @@ index 8129677d7a..1b7f211368 100644
  static int img_dd(int argc, char **argv)
  {
      int ret = 0;
-@@ -4525,12 +4541,14 @@ static int img_dd(int argc, char **argv)
+@@ -4517,12 +4533,14 @@ static int img_dd(int argc, char **argv)
      int c, i;
      const char *out_fmt = "raw";
      const char *fmt = NULL;
@@ -69,7 +69,7 @@ index 8129677d7a..1b7f211368 100644
      };
      struct DdIo in = {
          .bsz = 512, /* Block size is by default 512 bytes */
-@@ -4552,6 +4570,7 @@ static int img_dd(int argc, char **argv)
+@@ -4544,6 +4562,7 @@ static int img_dd(int argc, char **argv)
          { "of", img_dd_of, C_OF },
          { "skip", img_dd_skip, C_SKIP },
          { "osize", img_dd_osize, C_OSIZE },
@@ -77,7 +77,7 @@ index 8129677d7a..1b7f211368 100644
          { NULL, NULL, 0 }
      };
      const struct option long_options[] = {
-@@ -4758,14 +4777,18 @@ static int img_dd(int argc, char **argv)
+@@ -4750,14 +4769,18 @@ static int img_dd(int argc, char **argv)
  
      in.buf = g_new(uint8_t, in.bsz);
  
diff --git a/debian/patches/pve/0013-PVE-Up-qemu-img-dd-add-n-skip_create.patch b/debian/patches/pve/0013-PVE-Up-qemu-img-dd-add-n-skip_create.patch
index 0fc237d..c811cc2 100644
--- a/debian/patches/pve/0013-PVE-Up-qemu-img-dd-add-n-skip_create.patch
+++ b/debian/patches/pve/0013-PVE-Up-qemu-img-dd-add-n-skip_create.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 14 insertions(+), 9 deletions(-)
 
 diff --git a/qemu-img.c b/qemu-img.c
-index 1b7f211368..e14d2370c4 100644
+index 8da1ea3951..ea3edb4f04 100644
 --- a/qemu-img.c
 +++ b/qemu-img.c
-@@ -4543,7 +4543,7 @@ static int img_dd(int argc, char **argv)
+@@ -4535,7 +4535,7 @@ static int img_dd(int argc, char **argv)
      const char *fmt = NULL;
      int64_t size = 0, readsize = 0;
      int64_t block_count = 0, out_pos, in_pos;
@@ -21,7 +21,7 @@ index 1b7f211368..e14d2370c4 100644
      struct DdInfo dd = {
          .flags = 0,
          .count = 0,
-@@ -4581,7 +4581,7 @@ static int img_dd(int argc, char **argv)
+@@ -4573,7 +4573,7 @@ static int img_dd(int argc, char **argv)
          { 0, 0, 0, 0 }
      };
  
@@ -30,7 +30,7 @@ index 1b7f211368..e14d2370c4 100644
          if (c == EOF) {
              break;
          }
-@@ -4601,6 +4601,9 @@ static int img_dd(int argc, char **argv)
+@@ -4593,6 +4593,9 @@ static int img_dd(int argc, char **argv)
          case 'h':
              help();
              break;
@@ -40,7 +40,7 @@ index 1b7f211368..e14d2370c4 100644
          case 'U':
              force_share = true;
              break;
-@@ -4741,13 +4744,15 @@ static int img_dd(int argc, char **argv)
+@@ -4733,13 +4736,15 @@ static int img_dd(int argc, char **argv)
                                  size - in.bsz * in.offset, &error_abort);
          }
  
diff --git a/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch b/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
index baf8764..c958233 100644
--- a/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
+++ b/debian/patches/pve/0014-PVE-virtio-balloon-improve-query-balloon.patch
@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  3 files changed, 81 insertions(+), 4 deletions(-)
 
 diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
-index 25de154307..7c09716035 100644
+index 40b04f5180..76e907e628 100644
 --- a/hw/virtio/virtio-balloon.c
 +++ b/hw/virtio/virtio-balloon.c
-@@ -712,8 +712,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
+@@ -713,8 +713,37 @@ static uint64_t virtio_balloon_get_features(VirtIODevice *vdev, uint64_t f,
  static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
  {
      VirtIOBalloon *dev = opaque;
@@ -58,10 +58,10 @@ index 25de154307..7c09716035 100644
  
  static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 5ca3ebe942..1b32c59329 100644
+index b2551c16d1..2e725ed818 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -870,7 +870,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
+@@ -854,7 +854,35 @@ void hmp_info_balloon(Monitor *mon, const QDict *qdict)
          return;
      }
  
@@ -99,7 +99,7 @@ index 5ca3ebe942..1b32c59329 100644
      qapi_free_BalloonInfo(info);
  }
 diff --git a/qapi/misc.json b/qapi/misc.json
-index a7fba7230c..2445c950cc 100644
+index 33b94e3589..ed65ed27e3 100644
 --- a/qapi/misc.json
 +++ b/qapi/misc.json
 @@ -408,10 +408,30 @@
diff --git a/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch b/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch
index 6f75ce6..f9fd95e 100644
--- a/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch
+++ b/debian/patches/pve/0015-PVE-qapi-modify-query-machines.patch
@@ -12,12 +12,12 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  2 files changed, 8 insertions(+), 1 deletion(-)
 
 diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
-index 5bd95b8ab0..fd68f9baf8 100644
+index eed5aeb2f7..b0d9dcc7e2 100644
 --- a/hw/core/machine-qmp-cmds.c
 +++ b/hw/core/machine-qmp-cmds.c
-@@ -229,6 +229,11 @@ MachineInfoList *qmp_query_machines(Error **errp)
-         info->numa_mem_supported = mc->numa_mem_supported;
-         info->deprecated = !!mc->deprecation_reason;
+@@ -235,6 +235,11 @@ MachineInfoList *qmp_query_machines(Error **errp)
+             info->has_default_cpu_type = true;
+         }
  
 +        if (strcmp(mc->name, MACHINE_GET_CLASS(current_machine)->name) == 0) {
 +            info->has_is_current = true;
@@ -28,10 +28,10 @@ index 5bd95b8ab0..fd68f9baf8 100644
          entry->value = info;
          entry->next = mach_list;
 diff --git a/qapi/machine.json b/qapi/machine.json
-index 6db8a7e2ec..7b82c5f7f5 100644
+index ca26779f1a..cbdb6f6d66 100644
 --- a/qapi/machine.json
 +++ b/qapi/machine.json
-@@ -313,6 +313,8 @@
+@@ -336,6 +336,8 @@
  #
  # @is-default: whether the machine is default
  #
@@ -40,12 +40,12 @@ index 6db8a7e2ec..7b82c5f7f5 100644
  # @cpu-max: maximum number of CPUs supported by the machine type
  #           (since 1.5.0)
  #
-@@ -329,7 +331,7 @@
+@@ -355,7 +357,7 @@
  ##
  { 'struct': 'MachineInfo',
    'data': { 'name': 'str', '*alias': 'str',
 -            '*is-default': 'bool', 'cpu-max': 'int',
 +            '*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
              'hotpluggable-cpus': 'bool',  'numa-mem-supported': 'bool',
-             'deprecated': 'bool' } }
+             'deprecated': 'bool', '*default-cpu-type': 'str' } }
  
diff --git a/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch b/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch
index 71a3c90..ab89826 100644
--- a/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch
+++ b/debian/patches/pve/0016-PVE-qapi-modify-spice-query.patch
@@ -12,7 +12,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  2 files changed, 8 insertions(+)
 
 diff --git a/qapi/ui.json b/qapi/ui.json
-index 59e412139a..bcd781a1b9 100644
+index e04525d8b4..6127990e23 100644
 --- a/qapi/ui.json
 +++ b/qapi/ui.json
 @@ -211,11 +211,14 @@
@@ -31,7 +31,7 @@ index 59e412139a..bcd781a1b9 100644
    'if': 'defined(CONFIG_SPICE)' }
  
 diff --git a/ui/spice-core.c b/ui/spice-core.c
-index c95bbd6c77..ccba92a6ed 100644
+index ca04965ead..243466c13d 100644
 --- a/ui/spice-core.c
 +++ b/ui/spice-core.c
 @@ -539,6 +539,11 @@ SpiceInfo *qmp_query_spice(Error **errp)
diff --git a/debian/patches/pve/0017-PVE-internal-snapshot-async.patch b/debian/patches/pve/0017-PVE-internal-snapshot-async.patch
index 93fef3b..0c68575 100644
--- a/debian/patches/pve/0017-PVE-internal-snapshot-async.patch
+++ b/debian/patches/pve/0017-PVE-internal-snapshot-async.patch
@@ -14,13 +14,13 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  qapi/migration.json          |  34 +++
  qapi/misc.json               |  32 +++
  qemu-options.hx              |  13 +
- savevm-async.c               | 460 +++++++++++++++++++++++++++++++++++
+ savevm-async.c               | 463 +++++++++++++++++++++++++++++++++++
  vl.c                         |  10 +
- 11 files changed, 658 insertions(+)
+ 11 files changed, 661 insertions(+)
  create mode 100644 savevm-async.c
 
 diff --git a/Makefile.objs b/Makefile.objs
-index 6a143dcd57..21dd93b58c 100644
+index 11ba1a36bd..f97b40f232 100644
 --- a/Makefile.objs
 +++ b/Makefile.objs
 @@ -48,6 +48,7 @@ common-obj-y += bootdevice.o iothread.o
@@ -32,7 +32,7 @@ index 6a143dcd57..21dd93b58c 100644
  common-obj-y += qdev-monitor.o device-hotplug.o
  common-obj-$(CONFIG_WIN32) += os-win32.o
 diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
-index c59444c461..444bd8e43d 100644
+index 257ee7d7a3..139e673bea 100644
 --- a/hmp-commands-info.hx
 +++ b/hmp-commands-info.hx
 @@ -608,6 +608,19 @@ STEXI
@@ -56,10 +56,10 @@ index c59444c461..444bd8e43d 100644
  
      {
 diff --git a/hmp-commands.hx b/hmp-commands.hx
-index bfa5681dd2..e075d413c0 100644
+index cfcc044ce4..104288322d 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
-@@ -1944,3 +1944,35 @@ ETEXI
+@@ -1945,3 +1945,35 @@ ETEXI
  STEXI
  @end table
  ETEXI
@@ -130,10 +130,10 @@ index a0e9511440..c6ee8295f0 100644
  void hmp_screendump(Monitor *mon, const QDict *qdict);
  void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 1b32c59329..39a8020367 100644
+index 2e725ed818..90aa34be25 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -2640,6 +2640,63 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
+@@ -2607,6 +2607,63 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
      hmp_handle_error(mon, &err);
  }
  
@@ -198,10 +198,10 @@ index 1b32c59329..39a8020367 100644
  {
      IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
 diff --git a/qapi/migration.json b/qapi/migration.json
-index 9cfbaf8c6c..e206355d56 100644
+index b7348d0c8b..2792409977 100644
 --- a/qapi/migration.json
 +++ b/qapi/migration.json
-@@ -219,6 +219,40 @@
+@@ -222,6 +222,40 @@
             '*compression': 'CompressionStats',
             '*socket-address': ['SocketAddress'] } }
  
@@ -243,12 +243,12 @@ index 9cfbaf8c6c..e206355d56 100644
  # @query-migrate:
  #
 diff --git a/qapi/misc.json b/qapi/misc.json
-index 2445c950cc..31029e3132 100644
+index ed65ed27e3..4c4618a574 100644
 --- a/qapi/misc.json
 +++ b/qapi/misc.json
-@@ -1384,6 +1384,38 @@
+@@ -1368,6 +1368,38 @@
  ##
- { 'command': 'query-target', 'returns': 'TargetInfo' }
+ { 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
  
 +##
 +# @savevm-start:
@@ -286,10 +286,10 @@ index 2445c950cc..31029e3132 100644
  # @AcpiTableOptions:
  #
 diff --git a/qemu-options.hx b/qemu-options.hx
-index 9621e934c0..34994daafd 100644
+index 65c9473b73..4cb2681bfc 100644
 --- a/qemu-options.hx
 +++ b/qemu-options.hx
-@@ -3731,6 +3731,19 @@ STEXI
+@@ -3818,6 +3818,19 @@ STEXI
  Start right away with a saved state (@code{loadvm} in monitor)
  ETEXI
  
@@ -311,10 +311,10 @@ index 9621e934c0..34994daafd 100644
      "-daemonize      daemonize QEMU after initializing\n", QEMU_ARCH_ALL)
 diff --git a/savevm-async.c b/savevm-async.c
 new file mode 100644
-index 0000000000..2149010bb8
+index 0000000000..5a20009b9a
 --- /dev/null
 +++ b/savevm-async.c
-@@ -0,0 +1,460 @@
+@@ -0,0 +1,463 @@
 +#include "qemu/osdep.h"
 +#include "migration/migration.h"
 +#include "migration/savevm.h"
@@ -323,6 +323,7 @@ index 0000000000..2149010bb8
 +#include "migration/ram.h"
 +#include "migration/qemu-file.h"
 +#include "sysemu/sysemu.h"
++#include "sysemu/runstate.h"
 +#include "block/block.h"
 +#include "sysemu/block-backend.h"
 +#include "qapi/error.h"
@@ -332,6 +333,8 @@ index 0000000000..2149010bb8
 +#include "qapi/qapi-commands-misc.h"
 +#include "qapi/qapi-commands-block.h"
 +#include "qemu/cutils.h"
++#include "qemu/main-loop.h"
++#include "qemu/rcu.h"
 +
 +/* #define DEBUG_SAVEVM_STATE */
 +
@@ -423,8 +426,8 @@ index 0000000000..2149010bb8
 +        /* try to truncate, but ignore errors (will fail on block devices).
 +         * note: bdrv_read() need whole blocks, so we round up
 +         */
-+        size_t size = (snap_state.bs_pos + BDRV_SECTOR_SIZE) & BDRV_SECTOR_MASK;
-+        blk_truncate(snap_state.target, size, PREALLOC_MODE_OFF, NULL);
++        size_t size = QEMU_ALIGN_UP(snap_state.bs_pos, BDRV_SECTOR_SIZE);
++        blk_truncate(snap_state.target, size, false, PREALLOC_MODE_OFF, NULL);
 +        blk_op_unblock_all(snap_state.target, snap_state.blocker);
 +        error_free(snap_state.blocker);
 +        snap_state.blocker = NULL;
@@ -455,7 +458,7 @@ index 0000000000..2149010bb8
 +    snap_state.state = SAVE_STATE_ERROR;
 +}
 +
-+static int block_state_close(void *opaque)
++static int block_state_close(void *opaque, Error **errp)
 +{
 +    snap_state.file = NULL;
 +    return blk_flush(snap_state.target);
@@ -474,7 +477,7 @@ index 0000000000..2149010bb8
 +}
 +
 +static ssize_t block_state_writev_buffer(void *opaque, struct iovec *iov,
-+                                         int iovcnt, int64_t pos)
++                                         int iovcnt, int64_t pos, Error **errp)
 +{
 +    QEMUIOVector qiov;
 +    BlkRwCo rwco;
@@ -709,7 +712,7 @@ index 0000000000..2149010bb8
 +}
 +
 +static ssize_t loadstate_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
-+                                    size_t size)
++                                    size_t size, Error **errp)
 +{
 +    BlockBackend *be = opaque;
 +    int64_t maxlen = blk_getlength(be);
@@ -776,10 +779,10 @@ index 0000000000..2149010bb8
 +    return ret;
 +}
 diff --git a/vl.c b/vl.c
-index b426b32134..1c5536e5bb 100644
+index 6a65a64bfd..1616f55a38 100644
 --- a/vl.c
 +++ b/vl.c
-@@ -2869,6 +2869,7 @@ int main(int argc, char **argv, char **envp)
+@@ -2840,6 +2840,7 @@ int main(int argc, char **argv, char **envp)
      int optind;
      const char *optarg;
      const char *loadvm = NULL;
@@ -787,7 +790,7 @@ index b426b32134..1c5536e5bb 100644
      MachineClass *machine_class;
      const char *cpu_option;
      const char *vga_model = NULL;
-@@ -3445,6 +3446,9 @@ int main(int argc, char **argv, char **envp)
+@@ -3430,6 +3431,9 @@ int main(int argc, char **argv, char **envp)
              case QEMU_OPTION_loadvm:
                  loadvm = optarg;
                  break;
@@ -797,7 +800,7 @@ index b426b32134..1c5536e5bb 100644
              case QEMU_OPTION_full_screen:
                  dpy.has_full_screen = true;
                  dpy.full_screen = true;
-@@ -4444,6 +4448,12 @@ int main(int argc, char **argv, char **envp)
+@@ -4442,6 +4446,12 @@ int main(int argc, char **argv, char **envp)
              autostart = 0;
              exit(1);
          }
diff --git a/debian/patches/pve/0018-PVE-block-add-the-zeroinit-block-driver-filter.patch b/debian/patches/pve/0018-PVE-block-add-the-zeroinit-block-driver-filter.patch
index 5adbafe..34b9fe5 100644
--- a/debian/patches/pve/0018-PVE-block-add-the-zeroinit-block-driver-filter.patch
+++ b/debian/patches/pve/0018-PVE-block-add-the-zeroinit-block-driver-filter.patch
@@ -11,7 +11,7 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  create mode 100644 block/zeroinit.c
 
 diff --git a/block/Makefile.objs b/block/Makefile.objs
-index 35f3bca4d9..6022242c3f 100644
+index e394fe0b6c..a10ceabf5b 100644
 --- a/block/Makefile.objs
 +++ b/block/Makefile.objs
 @@ -11,6 +11,7 @@ block-obj-$(CONFIG_QED) += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
@@ -24,7 +24,7 @@ index 35f3bca4d9..6022242c3f 100644
  block-obj-y += blklogwrites.o
 diff --git a/block/zeroinit.c b/block/zeroinit.c
 new file mode 100644
-index 0000000000..e78511d36c
+index 0000000000..ca80cc672d
 --- /dev/null
 +++ b/block/zeroinit.c
 @@ -0,0 +1,204 @@
@@ -186,9 +186,9 @@ index 0000000000..e78511d36c
 +}
 +
 +static int zeroinit_co_truncate(BlockDriverState *bs, int64_t offset,
-+                             PreallocMode prealloc, Error **errp)
++                             _Bool exact, PreallocMode prealloc, Error **errp)
 +{
-+    return bdrv_co_truncate(bs->file, offset, prealloc, errp);
++    return bdrv_co_truncate(bs->file, offset, exact, prealloc, errp);
 +}
 +
 +static int zeroinit_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
diff --git a/debian/patches/pve/0019-PVE-backup-modify-job-api.patch b/debian/patches/pve/0019-PVE-backup-modify-job-api.patch
index 7bd2457..257f28e 100644
--- a/debian/patches/pve/0019-PVE-backup-modify-job-api.patch
+++ b/debian/patches/pve/0019-PVE-backup-modify-job-api.patch
@@ -12,16 +12,16 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
 ---
  block/backup.c            | 2 ++
  block/replication.c       | 2 +-
- blockdev.c                | 4 ++--
+ blockdev.c                | 2 +-
  include/block/block_int.h | 1 +
  job.c                     | 2 +-
- 5 files changed, 7 insertions(+), 4 deletions(-)
+ 5 files changed, 6 insertions(+), 3 deletions(-)
 
 diff --git a/block/backup.c b/block/backup.c
-index 8761f1f9a7..30008fcc34 100644
+index cf62b1a38c..ec3a4dacc0 100644
 --- a/block/backup.c
 +++ b/block/backup.c
-@@ -550,6 +550,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -347,6 +347,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
                    BlockdevOnError on_target_error,
                    int creation_flags,
                    BlockCompletionFunc *cb, void *opaque,
@@ -29,20 +29,20 @@ index 8761f1f9a7..30008fcc34 100644
                    JobTxn *txn, Error **errp)
  {
      int64_t len;
-@@ -675,6 +676,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -467,6 +468,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+     /* Required permissions are already taken by backup-top target */
      block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
                         &error_abort);
-     job->len = len;
 +    job->common.job.pause_count += pause_count;
  
      return &job->common;
  
 diff --git a/block/replication.c b/block/replication.c
-index 23b2993d74..e70a6cf2bd 100644
+index 99532ce521..ec8de7b427 100644
 --- a/block/replication.c
 +++ b/block/replication.c
 @@ -546,7 +546,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
-                                 0, MIRROR_SYNC_MODE_NONE, NULL, false,
+                                 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false, NULL,
                                  BLOCKDEV_ON_ERROR_REPORT,
                                  BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
 -                                backup_job_completed, bs, NULL, &local_err);
@@ -51,32 +51,23 @@ index 23b2993d74..e70a6cf2bd 100644
              error_propagate(errp, local_err);
              backup_job_cleanup(bs);
 diff --git a/blockdev.c b/blockdev.c
-index 4d141e9a1f..a7c97b1585 100644
+index 8e029e9c01..2994b2d0df 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3574,7 +3574,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
-     job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
-                             backup->sync, bmap, backup->compress,
-                             backup->on_source_error, backup->on_target_error,
--                            job_flags, NULL, NULL, txn, &local_err);
-+                            job_flags, NULL, NULL, 0, txn, &local_err);
-     if (local_err != NULL) {
-         error_propagate(errp, local_err);
-         goto unref;
-@@ -3679,7 +3679,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
-     job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
-                             backup->sync, bmap, backup->compress,
-                             backup->on_source_error, backup->on_target_error,
--                            job_flags, NULL, NULL, txn, &local_err);
-+                            job_flags, NULL, NULL, 0, txn, &local_err);
-     if (local_err != NULL) {
-         error_propagate(errp, local_err);
-     }
+@@ -3583,7 +3583,7 @@ static BlockJob *do_backup_common(BackupCommon *backup,
+                             backup->filter_node_name,
+                             backup->on_source_error,
+                             backup->on_target_error,
+-                            job_flags, NULL, NULL, txn, errp);
++                            job_flags, NULL, NULL, 0, txn, errp);
+     return job;
+ }
+ 
 diff --git a/include/block/block_int.h b/include/block/block_int.h
-index 05ee6b4866..bb2dddca83 100644
+index dd033d0b37..b0d5eb9485 100644
 --- a/include/block/block_int.h
 +++ b/include/block/block_int.h
-@@ -1173,6 +1173,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -1215,6 +1215,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
                              BlockdevOnError on_target_error,
                              int creation_flags,
                              BlockCompletionFunc *cb, void *opaque,
@@ -85,10 +76,10 @@ index 05ee6b4866..bb2dddca83 100644
  
  void hmp_drive_add_node(Monitor *mon, const char *optstr);
 diff --git a/job.c b/job.c
-index 28dd48f8a5..7a21e83780 100644
+index 04409b40aa..7554f735e3 100644
 --- a/job.c
 +++ b/job.c
-@@ -898,7 +898,7 @@ void job_start(Job *job)
+@@ -888,7 +888,7 @@ void job_start(Job *job)
      job->co = qemu_coroutine_create(job_co_entry, job);
      job->pause_count--;
      job->busy = true;
diff --git a/debian/patches/pve/0020-PVE-backup-introduce-vma-archive-format.patch b/debian/patches/pve/0020-PVE-backup-introduce-vma-archive-format.patch
index 6bb45cc..0cc77de 100644
--- a/debian/patches/pve/0020-PVE-backup-introduce-vma-archive-format.patch
+++ b/debian/patches/pve/0020-PVE-backup-introduce-vma-archive-format.patch
@@ -22,10 +22,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  create mode 100644 block/vma.c
 
 diff --git a/MAINTAINERS b/MAINTAINERS
-index d6de200453..de09d099f6 100644
+index 5e5e3e52d6..df278ab928 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -2563,6 +2563,12 @@ L: qemu-block at nongnu.org
+@@ -2624,6 +2624,12 @@ L: qemu-block at nongnu.org
  S: Supported
  F: block/vvfat.c
  
@@ -39,7 +39,7 @@ index d6de200453..de09d099f6 100644
  M: Stefan Hajnoczi <stefanha at redhat.com>
  L: qemu-block at nongnu.org
 diff --git a/block/Makefile.objs b/block/Makefile.objs
-index 6022242c3f..86b10d8ea7 100644
+index a10ceabf5b..3138b6ec88 100644
 --- a/block/Makefile.objs
 +++ b/block/Makefile.objs
 @@ -33,6 +33,7 @@ block-obj-$(CONFIG_RBD) += rbd.o
@@ -50,7 +50,7 @@ index 6022242c3f..86b10d8ea7 100644
  block-obj-y += accounting.o dirty-bitmap.o
  block-obj-y += write-threshold.o
  block-obj-y += backup.o
-@@ -64,3 +65,5 @@ qcow.o-libs        := -lz
+@@ -68,3 +69,5 @@ qcow.o-libs        := -lz
  linux-aio.o-libs   := -laio
  parallels.o-cflags := $(LIBXML2_CFLAGS)
  parallels.o-libs   := $(LIBXML2_LIBS)
@@ -566,7 +566,7 @@ index 0000000000..b911b198dc
 +
 +block_init(bdrv_vma_init);
 diff --git a/blockdev.c b/blockdev.c
-index a7c97b1585..7047475a3c 100644
+index 2994b2d0df..0f72ee1bd3 100644
 --- a/blockdev.c
 +++ b/blockdev.c
 @@ -31,11 +31,13 @@
@@ -591,7 +591,7 @@ index a7c97b1585..7047475a3c 100644
  #include "qapi/qmp/qdict.h"
  #include "qapi/qmp/qnum.h"
  #include "qapi/qmp/qstring.h"
-@@ -3168,6 +3171,539 @@ out:
+@@ -3212,6 +3215,539 @@ out:
      aio_context_release(aio_context);
  }
  
@@ -1023,8 +1023,8 @@ index a7c97b1585..7047475a3c 100644
 +        l = g_list_next(l);
 +
 +        job = backup_job_create(NULL, di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL, NULL,
-+                                false, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
-+                                JOB_DEFAULT,
++                                false, NULL, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
++                                JOB_DEFAULT, 0,
 +                                pvebackup_complete_cb, di, 2, NULL, &local_err);
 +        if (di->target) {
 +            bdrv_unref(di->target);
@@ -1132,21 +1132,21 @@ index a7c97b1585..7047475a3c 100644
                        bool has_base, const char *base,
                        bool has_base_node, const char *base_node,
 diff --git a/configure b/configure
-index 714e7fb6a1..5e16d8e562 100755
+index 6099be1d84..9e5b033c41 100755
 --- a/configure
 +++ b/configure
-@@ -499,6 +499,8 @@ docker="no"
+@@ -503,6 +503,8 @@ libxml2=""
  debug_mutex="no"
  libpmem=""
  default_devices="yes"
 +libudev="no"
 +vma=""
+ plugins="no"
  
- # cross compilers defaults, can be overridden with --cross-cc-ARCH
- cross_cc_aarch64="aarch64-linux-gnu-gcc"
-@@ -1543,6 +1545,10 @@ for opt do
+ supported_cpu="no"
+@@ -1539,6 +1541,10 @@ for opt do
    ;;
-   --disable-libpmem) libpmem=no
+   --disable-plugins) plugins="no"
    ;;
 +  --enable-vma) vma=yes
 +  ;;
@@ -1155,15 +1155,15 @@ index 714e7fb6a1..5e16d8e562 100755
    *)
        echo "ERROR: unknown option $opt"
        echo "Try '$0 --help' for more information"
-@@ -1842,6 +1848,7 @@ disabled with --disable-FEATURE, default is enabled if available:
-   capstone        capstone disassembler support
+@@ -1825,6 +1831,7 @@ disabled with --disable-FEATURE, default is enabled if available:
    debug-mutex     mutex debugging support
    libpmem         libpmem support
+   xkbcommon       xkbcommon support
 +  vma             VMA archive backend
  
  NOTE: The object files are built at the place where configure is launched
  EOF
-@@ -4402,6 +4409,22 @@ EOF
+@@ -4457,6 +4464,22 @@ EOF
    fi
  fi
  
@@ -1186,15 +1186,15 @@ index 714e7fb6a1..5e16d8e562 100755
  ##########################################
  # signalfd probe
  signalfd="no"
-@@ -6481,6 +6504,7 @@ echo "docker            $docker"
- echo "libpmem support   $libpmem"
+@@ -6599,6 +6622,7 @@ echo "libpmem support   $libpmem"
  echo "libudev           $libudev"
  echo "default devices   $default_devices"
+ echo "plugin support    $plugins"
 +echo "VMA support       $vma"
  
  if test "$supported_cpu" = "no"; then
      echo
-@@ -6983,6 +7007,12 @@ if test "$usb_redir" = "yes" ; then
+@@ -7108,6 +7132,12 @@ if test "$usb_redir" = "yes" ; then
    echo "USB_REDIR_LIBS=$usb_redir_libs" >> $config_host_mak
  fi
  
@@ -1208,7 +1208,7 @@ index 714e7fb6a1..5e16d8e562 100755
    echo "CONFIG_OPENGL=y" >> $config_host_mak
    echo "OPENGL_LIBS=$opengl_libs" >> $config_host_mak
 diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
-index 444bd8e43d..21106bcbe6 100644
+index 139e673bea..8db5ce03a7 100644
 --- a/hmp-commands-info.hx
 +++ b/hmp-commands-info.hx
 @@ -536,6 +536,19 @@ STEXI
@@ -1232,7 +1232,7 @@ index 444bd8e43d..21106bcbe6 100644
  
  #if defined(CONFIG_SLIRP)
 diff --git a/hmp-commands.hx b/hmp-commands.hx
-index e075d413c0..5bdfdeaf57 100644
+index 104288322d..29d11dd321 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
 @@ -105,6 +105,37 @@ STEXI
@@ -1295,10 +1295,10 @@ index c6ee8295f0..0f2f96c4af 100644
  void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
  void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index 39a8020367..bc9ca346f7 100644
+index 90aa34be25..9bdd0a271b 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -196,6 +196,44 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
+@@ -194,6 +194,44 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict)
      qapi_free_MouseInfoList(mice_list);
  }
  
@@ -1343,7 +1343,7 @@ index 39a8020367..bc9ca346f7 100644
  static char *SocketAddress_to_str(SocketAddress *addr)
  {
      switch (addr->type) {
-@@ -2078,6 +2116,31 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
+@@ -2062,6 +2100,31 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
      hmp_handle_error(mon, &error);
  }
  
@@ -1376,10 +1376,10 @@ index 39a8020367..bc9ca346f7 100644
  {
      Error *error = NULL;
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 0d43d4f37c..97cb7ec41c 100644
+index 0cf68fea14..76bd20c7fa 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -796,6 +796,97 @@
+@@ -800,6 +800,97 @@
  { 'command': 'query-block', 'returns': ['BlockInfo'] }
  
  
@@ -1477,7 +1477,7 @@ index 0d43d4f37c..97cb7ec41c 100644
  ##
  # @BlockDeviceTimedStats:
  #
-@@ -2835,7 +2926,7 @@
+@@ -2895,7 +2986,7 @@
              'qcow2', 'qed', 'quorum', 'raw', 'rbd',
              { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
              'sheepdog',
@@ -1486,7 +1486,7 @@ index 0d43d4f37c..97cb7ec41c 100644
  
  ##
  # @BlockdevOptionsFile:
-@@ -3898,6 +3989,21 @@
+@@ -3979,6 +4070,21 @@
              'server': 'InetSocketAddressBase',
              '*tls-creds': 'str' } }
  
@@ -1508,7 +1508,7 @@ index 0d43d4f37c..97cb7ec41c 100644
  ##
  # @BlockdevOptionsThrottle:
  #
-@@ -3993,6 +4099,7 @@
+@@ -4075,6 +4181,7 @@
        'throttle':   'BlockdevOptionsThrottle',
        'vdi':        'BlockdevOptionsGenericFormat',
        'vhdx':       'BlockdevOptionsGenericFormat',
@@ -1517,13 +1517,13 @@ index 0d43d4f37c..97cb7ec41c 100644
        'vpc':        'BlockdevOptionsGenericFormat',
        'vvfat':      'BlockdevOptionsVVFAT',
 diff --git a/qapi/common.json b/qapi/common.json
-index 99d313ef3b..bae0650c51 100644
+index 7b9cbcd97b..c3b8bb7b48 100644
 --- a/qapi/common.json
 +++ b/qapi/common.json
-@@ -193,3 +193,16 @@
-              'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
-              'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32',
-              'x86_64', 'xtensa', 'xtensaeb' ] }
+@@ -144,3 +144,16 @@
+ ##
+ { 'enum': 'PCIELinkWidth',
+   'data': [ '1', '2', '4', '8', '12', '16', '32' ] }
 +
 +##
 +# @UuidInfo:
@@ -1538,7 +1538,7 @@ index 99d313ef3b..bae0650c51 100644
 +##
 +{ 'struct': 'UuidInfo', 'data': {'UUID': 'str'} }
 diff --git a/qapi/misc.json b/qapi/misc.json
-index 31029e3132..335035c04d 100644
+index 4c4618a574..7d506b5300 100644
 --- a/qapi/misc.json
 +++ b/qapi/misc.json
 @@ -270,19 +270,6 @@
diff --git a/debian/patches/pve/0021-PVE-Deprecated-adding-old-vma-files.patch b/debian/patches/pve/0021-PVE-Deprecated-adding-old-vma-files.patch
index f40bc6d..ea5cb63 100644
--- a/debian/patches/pve/0021-PVE-Deprecated-adding-old-vma-files.patch
+++ b/debian/patches/pve/0021-PVE-Deprecated-adding-old-vma-files.patch
@@ -4,30 +4,35 @@ Date: Mon, 7 Aug 2017 08:51:16 +0200
 Subject: [PATCH] PVE: [Deprecated] adding old vma files
 
 TODO: Move to using a libvma block backend
+
 Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
+[rebase to v4.2.0, adapt to new structure in block/block-copy.c]
+Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
 ---
- Makefile                  |   3 +-
- Makefile.objs             |   1 +
- block/backup.c            |  88 ++--
- block/replication.c       |   1 +
- blockdev.c                | 208 +++++----
- include/block/block_int.h |   4 +
- job.c                     |   3 +-
- vma-reader.c              | 857 ++++++++++++++++++++++++++++++++++++++
- vma-writer.c              | 771 ++++++++++++++++++++++++++++++++++
- vma.c                     | 756 +++++++++++++++++++++++++++++++++
- vma.h                     | 150 +++++++
- 11 files changed, 2737 insertions(+), 105 deletions(-)
+ Makefile                   |   3 +-
+ Makefile.objs              |   1 +
+ block/backup.c             |  37 +-
+ block/block-copy.c         |  20 +-
+ block/replication.c        |   1 +
+ blockdev.c                 | 206 +++++----
+ include/block/block-copy.h |   2 +
+ include/block/block_int.h  |   4 +
+ job.c                      |   3 +-
+ vma-reader.c               | 857 +++++++++++++++++++++++++++++++++++++
+ vma-writer.c               | 771 +++++++++++++++++++++++++++++++++
+ vma.c                      | 756 ++++++++++++++++++++++++++++++++
+ vma.h                      | 150 +++++++
+ 13 files changed, 2720 insertions(+), 91 deletions(-)
  create mode 100644 vma-reader.c
  create mode 100644 vma-writer.c
  create mode 100644 vma.c
  create mode 100644 vma.h
 
 diff --git a/Makefile b/Makefile
-index 85862fb81a..421e7b486c 100644
+index b437a346d7..18d2dba2e4 100644
 --- a/Makefile
 +++ b/Makefile
-@@ -436,7 +436,7 @@ dummy := $(call unnest-vars,, \
+@@ -453,7 +453,7 @@ dummy := $(call unnest-vars,, \
  
  include $(SRC_PATH)/tests/Makefile.include
  
@@ -36,7 +41,7 @@ index 85862fb81a..421e7b486c 100644
  
  qemu-version.h: FORCE
  	$(call quiet-command, \
-@@ -544,6 +544,7 @@ qemu-img.o: qemu-img-cmds.h
+@@ -567,6 +567,7 @@ qemu-img.o: qemu-img-cmds.h
  qemu-img$(EXESUF): qemu-img.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
  qemu-nbd$(EXESUF): qemu-nbd.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
  qemu-io$(EXESUF): qemu-io.o $(authz-obj-y) $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
@@ -45,7 +50,7 @@ index 85862fb81a..421e7b486c 100644
  qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
  
 diff --git a/Makefile.objs b/Makefile.objs
-index 21dd93b58c..87c6033bc1 100644
+index f97b40f232..db7fbbe73b 100644
 --- a/Makefile.objs
 +++ b/Makefile.objs
 @@ -18,6 +18,7 @@ block-obj-y += block.o blockjob.o job.o
@@ -57,74 +62,35 @@ index 21dd93b58c..87c6033bc1 100644
  block-obj-m = block/
  
 diff --git a/block/backup.c b/block/backup.c
-index 30008fcc34..fdcfb0529c 100644
+index ec3a4dacc0..d737ab5a80 100644
 --- a/block/backup.c
 +++ b/block/backup.c
-@@ -41,6 +41,7 @@ typedef struct BackupBlockJob {
-     /* bitmap for sync=incremental */
+@@ -39,6 +39,8 @@ typedef struct BackupBlockJob {
+ 
      BdrvDirtyBitmap *sync_bitmap;
-     MirrorSyncMode sync_mode;
+ 
 +    BackupDumpFunc *dump_cb;
++
+     MirrorSyncMode sync_mode;
+     BitmapSyncMode bitmap_mode;
      BlockdevOnError on_source_error;
-     BlockdevOnError on_target_error;
-     CoRwlock flush_rwlock;
-@@ -129,12 +130,20 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
-     }
- 
-     if (buffer_is_zero(*bounce_buffer, nbytes)) {
--        ret = blk_co_pwrite_zeroes(job->target, start,
--                                   nbytes, write_flags | BDRV_REQ_MAY_UNMAP);
-+        if (job->dump_cb) {
-+            ret = job->dump_cb(job->common.job.opaque, job->target, start, nbytes, NULL);
-+        } else {
-+            ret = blk_co_pwrite_zeroes(job->target, start,
-+                                       nbytes, write_flags | BDRV_REQ_MAY_UNMAP);
-+        }
-     } else {
--        ret = blk_co_pwrite(job->target, start,
--                            nbytes, *bounce_buffer, write_flags |
--                            (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
-+        if (job->dump_cb) {
-+            ret = job->dump_cb(job->common.job.opaque, job->target, start, nbytes, *bounce_buffer);
-+        } else {
-+            ret = blk_co_pwrite(job->target, start,
-+                                nbytes, *bounce_buffer, write_flags |
-+                                (job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0));
-+        }
-     }
-     if (ret < 0) {
-         trace_backup_do_cow_write_fail(job, start, ret);
-@@ -218,8 +227,11 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
-         trace_backup_do_cow_process(job, start);
- 
-         if (job->use_copy_range) {
--            ret = backup_cow_with_offload(job, start, dirty_end,
--                                          is_write_notifier);
-+            if (job->dump_cb) {
-+                ret = - 1;
-+            } else {
-+                ret = backup_cow_with_offload(job, start, dirty_end, is_write_notifier);
-+            }
-             if (ret < 0) {
-                 job->use_copy_range = false;
-             }
-@@ -304,7 +316,9 @@ static void backup_abort(Job *job)
+@@ -135,7 +137,9 @@ static void backup_abort(Job *job)
  static void backup_clean(Job *job)
  {
      BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
--    assert(s->target);
-+    if (!s->target) {
+-
++    if (s->dump_cb) {
 +        return;
 +    }
-     blk_unref(s->target);
-     s->target = NULL;
+     bdrv_backup_top_drop(s->backup_top);
+ }
  
-@@ -350,9 +364,11 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
+@@ -160,9 +164,11 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
      if (read) {
          return block_job_error_action(&job->common, job->on_source_error,
                                        true, error);
 -    } else {
-+    } else if (job->target) {
++    } else if (!job->dump_cb) {
          return block_job_error_action(&job->common, job->on_target_error,
                                        false, error);
 +    } else {
@@ -132,7 +98,7 @@ index 30008fcc34..fdcfb0529c 100644
      }
  }
  
-@@ -549,6 +565,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -346,6 +352,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
                    BlockdevOnError on_source_error,
                    BlockdevOnError on_target_error,
                    int creation_flags,
@@ -140,16 +106,16 @@ index 30008fcc34..fdcfb0529c 100644
                    BlockCompletionFunc *cb, void *opaque,
                    int pause_count,
                    JobTxn *txn, Error **errp)
-@@ -560,7 +577,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
-     HBitmap *copy_bitmap = NULL;
+@@ -358,7 +365,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+     BlockCopyState *bcs = NULL;
  
      assert(bs);
 -    assert(target);
 +    assert(target || dump_cb);
  
-     if (bs == target) {
-         error_setg(errp, "Source and target cannot be the same");
-@@ -573,13 +590,13 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+     /* QMP interface protects us from these cases */
+     assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
+@@ -375,13 +382,13 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
          return NULL;
      }
  
@@ -160,12 +126,12 @@ index 30008fcc34..fdcfb0529c 100644
          return NULL;
      }
  
--    if (compress && target->drv->bdrv_co_pwritev_compressed == NULL) {
-+    if (target && compress && target->drv->bdrv_co_pwritev_compressed == NULL) {
+-    if (compress && !block_driver_can_compress(target->drv)) {
++    if (target && compress && !block_driver_can_compress(target->drv)) {
          error_setg(errp, "Compression is not supported for this drive %s",
                     bdrv_get_device_name(target));
          return NULL;
-@@ -589,7 +606,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -391,7 +398,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
          return NULL;
      }
  
@@ -174,7 +140,7 @@ index 30008fcc34..fdcfb0529c 100644
          return NULL;
      }
  
-@@ -619,7 +636,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -415,7 +422,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
          goto error;
      }
  
@@ -183,80 +149,99 @@ index 30008fcc34..fdcfb0529c 100644
      if (cluster_size < 0) {
          goto error;
      }
-@@ -636,16 +653,19 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
-         goto error;
+@@ -435,7 +442,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+      * tests/qemu-iotests/222
+      */
+     write_flags = (bdrv_chain_contains(target, bs) ? BDRV_REQ_SERIALISING : 0) |
+-                  (compress ? BDRV_REQ_WRITE_COMPRESSED : 0),
++                    (compress ? BDRV_REQ_WRITE_COMPRESSED : 0),
+ 
+     backup_top = bdrv_backup_top_append(bs, target, filter_node_name,
+                                         cluster_size, write_flags, &bcs, errp);
+@@ -444,13 +451,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
      }
  
--    /* The target must match the source in size, so no resize here either */
--    job->target = blk_new(job->common.job.aio_context,
--                          BLK_PERM_WRITE,
--                          BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
--                          BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD);
--    ret = blk_insert_bs(job->target, target, errp);
--    if (ret < 0) {
--        goto error;
-+    if (target) {
-+        /* The target must match the source in size, so no resize here either */
-+        job->target = blk_new(job->common.job.aio_context,
-+                              BLK_PERM_WRITE,
-+                              BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE |
-+                              BLK_PERM_WRITE_UNCHANGED | BLK_PERM_GRAPH_MOD);
-+        ret = blk_insert_bs(job->target, target, errp);
-+        if (ret < 0) {
-+            goto error;
-+        }
+     /* job->len is fixed, so we can't allow resize */
+-    job = block_job_create(job_id, &backup_job_driver, txn, backup_top,
+-                           0, BLK_PERM_ALL,
++    job = block_job_create(job_id, &backup_job_driver, txn,
++                           backup_top ? backup_top : bs, 0, BLK_PERM_ALL,
+                            speed, creation_flags, cb, opaque, errp);
+     if (!job) {
+         goto error;
      }
  
 +    job->dump_cb = dump_cb;
+     job->backup_top = backup_top;
+     job->source_bs = bs;
      job->on_source_error = on_source_error;
-     job->on_target_error = on_target_error;
-     job->sync_mode = sync_mode;
-@@ -658,10 +678,14 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
-     job->cluster_size = cluster_size;
-     job->copy_bitmap = copy_bitmap;
-     copy_bitmap = NULL;
--    job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk),
--                                        blk_get_max_transfer(job->target));
--    job->copy_range_size = QEMU_ALIGN_DOWN(job->copy_range_size,
--                                           job->cluster_size);
-+
-+    if (target) {
-+        job->copy_range_size = MIN_NON_ZERO(blk_get_max_transfer(job->common.blk),
-+                                            blk_get_max_transfer(job->target));
-+        job->copy_range_size = QEMU_ALIGN_DOWN(job->copy_range_size,
-+                                               job->cluster_size);
-+    }
-+
-     /*
-      * Set use_copy_range, consider the following:
-      * 1. Compression is not supported for copy_range.
-@@ -669,12 +693,16 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
-      *    that in here. If max_transfer is smaller than the job->cluster_size,
-      *    we do not use copy_range (in that case it's zero after aligning down
-      *    above).
-+     * 3. If !target, we're using PVE dump_cb callback
-      */
--    job->use_copy_range = !compress && job->copy_range_size > 0;
-+    job->use_copy_range = target && !compress && job->copy_range_size > 0;
-+
-+    if (target) {
-+        /* Required permissions are already taken with target's blk_new() */
-+        block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
-+                           &error_abort);
-+    }
+@@ -465,9 +473,12 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+     block_copy_set_callbacks(bcs, backup_progress_bytes_callback,
+                              backup_progress_reset_callback, job);
  
--    /* Required permissions are already taken with target's blk_new() */
+-    /* Required permissions are already taken by backup-top target */
 -    block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
 -                       &error_abort);
-     job->len = len;
++    if (target) {
++        /* Required permissions are already taken by backup-top target */
++        block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
++                        &error_abort);
++    }
++
      job->common.job.pause_count += pause_count;
  
+     return &job->common;
+diff --git a/block/block-copy.c b/block/block-copy.c
+index 79798a1567..64901f698c 100644
+--- a/block/block-copy.c
++++ b/block/block-copy.c
+@@ -19,6 +19,7 @@
+ #include "block/block-copy.h"
+ #include "sysemu/block-backend.h"
+ #include "qemu/units.h"
++#include "qemu/cutils.h"
+ 
+ #define BLOCK_COPY_MAX_COPY_RANGE (16 * MiB)
+ #define BLOCK_COPY_MAX_BUFFER (1 * MiB)
+@@ -161,8 +162,13 @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
+     assert(end < s->len || end == QEMU_ALIGN_UP(s->len, s->cluster_size));
+ 
+     if (s->use_copy_range) {
+-        ret = bdrv_co_copy_range(s->source, start, s->target, start, nbytes,
+-                                 0, s->write_flags);
++        if (s->dump_cb) {
++            ret = -1;
++        } else {
++            ret = bdrv_co_copy_range(s->source, start, s->target, start, nbytes,
++                                     0, s->write_flags);
++        }
++
+         if (ret < 0) {
+             trace_block_copy_copy_range_fail(s, start, ret);
+             s->use_copy_range = false;
+@@ -190,8 +196,14 @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
+         goto out;
+     }
+ 
+-    ret = bdrv_co_pwrite(s->target, start, nbytes, bounce_buffer,
+-                         s->write_flags);
++    if (job->dump_cb) {
++        ret = job->dump_cb(job->common.job.opaque, job->target, start, nbytes,
++                           *bounce_buffer);
++    } else {
++        ret = bdrv_co_pwrite(s->target, start, nbytes, bounce_buffer,
++                             s->write_flags);
++    }
++
+     if (ret < 0) {
+         trace_block_copy_write_fail(s, start, ret);
+         if (error_is_read) {
 diff --git a/block/replication.c b/block/replication.c
-index e70a6cf2bd..f060755713 100644
+index ec8de7b427..61806aa7f9 100644
 --- a/block/replication.c
 +++ b/block/replication.c
 @@ -546,6 +546,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
-                                 0, MIRROR_SYNC_MODE_NONE, NULL, false,
+                                 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false, NULL,
                                  BLOCKDEV_ON_ERROR_REPORT,
                                  BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
 +                                NULL,
@@ -264,7 +249,7 @@ index e70a6cf2bd..f060755713 100644
          if (local_err) {
              error_propagate(errp, local_err);
 diff --git a/blockdev.c b/blockdev.c
-index 7047475a3c..cee7952bbb 100644
+index 0f72ee1bd3..64db5b6ffa 100644
 --- a/blockdev.c
 +++ b/blockdev.c
 @@ -31,7 +31,6 @@
@@ -275,15 +260,15 @@ index 7047475a3c..cee7952bbb 100644
  #include "sysemu/block-backend.h"
  #include "sysemu/blockdev.h"
  #include "hw/block/block.h"
-@@ -64,6 +63,7 @@
- #include "qemu/cutils.h"
+@@ -66,6 +65,7 @@
  #include "qemu/help_option.h"
+ #include "qemu/main-loop.h"
  #include "qemu/throttle-options.h"
 +#include "vma.h"
  
  static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
      QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
-@@ -3176,15 +3176,14 @@ out:
+@@ -3220,15 +3220,14 @@ out:
  static struct PVEBackupState {
      Error *error;
      bool cancel;
@@ -301,7 +286,7 @@ index 7047475a3c..cee7952bbb 100644
      size_t total;
      size_t transferred;
      size_t zero_bytes;
-@@ -3203,6 +3202,71 @@ typedef struct PVEBackupDevInfo {
+@@ -3247,6 +3246,71 @@ typedef struct PVEBackupDevInfo {
  
  static void pvebackup_run_next_job(void);
  
@@ -373,7 +358,7 @@ index 7047475a3c..cee7952bbb 100644
  static void pvebackup_cleanup(void)
  {
      qemu_mutex_lock(&backup_state.backup_mutex);
-@@ -3214,9 +3278,11 @@ static void pvebackup_cleanup(void)
+@@ -3258,9 +3322,11 @@ static void pvebackup_cleanup(void)
  
      backup_state.end_time = time(NULL);
  
@@ -388,7 +373,7 @@ index 7047475a3c..cee7952bbb 100644
      }
  
      g_list_free(backup_state.di_list);
-@@ -3224,6 +3290,13 @@ static void pvebackup_cleanup(void)
+@@ -3268,6 +3334,13 @@ static void pvebackup_cleanup(void)
      qemu_mutex_unlock(&backup_state.backup_mutex);
  }
  
@@ -402,7 +387,7 @@ index 7047475a3c..cee7952bbb 100644
  static void pvebackup_complete_cb(void *opaque, int ret)
  {
      // This always runs in the main loop
-@@ -3240,9 +3313,9 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -3284,9 +3357,9 @@ static void pvebackup_complete_cb(void *opaque, int ret)
      di->bs = NULL;
      di->target = NULL;
  
@@ -415,7 +400,7 @@ index 7047475a3c..cee7952bbb 100644
      }
  
      // remove self from job queue
-@@ -3270,14 +3343,9 @@ static void pvebackup_cancel(void *opaque)
+@@ -3314,14 +3387,9 @@ static void pvebackup_cancel(void *opaque)
          error_setg(&backup_state.error, "backup cancelled");
      }
  
@@ -432,7 +417,7 @@ index 7047475a3c..cee7952bbb 100644
      }
  
      GList *l = backup_state.di_list;
-@@ -3308,18 +3376,14 @@ void qmp_backup_cancel(Error **errp)
+@@ -3352,18 +3420,14 @@ void qmp_backup_cancel(Error **errp)
      Coroutine *co = qemu_coroutine_create(pvebackup_cancel, NULL);
      qemu_coroutine_enter(co);
  
@@ -454,7 +439,7 @@ index 7047475a3c..cee7952bbb 100644
                           Error **errp)
  {
      char *cdata = NULL;
-@@ -3333,7 +3397,12 @@ static int config_to_vma(const char *file, BackupFormat format,
+@@ -3377,7 +3441,12 @@ static int config_to_vma(const char *file, BackupFormat format,
      char *basename = g_path_get_basename(file);
  
      if (format == BACKUP_FORMAT_VMA) {
@@ -468,7 +453,7 @@ index 7047475a3c..cee7952bbb 100644
      } else if (format == BACKUP_FORMAT_DIR) {
          char config_path[PATH_MAX];
          snprintf(config_path, PATH_MAX, "%s/%s", backup_dir, basename);
-@@ -3350,28 +3419,30 @@ static int config_to_vma(const char *file, BackupFormat format,
+@@ -3394,28 +3463,30 @@ static int config_to_vma(const char *file, BackupFormat format,
      return 0;
  }
  
@@ -508,7 +493,7 @@ index 7047475a3c..cee7952bbb 100644
      }
      qemu_mutex_unlock(&backup_state.backup_mutex);
  
-@@ -3382,7 +3453,7 @@ static void pvebackup_run_next_job(void)
+@@ -3426,7 +3497,7 @@ static void pvebackup_run_next_job(void)
  UuidInfo *qmp_backup(const char *backup_file, bool has_format,
                      BackupFormat format,
                      bool has_config_file, const char *config_file,
@@ -517,7 +502,7 @@ index 7047475a3c..cee7952bbb 100644
                      bool has_devlist, const char *devlist,
                      bool has_speed, int64_t speed, Error **errp)
  {
-@@ -3390,7 +3461,8 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3434,7 +3505,8 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      BlockDriverState *bs = NULL;
      const char *backup_dir = NULL;
      Error *local_err = NULL;
@@ -527,7 +512,7 @@ index 7047475a3c..cee7952bbb 100644
      gchar **devs = NULL;
      GList *di_list = NULL;
      GList *l;
-@@ -3402,7 +3474,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3446,7 +3518,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
          backup_state.backup_mutex_initialized = true;
      }
  
@@ -536,7 +521,7 @@ index 7047475a3c..cee7952bbb 100644
          error_set(errp, ERROR_CLASS_GENERIC_ERROR,
                    "previous backup not finished");
          return NULL;
-@@ -3477,40 +3549,28 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3521,40 +3593,28 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
          total += size;
      }
  
@@ -585,7 +570,7 @@ index 7047475a3c..cee7952bbb 100644
                  goto err;
              }
          }
-@@ -3551,14 +3611,14 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3595,14 +3655,14 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
  
      /* add configuration file to archive */
      if (has_config_file) {
@@ -602,7 +587,7 @@ index 7047475a3c..cee7952bbb 100644
              goto err;
          }
      }
-@@ -3581,12 +3641,13 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3625,12 +3685,13 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      }
      backup_state.backup_file = g_strdup(backup_file);
  
@@ -619,14 +604,14 @@ index 7047475a3c..cee7952bbb 100644
  
      backup_state.total = total;
      backup_state.transferred = 0;
-@@ -3597,21 +3658,21 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3641,21 +3702,21 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      while (l) {
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
          l = g_list_next(l);
 -
          job = backup_job_create(NULL, di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL, NULL,
-                                 false, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
-                                 JOB_DEFAULT,
+                                 false, NULL, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
+                                 JOB_DEFAULT, 0,
 -                                pvebackup_complete_cb, di, 2, NULL, &local_err);
 -        if (di->target) {
 -            bdrv_unref(di->target);
@@ -647,7 +632,7 @@ index 7047475a3c..cee7952bbb 100644
      }
  
      qemu_mutex_unlock(&backup_state.backup_mutex);
-@@ -3647,9 +3708,10 @@ err:
+@@ -3691,9 +3752,10 @@ err:
          g_strfreev(devs);
      }
  
@@ -661,29 +646,40 @@ index 7047475a3c..cee7952bbb 100644
      }
  
      if (backup_dir) {
-@@ -4110,7 +4172,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
-     job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
-                             backup->sync, bmap, backup->compress,
-                             backup->on_source_error, backup->on_target_error,
--                            job_flags, NULL, NULL, 0, txn, &local_err);
-+                            job_flags, NULL, NULL, NULL, 0, txn, &local_err);
-     if (local_err != NULL) {
-         error_propagate(errp, local_err);
-         goto unref;
-@@ -4215,7 +4277,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
-     job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
-                             backup->sync, bmap, backup->compress,
-                             backup->on_source_error, backup->on_target_error,
--                            job_flags, NULL, NULL, 0, txn, &local_err);
-+                            job_flags, NULL, NULL, NULL, 0, txn, &local_err);
-     if (local_err != NULL) {
-         error_propagate(errp, local_err);
-     }
+@@ -4119,7 +4181,7 @@ static BlockJob *do_backup_common(BackupCommon *backup,
+                             backup->filter_node_name,
+                             backup->on_source_error,
+                             backup->on_target_error,
+-                            job_flags, NULL, NULL, 0, txn, errp);
++                            job_flags, NULL, NULL, NULL, 0, txn, errp);
+     return job;
+ }
+ 
+diff --git a/include/block/block-copy.h b/include/block/block-copy.h
+index 0a161724d7..f8c38eba36 100644
+--- a/include/block/block-copy.h
++++ b/include/block/block-copy.h
+@@ -16,6 +16,7 @@
+ #define BLOCK_COPY_H
+ 
+ #include "block/block.h"
++#include "block/block_int.h"
+ #include "qemu/co-shared-resource.h"
+ 
+ typedef struct BlockCopyInFlightReq {
+@@ -35,6 +36,7 @@ typedef struct BlockCopyState {
+      */
+     BdrvChild *source;
+     BdrvChild *target;
++    BackupDumpFunc *dump_cb;
+     BdrvDirtyBitmap *copy_bitmap;
+     int64_t cluster_size;
+     bool use_copy_range;
 diff --git a/include/block/block_int.h b/include/block/block_int.h
-index bb2dddca83..5a8b2e06c1 100644
+index b0d5eb9485..7ae20877c7 100644
 --- a/include/block/block_int.h
 +++ b/include/block/block_int.h
-@@ -61,6 +61,9 @@
+@@ -60,6 +60,9 @@
  
  #define BLOCK_PROBE_BUF_SIZE        512
  
@@ -693,7 +689,7 @@ index bb2dddca83..5a8b2e06c1 100644
  enum BdrvTrackedRequestType {
      BDRV_TRACKED_READ,
      BDRV_TRACKED_WRITE,
-@@ -1172,6 +1175,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -1214,6 +1217,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
                              BlockdevOnError on_source_error,
                              BlockdevOnError on_target_error,
                              int creation_flags,
@@ -702,7 +698,7 @@ index bb2dddca83..5a8b2e06c1 100644
                              int pause_count,
                              JobTxn *txn, Error **errp);
 diff --git a/job.c b/job.c
-index 7a21e83780..9d27999678 100644
+index 7554f735e3..b03ef989e2 100644
 --- a/job.c
 +++ b/job.c
 @@ -248,7 +248,8 @@ static bool job_started(Job *job)
diff --git a/debian/patches/pve/0025-PVE-Add-dummy-id-command-line-parameter.patch b/debian/patches/pve/0025-PVE-Add-dummy-id-command-line-parameter.patch
index 94ec6fb..0c4d678 100644
--- a/debian/patches/pve/0025-PVE-Add-dummy-id-command-line-parameter.patch
+++ b/debian/patches/pve/0025-PVE-Add-dummy-id-command-line-parameter.patch
@@ -14,10 +14,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  2 files changed, 11 insertions(+)
 
 diff --git a/qemu-options.hx b/qemu-options.hx
-index 34994daafd..6db02fe903 100644
+index 4cb2681bfc..b84e260fa5 100644
 --- a/qemu-options.hx
 +++ b/qemu-options.hx
-@@ -802,6 +802,9 @@ STEXI
+@@ -826,6 +826,9 @@ STEXI
  @table @option
  ETEXI
  
@@ -28,10 +28,10 @@ index 34994daafd..6db02fe903 100644
      "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n", QEMU_ARCH_ALL)
  DEF("fdb", HAS_ARG, QEMU_OPTION_fdb, "", QEMU_ARCH_ALL)
 diff --git a/vl.c b/vl.c
-index 1c5536e5bb..7ffcd271f1 100644
+index 1616f55a38..4df15640c5 100644
 --- a/vl.c
 +++ b/vl.c
-@@ -2857,6 +2857,7 @@ static void user_register_global_props(void)
+@@ -2828,6 +2828,7 @@ static void user_register_global_props(void)
  int main(int argc, char **argv, char **envp)
  {
      int i;
@@ -39,7 +39,7 @@ index 1c5536e5bb..7ffcd271f1 100644
      int snapshot, linux_boot;
      const char *initrd_filename;
      const char *kernel_filename, *kernel_cmdline;
-@@ -3570,6 +3571,13 @@ int main(int argc, char **argv, char **envp)
+@@ -3560,6 +3561,13 @@ int main(int argc, char **argv, char **envp)
                      exit(1);
                  }
                  break;
diff --git a/debian/patches/pve/0026-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch b/debian/patches/pve/0026-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
index 727e13b..96cac92 100644
--- a/debian/patches/pve/0026-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
+++ b/debian/patches/pve/0026-PVE-Config-Revert-target-i386-disable-LINT0-after-re.patch
@@ -11,10 +11,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 9 insertions(+)
 
 diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
-index e764a2bb03..f66ea72d78 100644
+index 375cb6abe9..e7d479c7e9 100644
 --- a/hw/intc/apic_common.c
 +++ b/hw/intc/apic_common.c
-@@ -258,6 +258,15 @@ static void apic_reset_common(DeviceState *dev)
+@@ -259,6 +259,15 @@ static void apic_reset_common(DeviceState *dev)
      info->vapic_base_update(s);
  
      apic_init_reset(dev);
@@ -29,4 +29,4 @@ index e764a2bb03..f66ea72d78 100644
 +    }
  }
  
- /* This function is only used for old state version 1 and 2 */
+ static const VMStateDescription vmstate_apic_common;
diff --git a/debian/patches/pve/0027-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch b/debian/patches/pve/0027-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
index 8f13e04..83a79d1 100644
--- a/debian/patches/pve/0027-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
+++ b/debian/patches/pve/0027-PVE-Up-Config-file-posix-make-locking-optiono-on-cre.patch
@@ -13,10 +13,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  2 files changed, 43 insertions(+), 21 deletions(-)
 
 diff --git a/block/file-posix.c b/block/file-posix.c
-index 71aa45ce5d..ae1cd3980e 100644
+index 44b49265ae..0722b0f529 100644
 --- a/block/file-posix.c
 +++ b/block/file-posix.c
-@@ -2230,6 +2230,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2250,6 +2250,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
      int fd;
      uint64_t perm, shared;
      int result = 0;
@@ -24,7 +24,7 @@ index 71aa45ce5d..ae1cd3980e 100644
  
      /* Validate options and set default values */
      assert(options->driver == BLOCKDEV_DRIVER_FILE);
-@@ -2263,19 +2264,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2283,19 +2284,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
      perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
      shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
  
@@ -59,7 +59,7 @@ index 71aa45ce5d..ae1cd3980e 100644
      }
  
      /* Clear the file by truncating it to 0 */
-@@ -2308,13 +2312,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
+@@ -2328,13 +2332,15 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
      }
  
  out_unlock:
@@ -82,7 +82,7 @@ index 71aa45ce5d..ae1cd3980e 100644
      }
  
  out_close:
-@@ -2335,6 +2341,7 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
+@@ -2355,6 +2361,7 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
      PreallocMode prealloc;
      char *buf = NULL;
      Error *local_err = NULL;
@@ -90,7 +90,7 @@ index 71aa45ce5d..ae1cd3980e 100644
  
      /* Skip file: protocol prefix */
      strstart(filename, "file:", &filename);
-@@ -2352,6 +2359,18 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
+@@ -2372,6 +2379,18 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
          return -EINVAL;
      }
  
@@ -109,7 +109,7 @@ index 71aa45ce5d..ae1cd3980e 100644
      options = (BlockdevCreateOptions) {
          .driver     = BLOCKDEV_DRIVER_FILE,
          .u.file     = {
-@@ -2361,6 +2380,8 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
+@@ -2381,6 +2400,8 @@ static int coroutine_fn raw_co_create_opts(const char *filename, QemuOpts *opts,
              .preallocation      = prealloc,
              .has_nocow          = true,
              .nocow              = nocow,
@@ -118,7 +118,7 @@ index 71aa45ce5d..ae1cd3980e 100644
          },
      };
      return raw_co_create(&options, errp);
-@@ -2838,7 +2859,7 @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
+@@ -2901,7 +2922,7 @@ static int raw_check_perm(BlockDriverState *bs, uint64_t perm, uint64_t shared,
      }
  
      /* Copy locks to the new fd */
@@ -128,10 +128,10 @@ index 71aa45ce5d..ae1cd3980e 100644
                                     false, errp);
          if (ret < 0) {
 diff --git a/qapi/block-core.json b/qapi/block-core.json
-index 97cb7ec41c..f432d4f3ec 100644
+index 76bd20c7fa..9b4dd607d1 100644
 --- a/qapi/block-core.json
 +++ b/qapi/block-core.json
-@@ -4284,7 +4284,8 @@
+@@ -4366,7 +4366,8 @@
    'data': { 'filename':         'str',
              'size':             'size',
              '*preallocation':   'PreallocMode',
diff --git a/debian/patches/pve/0028-PVE-savevm-async-kick-AIO-wait-on-block-state-write.patch b/debian/patches/pve/0028-PVE-savevm-async-kick-AIO-wait-on-block-state-write.patch
index 77fcb9b..a240593 100644
--- a/debian/patches/pve/0028-PVE-savevm-async-kick-AIO-wait-on-block-state-write.patch
+++ b/debian/patches/pve/0028-PVE-savevm-async-kick-AIO-wait-on-block-state-write.patch
@@ -9,10 +9,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 1 insertion(+)
 
 diff --git a/savevm-async.c b/savevm-async.c
-index 2149010bb8..0bbbbf51ba 100644
+index 5a20009b9a..e4bb0d24b2 100644
 --- a/savevm-async.c
 +++ b/savevm-async.c
-@@ -154,6 +154,7 @@ static void coroutine_fn block_state_write_entry(void *opaque) {
+@@ -157,6 +157,7 @@ static void coroutine_fn block_state_write_entry(void *opaque) {
      BlkRwCo *rwco = opaque;
      rwco->ret = blk_co_pwritev(snap_state.target, rwco->offset, rwco->qiov->size,
                                 rwco->qiov, 0);
diff --git a/debian/patches/pve/0029-PVE-move-snapshot-cleanup-into-bottom-half.patch b/debian/patches/pve/0029-PVE-move-snapshot-cleanup-into-bottom-half.patch
index fd07494..cb7651f 100644
--- a/debian/patches/pve/0029-PVE-move-snapshot-cleanup-into-bottom-half.patch
+++ b/debian/patches/pve/0029-PVE-move-snapshot-cleanup-into-bottom-half.patch
@@ -16,10 +16,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/savevm-async.c b/savevm-async.c
-index 0bbbbf51ba..f9355c5036 100644
+index e4bb0d24b2..10837fc858 100644
 --- a/savevm-async.c
 +++ b/savevm-async.c
-@@ -197,6 +197,8 @@ static void process_savevm_cleanup(void *opaque)
+@@ -200,6 +200,8 @@ static void process_savevm_cleanup(void *opaque)
      int ret;
      qemu_bh_delete(snap_state.cleanup_bh);
      snap_state.cleanup_bh = NULL;
@@ -28,7 +28,7 @@ index 0bbbbf51ba..f9355c5036 100644
      qemu_mutex_unlock_iothread();
      qemu_thread_join(&snap_state.thread);
      qemu_mutex_lock_iothread();
-@@ -273,7 +275,6 @@ static void *process_savevm_thread(void *opaque)
+@@ -276,7 +278,6 @@ static void *process_savevm_thread(void *opaque)
                      save_snapshot_error("qemu_savevm_state_iterate error %d", ret);
                      break;
              }
diff --git a/debian/patches/pve/0030-PVE-monitor-disable-oob-capability.patch b/debian/patches/pve/0030-PVE-monitor-disable-oob-capability.patch
index d144da0..ce7ca1e 100644
--- a/debian/patches/pve/0030-PVE-monitor-disable-oob-capability.patch
+++ b/debian/patches/pve/0030-PVE-monitor-disable-oob-capability.patch
@@ -18,10 +18,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 1 insertion(+), 2 deletions(-)
 
 diff --git a/monitor/qmp.c b/monitor/qmp.c
-index fb3e66c62a..ad6703dc52 100644
+index b67a8e7d1f..8f44fed944 100644
 --- a/monitor/qmp.c
 +++ b/monitor/qmp.c
-@@ -379,8 +379,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty)
+@@ -395,8 +395,7 @@ void monitor_init_qmp(Chardev *chr, bool pretty)
      MonitorQMP *mon = g_new0(MonitorQMP, 1);
  
      /* Note: we run QMP monitor in I/O thread when @chr supports that */
diff --git a/debian/patches/pve/0032-qmp_backup-run-backup-related-code-inside-coroutines.patch b/debian/patches/pve/0032-qmp_backup-run-backup-related-code-inside-coroutines.patch
index 95ee63f..36a10c4 100644
--- a/debian/patches/pve/0032-qmp_backup-run-backup-related-code-inside-coroutines.patch
+++ b/debian/patches/pve/0032-qmp_backup-run-backup-related-code-inside-coroutines.patch
@@ -7,14 +7,14 @@ So that we can safely use coroutines/yield everywhere.
 
 Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
 ---
- blockdev.c | 250 ++++++++++++++++++++++++++++++++++++++---------------
- 1 file changed, 180 insertions(+), 70 deletions(-)
+ blockdev.c | 252 ++++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 181 insertions(+), 71 deletions(-)
 
 diff --git a/blockdev.c b/blockdev.c
-index cee7952bbb..cec0f770e8 100644
+index 64db5b6ffa..63f93f549a 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3173,6 +3173,34 @@ out:
+@@ -3217,6 +3217,34 @@ out:
  
  /* PVE backup related function */
  
@@ -49,7 +49,7 @@ index cee7952bbb..cec0f770e8 100644
  static struct PVEBackupState {
      Error *error;
      bool cancel;
-@@ -3200,12 +3228,14 @@ typedef struct PVEBackupDevInfo {
+@@ -3244,12 +3272,14 @@ typedef struct PVEBackupDevInfo {
      BlockDriverState *target;
  } PVEBackupDevInfo;
  
@@ -66,7 +66,7 @@ index cee7952bbb..cec0f770e8 100644
      const uint64_t size = bytes;
      const unsigned char *buf = pbuf;
      PVEBackupDevInfo *di = opaque;
-@@ -3267,8 +3297,10 @@ static int pvebackup_dump_cb(void *opaque, BlockBackend *target,
+@@ -3311,8 +3341,10 @@ static int pvebackup_dump_cb(void *opaque, BlockBackend *target,
      return size;
  }
  
@@ -78,7 +78,7 @@ index cee7952bbb..cec0f770e8 100644
      qemu_mutex_lock(&backup_state.backup_mutex);
      // Avoid race between block jobs and backup-cancel command:
      if (!backup_state.vmaw) {
-@@ -3290,18 +3322,19 @@ static void pvebackup_cleanup(void)
+@@ -3334,18 +3366,19 @@ static void pvebackup_cleanup(void)
      qemu_mutex_unlock(&backup_state.backup_mutex);
  }
  
@@ -107,7 +107,7 @@ index cee7952bbb..cec0f770e8 100644
  
      di->completed = true;
  
-@@ -3314,8 +3347,7 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -3358,8 +3391,7 @@ static void pvebackup_complete_cb(void *opaque, int ret)
      di->target = NULL;
  
      if (backup_state.vmaw) {
@@ -117,7 +117,7 @@ index cee7952bbb..cec0f770e8 100644
      }
  
      // remove self from job queue
-@@ -3325,12 +3357,25 @@ static void pvebackup_complete_cb(void *opaque, int ret)
+@@ -3369,12 +3401,25 @@ static void pvebackup_complete_cb(void *opaque, int ret)
      qemu_mutex_unlock(&backup_state.backup_mutex);
  
      if (!backup_state.cancel) {
@@ -145,7 +145,7 @@ index cee7952bbb..cec0f770e8 100644
      backup_state.cancel = true;
      qemu_mutex_lock(&backup_state.backup_mutex);
      // Avoid race between block jobs and backup-cancel command:
-@@ -3365,21 +3410,16 @@ static void pvebackup_cancel(void *opaque)
+@@ -3409,21 +3454,16 @@ static void pvebackup_cancel(void *opaque)
          }
      }
  
@@ -170,7 +170,7 @@ index cee7952bbb..cec0f770e8 100644
  }
  
  static int config_to_vma(const char *file, BackupFormat format,
-@@ -3420,8 +3460,11 @@ static int config_to_vma(const char *file, BackupFormat format,
+@@ -3464,8 +3504,11 @@ static int config_to_vma(const char *file, BackupFormat format,
  }
  
  bool job_should_pause(Job *job);
@@ -183,20 +183,15 @@ index cee7952bbb..cec0f770e8 100644
      qemu_mutex_lock(&backup_state.backup_mutex);
  
      GList *l = backup_state.di_list;
-@@ -3447,16 +3490,33 @@ static void pvebackup_run_next_job(void)
+@@ -3491,16 +3534,33 @@ static void pvebackup_run_next_job(void)
      qemu_mutex_unlock(&backup_state.backup_mutex);
  
      // no more jobs, run the cleanup
 -    pvebackup_cleanup();
+-}
 +    pvebackup_co_cleanup();
- }
- 
--UuidInfo *qmp_backup(const char *backup_file, bool has_format,
--                    BackupFormat format,
--                    bool has_config_file, const char *config_file,
--		    bool has_firewall_file, const char *firewall_file,
--                    bool has_devlist, const char *devlist,
--                    bool has_speed, int64_t speed, Error **errp)
++}
++
 +typedef struct QmpBackupTask {
 +    const char *backup_file;
 +    bool has_format;
@@ -212,7 +207,13 @@ index cee7952bbb..cec0f770e8 100644
 +    Error **errp;
 +    UuidInfo *result;
 +} QmpBackupTask;
-+
+ 
+-UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+-                    BackupFormat format,
+-                    bool has_config_file, const char *config_file,
+-		    bool has_firewall_file, const char *firewall_file,
+-                    bool has_devlist, const char *devlist,
+-                    bool has_speed, int64_t speed, Error **errp)
 +static void coroutine_fn pvebackup_co_start(void *opaque)
  {
 +    assert(qemu_in_coroutine());
@@ -224,7 +225,7 @@ index cee7952bbb..cec0f770e8 100644
      BlockBackend *blk;
      BlockDriverState *bs = NULL;
      const char *backup_dir = NULL;
-@@ -3475,16 +3535,16 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3519,16 +3579,16 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      }
  
      if (backup_state.di_list) {
@@ -246,7 +247,7 @@ index cee7952bbb..cec0f770e8 100644
  
          gchar **d = devs;
          while (d && *d) {
-@@ -3492,18 +3552,18 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3536,18 +3596,18 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
              if (blk) {
                  bs = blk_bs(blk);
                  if (bdrv_is_read_only(bs)) {
@@ -268,7 +269,7 @@ index cee7952bbb..cec0f770e8 100644
                            "Device '%s' not found", *d);
                  goto err;
              }
-@@ -3526,7 +3586,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3570,7 +3630,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      }
  
      if (!di_list) {
@@ -277,7 +278,7 @@ index cee7952bbb..cec0f770e8 100644
          goto err;
      }
  
-@@ -3536,13 +3596,13 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3580,13 +3640,13 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      while (l) {
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
          l = g_list_next(l);
@@ -293,7 +294,7 @@ index cee7952bbb..cec0f770e8 100644
              goto err;
          }
          di->size = size;
-@@ -3552,10 +3612,10 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3596,10 +3656,10 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      uuid_generate(uuid);
  
      if (format == BACKUP_FORMAT_VMA) {
@@ -306,7 +307,7 @@ index cee7952bbb..cec0f770e8 100644
              }
              goto err;
          }
-@@ -3569,18 +3629,18 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3613,18 +3673,18 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
              const char *devname = bdrv_get_device_name(di->bs);
              di->dev_id = vma_writer_register_stream(vmaw, devname, di->size);
              if (di->dev_id <= 0) {
@@ -330,7 +331,7 @@ index cee7952bbb..cec0f770e8 100644
  
          l = di_list;
          while (l) {
-@@ -3594,31 +3654,31 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3638,31 +3698,31 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
              bdrv_img_create(di->targetfile, "raw", NULL, NULL, NULL,
                              di->size, flags, false, &local_err);
              if (local_err) {
@@ -369,7 +370,7 @@ index cee7952bbb..cec0f770e8 100644
              goto err;
          }
      }
-@@ -3631,7 +3691,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3675,7 +3735,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
          backup_state.error = NULL;
      }
  
@@ -378,7 +379,7 @@ index cee7952bbb..cec0f770e8 100644
  
      backup_state.start_time = time(NULL);
      backup_state.end_time = 0;
-@@ -3639,7 +3699,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3683,7 +3743,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      if (backup_state.backup_file) {
          g_free(backup_state.backup_file);
      }
@@ -387,16 +388,16 @@ index cee7952bbb..cec0f770e8 100644
  
      backup_state.vmaw = vmaw;
  
-@@ -3658,14 +3718,13 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3702,14 +3762,13 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      while (l) {
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
          l = g_list_next(l);
 -        job = backup_job_create(NULL, di->bs, di->target, speed, MIRROR_SYNC_MODE_FULL, NULL,
 +        job = backup_job_create(NULL, di->bs, di->target, backup_state.speed, MIRROR_SYNC_MODE_FULL, NULL,
-                                 false, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
--                                JOB_DEFAULT,
+                                 false, NULL, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
+-                                JOB_DEFAULT, 0,
 -                                pvebackup_dump_cb, pvebackup_complete_cb, di,
-+                                JOB_DEFAULT, pvebackup_co_dump_cb, pvebackup_complete_cb, di,
++                                JOB_DEFAULT, 0, pvebackup_co_dump_cb, pvebackup_complete_cb, di,
                                  1, NULL, &local_err);
          if (!job || local_err != NULL) {
              error_setg(&backup_state.error, "backup_job_create failed");
@@ -405,7 +406,7 @@ index cee7952bbb..cec0f770e8 100644
          } else {
              job_start(&job->job);
          }
-@@ -3678,13 +3737,14 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3722,13 +3781,14 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      qemu_mutex_unlock(&backup_state.backup_mutex);
  
      if (!backup_state.error) {
@@ -422,7 +423,7 @@ index cee7952bbb..cec0f770e8 100644
  
  err:
  
-@@ -3711,23 +3771,61 @@ err:
+@@ -3755,23 +3815,61 @@ err:
      if (vmaw) {
          Error *err = NULL;
          vma_writer_close(vmaw, &err);
@@ -488,7 +489,7 @@ index cee7952bbb..cec0f770e8 100644
      }
  
      info->has_status = true;
-@@ -3763,7 +3861,19 @@ BackupStatus *qmp_query_backup(Error **errp)
+@@ -3807,7 +3905,19 @@ BackupStatus *qmp_query_backup(Error **errp)
      info->has_transferred = true;
      info->transferred = backup_state.transferred;
  
diff --git a/debian/patches/pve/0033-qmp_backup-use-a-CoMutex-to-protect-access-to-backup.patch b/debian/patches/pve/0033-qmp_backup-use-a-CoMutex-to-protect-access-to-backup.patch
index 6a08930..f935b2b 100644
--- a/debian/patches/pve/0033-qmp_backup-use-a-CoMutex-to-protect-access-to-backup.patch
+++ b/debian/patches/pve/0033-qmp_backup-use-a-CoMutex-to-protect-access-to-backup.patch
@@ -14,10 +14,10 @@ Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
  1 file changed, 52 insertions(+), 22 deletions(-)
 
 diff --git a/blockdev.c b/blockdev.c
-index cec0f770e8..29196c18d8 100644
+index 63f93f549a..6a3289a409 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3215,7 +3215,7 @@ static struct PVEBackupState {
+@@ -3259,7 +3259,7 @@ static struct PVEBackupState {
      size_t total;
      size_t transferred;
      size_t zero_bytes;
@@ -26,7 +26,7 @@ index cec0f770e8..29196c18d8 100644
      bool      backup_mutex_initialized;
  } backup_state;
  
-@@ -3240,7 +3240,10 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
+@@ -3284,7 +3284,10 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
      const unsigned char *buf = pbuf;
      PVEBackupDevInfo *di = opaque;
  
@@ -37,7 +37,7 @@ index cec0f770e8..29196c18d8 100644
          return size; // return success
      }
  
-@@ -3251,6 +3254,7 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
+@@ -3295,6 +3298,7 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
                         "got unaligned write inside backup dump "
                         "callback (sector %ld)", start);
          }
@@ -45,7 +45,7 @@ index cec0f770e8..29196c18d8 100644
          return -1; // not aligned to cluster size
      }
  
-@@ -3292,6 +3296,8 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
+@@ -3336,6 +3340,8 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
          backup_state.transferred += size;
      }
  
@@ -54,7 +54,7 @@ index cec0f770e8..29196c18d8 100644
      // Note: always return success, because we want that writes succeed anyways.
  
      return size;
-@@ -3301,10 +3307,9 @@ static void coroutine_fn pvebackup_co_cleanup(void)
+@@ -3345,10 +3351,9 @@ static void coroutine_fn pvebackup_co_cleanup(void)
  {
      assert(qemu_in_coroutine());
  
@@ -67,7 +67,7 @@ index cec0f770e8..29196c18d8 100644
          return;
      }
  
-@@ -3319,7 +3324,7 @@ static void coroutine_fn pvebackup_co_cleanup(void)
+@@ -3363,7 +3368,7 @@ static void coroutine_fn pvebackup_co_cleanup(void)
  
      g_list_free(backup_state.di_list);
      backup_state.di_list = NULL;
@@ -76,7 +76,7 @@ index cec0f770e8..29196c18d8 100644
  }
  
  typedef struct PVEBackupCompeteCallbackData {
-@@ -3333,6 +3338,8 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
+@@ -3377,6 +3382,8 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
  
      PVEBackupCompeteCallbackData *cb_data = opaque;
  
@@ -85,7 +85,7 @@ index cec0f770e8..29196c18d8 100644
      PVEBackupDevInfo *di = cb_data->di;
      int ret = cb_data->result;
  
-@@ -3351,12 +3358,14 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
+@@ -3395,12 +3402,14 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
      }
  
      // remove self from job queue
@@ -103,7 +103,7 @@ index cec0f770e8..29196c18d8 100644
          pvebackup_co_run_next_job();
      }
  }
-@@ -3376,11 +3385,13 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+@@ -3420,11 +3429,13 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
  {
      assert(qemu_in_coroutine());
  
@@ -119,7 +119,7 @@ index cec0f770e8..29196c18d8 100644
          return;
      }
  
-@@ -3393,6 +3404,7 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+@@ -3437,6 +3448,7 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
          vma_writer_set_error(backup_state.vmaw, "backup cancelled");
      }
  
@@ -127,7 +127,7 @@ index cec0f770e8..29196c18d8 100644
      GList *l = backup_state.di_list;
      while (l) {
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
-@@ -3403,6 +3415,7 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+@@ -3447,6 +3459,7 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
                  AioContext *aio_context = blk_get_aio_context(job->blk);
                  aio_context_acquire(aio_context);
                  if (!di->completed) {
@@ -135,7 +135,7 @@ index cec0f770e8..29196c18d8 100644
                      job_cancel(&job->job, false);
                  }
                  aio_context_release(aio_context);
-@@ -3411,7 +3424,8 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+@@ -3455,7 +3468,8 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
      }
  
      qemu_co_mutex_unlock(&backup_state.backup_mutex);
@@ -145,7 +145,7 @@ index cec0f770e8..29196c18d8 100644
  }
  
  void qmp_backup_cancel(Error **errp)
-@@ -3465,7 +3479,7 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
+@@ -3509,7 +3523,7 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
  {
      assert(qemu_in_coroutine());
  
@@ -154,7 +154,7 @@ index cec0f770e8..29196c18d8 100644
  
      GList *l = backup_state.di_list;
      while (l) {
-@@ -3474,11 +3488,13 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
+@@ -3518,11 +3532,13 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
          if (!di->completed && di->bs && di->bs->job) {
              BlockJob *job = di->bs->job;
              AioContext *aio_context = blk_get_aio_context(job->blk);
@@ -171,7 +171,7 @@ index cec0f770e8..29196c18d8 100644
                  } else {
                      job_resume(&job->job);
                  }
-@@ -3487,7 +3503,7 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
+@@ -3531,7 +3547,7 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
              return;
          }
      }
@@ -180,7 +180,7 @@ index cec0f770e8..29196c18d8 100644
  
      // no more jobs, run the cleanup
      pvebackup_co_cleanup();
-@@ -3530,11 +3546,14 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3574,11 +3590,14 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
      BlockJob *job;
  
      if (!backup_state.backup_mutex_initialized) {
@@ -196,7 +196,7 @@ index cec0f770e8..29196c18d8 100644
          error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
                    "previous backup not finished");
          return;
-@@ -3706,7 +3725,6 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3750,7 +3769,6 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
      uuid_copy(backup_state.uuid, uuid);
      uuid_unparse_lower(uuid, backup_state.uuid_str);
  
@@ -204,7 +204,7 @@ index cec0f770e8..29196c18d8 100644
      backup_state.di_list = di_list;
  
      backup_state.total = total;
-@@ -3724,20 +3742,21 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3768,20 +3786,21 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
                                  1, NULL, &local_err);
          if (!job || local_err != NULL) {
              error_setg(&backup_state.error, "backup_job_create failed");
@@ -230,7 +230,7 @@ index cec0f770e8..29196c18d8 100644
      }
  
      uuid_info = g_malloc0(sizeof(*uuid_info));
-@@ -3778,6 +3797,8 @@ err:
+@@ -3822,6 +3841,8 @@ err:
          rmdir(backup_dir);
      }
  
@@ -239,7 +239,7 @@ index cec0f770e8..29196c18d8 100644
      task->result = NULL;
      return;
  }
-@@ -3805,6 +3826,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
+@@ -3849,6 +3870,7 @@ UuidInfo *qmp_backup(const char *backup_file, bool has_format,
      };
  
      block_on_coroutine_fn(pvebackup_co_start, &task);
@@ -247,7 +247,7 @@ index cec0f770e8..29196c18d8 100644
      return task.result;
  }
  
-@@ -3822,9 +3844,15 @@ static void coroutine_fn pvebackup_co_query(void *opaque)
+@@ -3866,9 +3888,15 @@ static void coroutine_fn pvebackup_co_query(void *opaque)
  
      BackupStatus *info = g_malloc0(sizeof(*info));
  
@@ -263,7 +263,7 @@ index cec0f770e8..29196c18d8 100644
          return;
      }
  
-@@ -3862,6 +3890,8 @@ static void coroutine_fn pvebackup_co_query(void *opaque)
+@@ -3906,6 +3934,8 @@ static void coroutine_fn pvebackup_co_query(void *opaque)
      info->transferred = backup_state.transferred;
  
      task->result = info;
diff --git a/debian/patches/pve/0035-backup_job_create-pass-cluster-size-for-dump.patch b/debian/patches/pve/0035-backup_job_create-pass-cluster-size-for-dump.patch
index ba78610..2c402b2 100644
--- a/debian/patches/pve/0035-backup_job_create-pass-cluster-size-for-dump.patch
+++ b/debian/patches/pve/0035-backup_job_create-pass-cluster-size-for-dump.patch
@@ -4,18 +4,20 @@ Date: Thu, 24 Oct 2019 08:06:50 +0200
 Subject: [PATCH] backup_job_create: pass cluster size for dump
 
 Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
+[PVE: backup: consider source cluster size as well]
+Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
 ---
- block/backup.c            |  8 +++++++-
- block/replication.c       |  2 +-
- blockdev.c                | 10 ++++++----
- include/block/block_int.h |  4 ++++
- 4 files changed, 18 insertions(+), 6 deletions(-)
+ block/backup.c            | 3 +++
+ block/replication.c       | 2 +-
+ blockdev.c                | 8 +++++---
+ include/block/block_int.h | 4 ++++
+ 4 files changed, 13 insertions(+), 4 deletions(-)
 
 diff --git a/block/backup.c b/block/backup.c
-index fdcfb0529c..2398a4d602 100644
+index d737ab5a80..a06a5a4970 100644
 --- a/block/backup.c
 +++ b/block/backup.c
-@@ -566,6 +566,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -353,6 +353,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
                    BlockdevOnError on_target_error,
                    int creation_flags,
                    BackupDumpFunc *dump_cb,
@@ -23,26 +25,21 @@ index fdcfb0529c..2398a4d602 100644
                    BlockCompletionFunc *cb, void *opaque,
                    int pause_count,
                    JobTxn *txn, Error **errp)
-@@ -636,7 +637,12 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
-         goto error;
+@@ -423,6 +424,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
      }
  
--    cluster_size = backup_calculate_cluster_size(target ? target : bs, errp);
-+    if (target) {
-+        cluster_size = backup_calculate_cluster_size(target, errp);
-+    } else {
-+        cluster_size = dump_cb_block_size;
-+    }
+     cluster_size = backup_calculate_cluster_size(target ? target : bs, errp);
++    cluster_size = MAX(cluster_size, dump_cb_block_size);
 +
      if (cluster_size < 0) {
          goto error;
      }
 diff --git a/block/replication.c b/block/replication.c
-index f060755713..b9465c3587 100644
+index 61806aa7f9..1df7d59120 100644
 --- a/block/replication.c
 +++ b/block/replication.c
 @@ -546,7 +546,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
-                                 0, MIRROR_SYNC_MODE_NONE, NULL, false,
+                                 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false, NULL,
                                  BLOCKDEV_ON_ERROR_REPORT,
                                  BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
 -                                NULL,
@@ -51,10 +48,10 @@ index f060755713..b9465c3587 100644
          if (local_err) {
              error_propagate(errp, local_err);
 diff --git a/blockdev.c b/blockdev.c
-index 29196c18d8..a95beb823e 100644
+index 6a3289a409..c21017c3d3 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3544,6 +3544,7 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3588,6 +3588,7 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
      GList *l;
      UuidInfo *uuid_info;
      BlockJob *job;
@@ -62,7 +59,7 @@ index 29196c18d8..a95beb823e 100644
  
      if (!backup_state.backup_mutex_initialized) {
          qemu_co_mutex_init(&backup_state.backup_mutex);
-@@ -3631,6 +3632,7 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3675,6 +3676,7 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
      uuid_generate(uuid);
  
      if (format == BACKUP_FORMAT_VMA) {
@@ -70,40 +67,31 @@ index 29196c18d8..a95beb823e 100644
          vmaw = vma_writer_create(task->backup_file, uuid, &local_err);
          if (!vmaw) {
              if (local_err) {
-@@ -3738,8 +3740,8 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3782,8 +3784,8 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
          l = g_list_next(l);
          job = backup_job_create(NULL, di->bs, di->target, backup_state.speed, MIRROR_SYNC_MODE_FULL, NULL,
-                                 false, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
--                                JOB_DEFAULT, pvebackup_co_dump_cb, pvebackup_complete_cb, di,
+                                 false, NULL, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
+-                                JOB_DEFAULT, 0, pvebackup_co_dump_cb, pvebackup_complete_cb, di,
 -                                1, NULL, &local_err);
-+                                JOB_DEFAULT, pvebackup_co_dump_cb, dump_cb_block_size,
++                                JOB_DEFAULT, 0, pvebackup_co_dump_cb, dump_cb_block_size,
 +                                pvebackup_complete_cb, di, 1, NULL, &local_err);
          if (!job || local_err != NULL) {
              error_setg(&backup_state.error, "backup_job_create failed");
              break;
-@@ -4312,7 +4314,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
-     job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
-                             backup->sync, bmap, backup->compress,
-                             backup->on_source_error, backup->on_target_error,
--                            job_flags, NULL, NULL, NULL, 0, txn, &local_err);
-+                            job_flags, NULL, 0, NULL, NULL, 0, txn, &local_err);
-     if (local_err != NULL) {
-         error_propagate(errp, local_err);
-         goto unref;
-@@ -4417,7 +4419,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn,
-     job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
-                             backup->sync, bmap, backup->compress,
-                             backup->on_source_error, backup->on_target_error,
--                            job_flags, NULL, NULL, NULL, 0, txn, &local_err);
-+                            job_flags, NULL, 0, NULL, NULL, 0, txn, &local_err);
-     if (local_err != NULL) {
-         error_propagate(errp, local_err);
-     }
+@@ -4321,7 +4323,7 @@ static BlockJob *do_backup_common(BackupCommon *backup,
+                             backup->filter_node_name,
+                             backup->on_source_error,
+                             backup->on_target_error,
+-                            job_flags, NULL, NULL, NULL, 0, txn, errp);
++                            job_flags, NULL, 0, NULL, NULL, 0, txn, errp);
+     return job;
+ }
+ 
 diff --git a/include/block/block_int.h b/include/block/block_int.h
-index 5a8b2e06c1..e7ca823058 100644
+index 7ae20877c7..ccb2838aa7 100644
 --- a/include/block/block_int.h
 +++ b/include/block/block_int.h
-@@ -1160,6 +1160,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
+@@ -1200,6 +1200,9 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
   * @on_target_error: The action to take upon error writing to the target.
   * @creation_flags: Flags that control the behavior of the Job lifetime.
   *                  See @BlockJobCreateFlags
@@ -113,7 +101,7 @@ index 5a8b2e06c1..e7ca823058 100644
   * @cb: Completion function for the job.
   * @opaque: Opaque pointer value passed to @cb.
   * @txn: Transaction that this job is part of (may be NULL).
-@@ -1176,6 +1179,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+@@ -1218,6 +1221,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
                              BlockdevOnError on_target_error,
                              int creation_flags,
                              BackupDumpFunc *dump_cb,
diff --git a/debian/patches/pve/0036-avoid-calling-dump_cb-with-NULL-data-pointer-for-sma.patch b/debian/patches/pve/0036-avoid-calling-dump_cb-with-NULL-data-pointer-for-sma.patch
deleted file mode 100644
index a9d8b1a..0000000
--- a/debian/patches/pve/0036-avoid-calling-dump_cb-with-NULL-data-pointer-for-sma.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Dietmar Maurer <dietmar at proxmox.com>
-Date: Thu, 24 Oct 2019 08:06:51 +0200
-Subject: [PATCH] avoid calling dump_cb with NULL data pointer for small/last
- cluster
-
-The last block of a backup may be smaller than cluster_size.
-
-Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
----
- block/backup.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/block/backup.c b/block/backup.c
-index 2398a4d602..c682c99f7a 100644
---- a/block/backup.c
-+++ b/block/backup.c
-@@ -131,7 +131,12 @@ static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job,
- 
-     if (buffer_is_zero(*bounce_buffer, nbytes)) {
-         if (job->dump_cb) {
--            ret = job->dump_cb(job->common.job.opaque, job->target, start, nbytes, NULL);
-+            if (nbytes == job->cluster_size) {
-+                // Note: pass NULL to indicate that we want to write [0u8; cluster_size]
-+                ret = job->dump_cb(job->common.job.opaque, job->target, start, nbytes, NULL);
-+            } else {
-+                ret = job->dump_cb(job->common.job.opaque, job->target, start, nbytes, *bounce_buffer);
-+            }
-         } else {
-             ret = blk_co_pwrite_zeroes(job->target, start,
-                                        nbytes, write_flags | BDRV_REQ_MAY_UNMAP);
diff --git a/debian/patches/pve/0037-rename-config_to_vma-into-pvebackup_co_add_config.patch b/debian/patches/pve/0036-rename-config_to_vma-into-pvebackup_co_add_config.patch
similarity index 91%
rename from debian/patches/pve/0037-rename-config_to_vma-into-pvebackup_co_add_config.patch
rename to debian/patches/pve/0036-rename-config_to_vma-into-pvebackup_co_add_config.patch
index e7d277d..b96131f 100644
--- a/debian/patches/pve/0037-rename-config_to_vma-into-pvebackup_co_add_config.patch
+++ b/debian/patches/pve/0036-rename-config_to_vma-into-pvebackup_co_add_config.patch
@@ -14,10 +14,10 @@ Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
  1 file changed, 26 insertions(+), 14 deletions(-)
 
 diff --git a/blockdev.c b/blockdev.c
-index a95beb823e..530b76c82f 100644
+index c21017c3d3..e4ddd774ab 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3436,10 +3436,16 @@ void qmp_backup_cancel(Error **errp)
+@@ -3480,10 +3480,16 @@ void qmp_backup_cancel(Error **errp)
      block_on_coroutine_fn(pvebackup_co_cancel, NULL);
  }
  
@@ -37,7 +37,7 @@ index a95beb823e..530b76c82f 100644
      char *cdata = NULL;
      gsize clen = 0;
      GError *err = NULL;
-@@ -3449,28 +3455,30 @@ static int config_to_vma(const char *file, BackupFormat format,
+@@ -3493,28 +3499,30 @@ static int config_to_vma(const char *file, BackupFormat format,
      }
  
      char *basename = g_path_get_basename(file);
@@ -77,7 +77,7 @@ index a95beb823e..530b76c82f 100644
  }
  
  bool job_should_pause(Job *job);
-@@ -3546,6 +3554,9 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3590,6 +3598,9 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
      BlockJob *job;
      int dump_cb_block_size = -1;
  
@@ -87,7 +87,7 @@ index a95beb823e..530b76c82f 100644
      if (!backup_state.backup_mutex_initialized) {
          qemu_co_mutex_init(&backup_state.backup_mutex);
          backup_state.backup_mutex_initialized = true;
-@@ -3690,16 +3701,17 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3734,16 +3745,17 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
          goto err;
      }
  
diff --git a/debian/patches/pve/0038-pvebackup_co_dump_cb-do-not-call-job-cancel.patch b/debian/patches/pve/0037-pvebackup_co_dump_cb-do-not-call-job-cancel.patch
similarity index 90%
rename from debian/patches/pve/0038-pvebackup_co_dump_cb-do-not-call-job-cancel.patch
rename to debian/patches/pve/0037-pvebackup_co_dump_cb-do-not-call-job-cancel.patch
index 84282e2..8462c04 100644
--- a/debian/patches/pve/0038-pvebackup_co_dump_cb-do-not-call-job-cancel.patch
+++ b/debian/patches/pve/0037-pvebackup_co_dump_cb-do-not-call-job-cancel.patch
@@ -9,10 +9,10 @@ The backup loop will automatically abort if we return an error.
  1 file changed, 2 insertions(+), 4 deletions(-)
 
 diff --git a/blockdev.c b/blockdev.c
-index 530b76c82f..568f71fdb4 100644
+index e4ddd774ab..a644bdbe27 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3274,10 +3274,8 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
+@@ -3318,10 +3318,8 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
                  if (!backup_state.error) {
                      vma_writer_error_propagate(backup_state.vmaw, &backup_state.error);
                  }
diff --git a/debian/patches/pve/0039-fix-backup-job-completion.patch b/debian/patches/pve/0038-fix-backup-job-completion.patch
similarity index 87%
rename from debian/patches/pve/0039-fix-backup-job-completion.patch
rename to debian/patches/pve/0038-fix-backup-job-completion.patch
index 8b4a9ce..468262f 100644
--- a/debian/patches/pve/0039-fix-backup-job-completion.patch
+++ b/debian/patches/pve/0038-fix-backup-job-completion.patch
@@ -12,10 +12,10 @@ jobs in the list.
  1 file changed, 4 insertions(+), 5 deletions(-)
 
 diff --git a/blockdev.c b/blockdev.c
-index 568f71fdb4..66f2711185 100644
+index a644bdbe27..6d04365ef0 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3359,12 +3359,14 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
+@@ -3403,12 +3403,14 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
      backup_state.di_list = g_list_remove(backup_state.di_list, di);
      g_free(di);
  
@@ -32,7 +32,7 @@ index 568f71fdb4..66f2711185 100644
      }
  }
  
-@@ -3510,9 +3512,6 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
+@@ -3554,9 +3556,6 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
          }
      }
      qemu_co_mutex_unlock(&backup_state.backup_mutex);
diff --git a/debian/patches/pve/0040-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch b/debian/patches/pve/0039-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch
similarity index 88%
rename from debian/patches/pve/0040-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch
rename to debian/patches/pve/0039-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch
index 9650476..9ceffd6 100644
--- a/debian/patches/pve/0040-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch
+++ b/debian/patches/pve/0039-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch
@@ -9,10 +9,10 @@ Subject: [PATCH] pvebackup_complete_cb: avoid poll loop if already inside
  1 file changed, 8 insertions(+), 2 deletions(-)
 
 diff --git a/blockdev.c b/blockdev.c
-index 66f2711185..083ada6c8e 100644
+index 6d04365ef0..203622a2b2 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3189,6 +3189,8 @@ static void coroutine_fn block_on_coroutine_wrapper(void *opaque)
+@@ -3233,6 +3233,8 @@ static void coroutine_fn block_on_coroutine_wrapper(void *opaque)
  
  static void block_on_coroutine_fn(CoroutineEntry *entry, void *entry_arg)
  {
@@ -21,7 +21,7 @@ index 66f2711185..083ada6c8e 100644
      AioContext *ctx = qemu_get_current_aio_context();
      BlockOnCoroutineWrapper wrapper = {
          .finished = false,
-@@ -3372,13 +3374,17 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
+@@ -3416,13 +3418,17 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
  
  static void pvebackup_complete_cb(void *opaque, int ret)
  {
diff --git a/debian/patches/pve/0042-PVE-fixup-vma-tool.patch b/debian/patches/pve/0040-PVE-fixup-vma-tool.patch
similarity index 100%
rename from debian/patches/pve/0042-PVE-fixup-vma-tool.patch
rename to debian/patches/pve/0040-PVE-fixup-vma-tool.patch
diff --git a/debian/patches/pve/0041-PVE-backup-consider-source-cluster-size-as-well.patch b/debian/patches/pve/0041-PVE-backup-consider-source-cluster-size-as-well.patch
deleted file mode 100644
index b72cb76..0000000
--- a/debian/patches/pve/0041-PVE-backup-consider-source-cluster-size-as-well.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Wolfgang Bumiller <w.bumiller at proxmox.com>
-Date: Mon, 4 Nov 2019 14:18:40 +0100
-Subject: [PATCH] PVE: backup: consider source cluster size as well
-
-Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
----
- block/backup.c | 7 ++-----
- 1 file changed, 2 insertions(+), 5 deletions(-)
-
-diff --git a/block/backup.c b/block/backup.c
-index c682c99f7a..556367f8ba 100644
---- a/block/backup.c
-+++ b/block/backup.c
-@@ -642,11 +642,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
-         goto error;
-     }
- 
--    if (target) {
--        cluster_size = backup_calculate_cluster_size(target, errp);
--    } else {
--        cluster_size = dump_cb_block_size;
--    }
-+    cluster_size = backup_calculate_cluster_size(target ? target : bs, errp);
-+    cluster_size = MAX(cluster_size, dump_cb_block_size);
- 
-     if (cluster_size < 0) {
-         goto error;
diff --git a/debian/patches/pve/0043-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch b/debian/patches/pve/0041-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch
similarity index 95%
rename from debian/patches/pve/0043-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch
rename to debian/patches/pve/0041-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch
index 7f0b28a..7d64be5 100644
--- a/debian/patches/pve/0043-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch
+++ b/debian/patches/pve/0041-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch
@@ -10,10 +10,10 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  1 file changed, 27 insertions(+), 22 deletions(-)
 
 diff --git a/blockdev.c b/blockdev.c
-index 083ada6c8e..46e8a2780a 100644
+index 203622a2b2..84b936b8b6 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3416,15 +3416,17 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+@@ -3460,15 +3460,17 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
          l = g_list_next(l);
          if (!di->completed && di->bs) {
@@ -39,7 +39,7 @@ index 083ada6c8e..46e8a2780a 100644
              }
          }
      }
-@@ -3499,22 +3501,25 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
+@@ -3543,22 +3545,25 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
      while (l) {
          PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
          l = g_list_next(l);
diff --git a/debian/patches/pve/0044-Acquire-aio_context-before-calling-block_job_add_bdr.patch b/debian/patches/pve/0042-Acquire-aio_context-before-calling-block_job_add_bdr.patch
similarity index 88%
rename from debian/patches/pve/0044-Acquire-aio_context-before-calling-block_job_add_bdr.patch
rename to debian/patches/pve/0042-Acquire-aio_context-before-calling-block_job_add_bdr.patch
index b1861d3..d7d7809 100644
--- a/debian/patches/pve/0044-Acquire-aio_context-before-calling-block_job_add_bdr.patch
+++ b/debian/patches/pve/0042-Acquire-aio_context-before-calling-block_job_add_bdr.patch
@@ -12,10 +12,10 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
  1 file changed, 10 insertions(+)
 
 diff --git a/blockjob.c b/blockjob.c
-index 74abb97bfd..75b9180a7f 100644
+index c6e20e2fcd..4e6074f18c 100644
 --- a/blockjob.c
 +++ b/blockjob.c
-@@ -448,10 +448,20 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
+@@ -436,10 +436,20 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
      notifier_list_add(&job->job.on_ready, &job->ready_notifier);
      notifier_list_add(&job->job.on_idle, &job->idle_notifier);
  
@@ -35,4 +35,4 @@ index 74abb97bfd..75b9180a7f 100644
 +
      bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
  
-     blk_set_allow_aio_context_change(blk, true);
+     /* Disable request queuing in the BlockBackend to avoid deadlocks on drain:
diff --git a/debian/patches/pve/0045-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch b/debian/patches/pve/0043-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
similarity index 95%
rename from debian/patches/pve/0045-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
rename to debian/patches/pve/0043-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
index 96fc6a8..a6793cf 100644
--- a/debian/patches/pve/0045-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
+++ b/debian/patches/pve/0043-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
@@ -26,10 +26,10 @@ Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/hw/core/machine.c b/hw/core/machine.c
-index 32d1ca9abc..0ee68f1473 100644
+index 1689ad3bf8..bdcb351ede 100644
 --- a/hw/core/machine.c
 +++ b/hw/core/machine.c
-@@ -34,7 +34,8 @@ GlobalProperty hw_compat_4_0[] = {
+@@ -39,7 +39,8 @@ GlobalProperty hw_compat_4_0[] = {
      { "virtio-vga",     "edid", "false" },
      { "virtio-gpu",     "edid", "false" },
      { "virtio-device", "use-started", "false" },
diff --git a/debian/patches/pve/0046-PVE-Allow-version-code-in-machine-type.patch b/debian/patches/pve/0044-PVE-Allow-version-code-in-machine-type.patch
similarity index 79%
rename from debian/patches/pve/0046-PVE-Allow-version-code-in-machine-type.patch
rename to debian/patches/pve/0044-PVE-Allow-version-code-in-machine-type.patch
index e50112e..920ef1b 100644
--- a/debian/patches/pve/0046-PVE-Allow-version-code-in-machine-type.patch
+++ b/debian/patches/pve/0044-PVE-Allow-version-code-in-machine-type.patch
@@ -13,15 +13,15 @@ Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
 ---
  hw/core/machine-qmp-cmds.c |  6 ++++++
  include/hw/boards.h        |  2 ++
- qapi/machine.json          |  2 +-
+ qapi/machine.json          |  3 ++-
  vl.c                       | 15 ++++++++++++++-
- 4 files changed, 23 insertions(+), 2 deletions(-)
+ 4 files changed, 24 insertions(+), 2 deletions(-)
 
 diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
-index fd68f9baf8..61fcad138d 100644
+index b0d9dcc7e2..50be8be458 100644
 --- a/hw/core/machine-qmp-cmds.c
 +++ b/hw/core/machine-qmp-cmds.c
-@@ -232,6 +232,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
+@@ -238,6 +238,12 @@ MachineInfoList *qmp_query_machines(Error **errp)
          if (strcmp(mc->name, MACHINE_GET_CLASS(current_machine)->name) == 0) {
              info->has_is_current = true;
              info->is_current = true;
@@ -35,10 +35,10 @@ index fd68f9baf8..61fcad138d 100644
  
          entry = g_malloc0(sizeof(*entry));
 diff --git a/include/hw/boards.h b/include/hw/boards.h
-index a71d1a53a5..952d2add82 100644
+index de45087f34..e24d2134c0 100644
 --- a/include/hw/boards.h
 +++ b/include/hw/boards.h
-@@ -178,6 +178,8 @@ struct MachineClass {
+@@ -185,6 +185,8 @@ struct MachineClass {
      const char *desc;
      const char *deprecation_reason;
  
@@ -46,25 +46,26 @@ index a71d1a53a5..952d2add82 100644
 +
      void (*init)(MachineState *state);
      void (*reset)(MachineState *state);
-     void (*hot_add_cpu)(MachineState *state, const int64_t id, Error **errp);
+     void (*wakeup)(MachineState *state);
 diff --git a/qapi/machine.json b/qapi/machine.json
-index 7b82c5f7f5..11fef6714e 100644
+index cbdb6f6d66..a2bd4dd304 100644
 --- a/qapi/machine.json
 +++ b/qapi/machine.json
-@@ -333,7 +333,7 @@
+@@ -359,7 +359,8 @@
    'data': { 'name': 'str', '*alias': 'str',
              '*is-default': 'bool', '*is-current': 'bool', 'cpu-max': 'int',
              'hotpluggable-cpus': 'bool',  'numa-mem-supported': 'bool',
--            'deprecated': 'bool' } }
-+            'deprecated': 'bool', '*pve-version': 'str' } }
+-            'deprecated': 'bool', '*default-cpu-type': 'str' } }
++            'deprecated': 'bool', '*default-cpu-type': 'str',
++            '*pve-version': 'str' } }
  
  ##
  # @query-machines:
 diff --git a/vl.c b/vl.c
-index 7ffcd271f1..1305cdaee7 100644
+index 4df15640c5..e7f3ce7607 100644
 --- a/vl.c
 +++ b/vl.c
-@@ -2454,6 +2454,8 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
+@@ -2475,6 +2475,8 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
  {
      MachineClass *mc;
      GSList *el;
@@ -73,7 +74,7 @@ index 7ffcd271f1..1305cdaee7 100644
  
      if (is_help_option(name)) {
          printf("Supported machines are:\n");
-@@ -2470,12 +2472,23 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
+@@ -2491,12 +2493,23 @@ static MachineClass *machine_parse(const char *name, GSList *machines)
          exit(0);
      }
  
diff --git a/debian/patches/pve/0047-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch b/debian/patches/pve/0045-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch
similarity index 87%
rename from debian/patches/pve/0047-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch
rename to debian/patches/pve/0045-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch
index c739b77..9c7ac25 100644
--- a/debian/patches/pve/0047-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch
+++ b/debian/patches/pve/0045-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch
@@ -10,10 +10,10 @@ Signed-off-by: Tim Marx <t.marx at proxmox.com>
  1 file changed, 6 insertions(+)
 
 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
-index bc9ca346f7..fb820410de 100644
+index 9bdd0a271b..23352d714d 100644
 --- a/monitor/hmp-cmds.c
 +++ b/monitor/hmp-cmds.c
-@@ -201,6 +201,12 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
+@@ -199,6 +199,12 @@ void hmp_info_backup(Monitor *mon, const QDict *qdict)
      BackupStatus *info;
  
      info = qmp_query_backup(NULL);
@@ -26,6 +26,3 @@ index bc9ca346f7..fb820410de 100644
      if (info->has_status) {
          if (info->has_errmsg) {
              monitor_printf(mon, "Backup status: %s - %s\n",
--- 
-2.20.1
-
diff --git a/debian/patches/pve/0048-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch b/debian/patches/pve/0046-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch
similarity index 91%
rename from debian/patches/pve/0048-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch
rename to debian/patches/pve/0046-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch
index f8b368e..5048bda 100644
--- a/debian/patches/pve/0048-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch
+++ b/debian/patches/pve/0046-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch
@@ -1,8 +1,8 @@
-From 4c2e4e498716b8a556fccec20fb1348555c2b189 Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Dietmar Maurer <dietmar at proxmox.com>
 Date: Fri, 14 Feb 2020 10:21:37 +0100
-Subject: [PATCH qemu 1/7] PVE backup: use separate CoRwlock for data accessed
- by qmp query_backup
+Subject: [PATCH] PVE backup: use separate CoRwlock for data accessed by qmp
+ query_backup
 
 This should minimize contention between query_backup and running backup jobs.
 ---
@@ -10,10 +10,10 @@ This should minimize contention between query_backup and running backup jobs.
  1 file changed, 112 insertions(+), 66 deletions(-)
 
 diff --git a/blockdev.c b/blockdev.c
-index 46e8a2780a..4367eaf2a7 100644
+index 84b936b8b6..7c419f6b7e 100644
 --- a/blockdev.c
 +++ b/blockdev.c
-@@ -3203,22 +3203,26 @@ static void block_on_coroutine_fn(CoroutineEntry *entry, void *entry_arg)
+@@ -3247,22 +3247,26 @@ static void block_on_coroutine_fn(CoroutineEntry *entry, void *entry_arg)
      AIO_WAIT_WHILE(ctx, !wrapper.finished);
  }
  
@@ -50,7 +50,7 @@ index 46e8a2780a..4367eaf2a7 100644
  } backup_state;
  
  typedef struct PVEBackupDevInfo {
-@@ -3251,11 +3255,14 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
+@@ -3295,11 +3299,14 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
  
      uint64_t cluster_num = start / VMA_CLUSTER_SIZE;
      if ((cluster_num * VMA_CLUSTER_SIZE) != start) {
@@ -67,7 +67,7 @@ index 46e8a2780a..4367eaf2a7 100644
          qemu_co_mutex_unlock(&backup_state.backup_mutex);
          return -1; // not aligned to cluster size
      }
-@@ -3273,27 +3280,35 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
+@@ -3317,27 +3324,35 @@ static int coroutine_fn pvebackup_co_dump_cb(void *opaque, BlockBackend *target,
                  buf += VMA_CLUSTER_SIZE;
              }
              if (ret < 0) {
@@ -110,7 +110,7 @@ index 46e8a2780a..4367eaf2a7 100644
      }
  
      qemu_co_mutex_unlock(&backup_state.backup_mutex);
-@@ -3313,12 +3328,20 @@ static void coroutine_fn pvebackup_co_cleanup(void)
+@@ -3357,12 +3372,20 @@ static void coroutine_fn pvebackup_co_cleanup(void)
          return;
      }
  
@@ -133,7 +133,7 @@ index 46e8a2780a..4367eaf2a7 100644
          backup_state.vmaw = NULL;
      }
  
-@@ -3345,10 +3368,14 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
+@@ -3389,10 +3412,14 @@ static void coroutine_fn pvebackup_co_complete_cb(void *opaque)
  
      di->completed = true;
  
@@ -150,7 +150,7 @@ index 46e8a2780a..4367eaf2a7 100644
  
      di->bs = NULL;
      di->target = NULL;
-@@ -3401,9 +3428,12 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+@@ -3445,9 +3472,12 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
          return;
      }
  
@@ -165,7 +165,7 @@ index 46e8a2780a..4367eaf2a7 100644
  
      if (backup_state.vmaw) {
          /* make sure vma writer does not block anymore */
-@@ -3438,7 +3468,7 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+@@ -3482,7 +3512,7 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
  
  void qmp_backup_cancel(Error **errp)
  {
@@ -174,7 +174,7 @@ index 46e8a2780a..4367eaf2a7 100644
          return;
  
      block_on_coroutine_fn(pvebackup_co_cancel, NULL);
-@@ -3508,9 +3538,13 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
+@@ -3552,9 +3582,13 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
                      qemu_co_mutex_unlock(&backup_state.backup_mutex);
                      aio_context_acquire(aio_context);
  
@@ -190,7 +190,7 @@ index 46e8a2780a..4367eaf2a7 100644
                              job_cancel(&job->job, false);
                          } else {
                              job_resume(&job->job);
-@@ -3565,9 +3599,10 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3609,9 +3643,10 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
      const char *config_name = "qemu-server.conf";
      const char *firewall_name = "qemu-server.fw";
  
@@ -203,7 +203,7 @@ index 46e8a2780a..4367eaf2a7 100644
      }
  
      qemu_co_mutex_lock(&backup_state.backup_mutex);
-@@ -3727,31 +3762,36 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3771,31 +3806,36 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
  
      backup_state.cancel = false;
  
@@ -247,18 +247,18 @@ index 46e8a2780a..4367eaf2a7 100644
 +    qemu_co_rwlock_unlock(&backup_state.stat.rwlock);
 +
 +    backup_state.speed = (task->has_speed && task->speed > 0) ? task->speed : 0;
-+
-+    backup_state.vmaw = vmaw;
  
 -    backup_state.total = total;
 -    backup_state.transferred = 0;
 -    backup_state.zero_bytes = 0;
++    backup_state.vmaw = vmaw;
++
 +    backup_state.di_list = di_list;
  
      /* start all jobs (paused state) */
      l = di_list;
-@@ -3763,7 +3803,9 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
-                                 JOB_DEFAULT, pvebackup_co_dump_cb, dump_cb_block_size,
+@@ -3807,7 +3847,9 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+                                 JOB_DEFAULT, 0, pvebackup_co_dump_cb, dump_cb_block_size,
                                  pvebackup_complete_cb, di, 1, NULL, &local_err);
          if (!job || local_err != NULL) {
 -            error_setg(&backup_state.error, "backup_job_create failed");
@@ -268,7 +268,7 @@ index 46e8a2780a..4367eaf2a7 100644
              break;
          }
          job_start(&job->job);
-@@ -3775,14 +3817,18 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+@@ -3819,14 +3861,18 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
  
      qemu_co_mutex_unlock(&backup_state.backup_mutex);
  
@@ -289,7 +289,7 @@ index 46e8a2780a..4367eaf2a7 100644
  
      task->result = uuid_info;
      return;
-@@ -3866,54 +3912,54 @@ static void coroutine_fn pvebackup_co_query(void *opaque)
+@@ -3910,54 +3956,54 @@ static void coroutine_fn pvebackup_co_query(void *opaque)
  
      BackupStatus *info = g_malloc0(sizeof(*info));
  
@@ -360,6 +360,3 @@ index 46e8a2780a..4367eaf2a7 100644
  }
  
  BackupStatus *qmp_query_backup(Error **errp)
--- 
-2.20.1
-
diff --git a/debian/patches/pve/0049-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch b/debian/patches/pve/0047-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch
similarity index 80%
rename from debian/patches/pve/0049-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch
rename to debian/patches/pve/0047-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch
index c1c7b24..9936c3d 100644
--- a/debian/patches/pve/0049-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch
+++ b/debian/patches/pve/0047-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch
@@ -1,7 +1,7 @@
-From ca384caae9a0dbbbbab2174ec09935702ac7a067 Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Dietmar Maurer <dietmar at proxmox.com>
 Date: Fri, 14 Feb 2020 11:51:02 +0100
-Subject: [PATCH qemu 2/7] PVE backup - block_on_coroutine_wrapper: call
+Subject: [PATCH] PVE backup - block_on_coroutine_wrapper: call
  aio_wait_kick() as described in block/aio-wait.h
 
 ---
@@ -20,6 +20,3 @@ index 4367eaf2a7..2f84f8832d 100644
  }
  
  static void block_on_coroutine_fn(CoroutineEntry *entry, void *entry_arg)
--- 
-2.20.1
-
diff --git a/debian/patches/pve/0050-PVE-backup-move-backup_state.cancel-to-backup_state.patch b/debian/patches/pve/0048-PVE-backup-move-backup_state.cancel-to-backup_state.patch
similarity index 95%
rename from debian/patches/pve/0050-PVE-backup-move-backup_state.cancel-to-backup_state.patch
rename to debian/patches/pve/0048-PVE-backup-move-backup_state.cancel-to-backup_state.patch
index 7841169..e0263ba 100644
--- a/debian/patches/pve/0050-PVE-backup-move-backup_state.cancel-to-backup_state.patch
+++ b/debian/patches/pve/0048-PVE-backup-move-backup_state.cancel-to-backup_state.patch
@@ -1,7 +1,7 @@
-From c8856d5cbcf3d427cd02c9556f845486ab5362bc Mon Sep 17 00:00:00 2001
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 From: Dietmar Maurer <dietmar at proxmox.com>
 Date: Fri, 14 Feb 2020 12:37:27 +0100
-Subject: [PATCH qemu 3/7] PVE backup: move backup_state.cancel to
+Subject: [PATCH] PVE backup: move backup_state.cancel to
  backup_state.stat.cancel
 
 In order to avoid lock contention with qmp_backup_cancel.
@@ -90,6 +90,3 @@ index 2f84f8832d..a4b5b98224 100644
      if (backup_state.stat.error) {
          error_free(backup_state.stat.error);
          backup_state.stat.error = NULL;
--- 
-2.20.1
-
diff --git a/debian/patches/pve/0049-call-dump_cb-with-NULL-for-empty-blocks.patch b/debian/patches/pve/0049-call-dump_cb-with-NULL-for-empty-blocks.patch
new file mode 100644
index 0000000..d71e103
--- /dev/null
+++ b/debian/patches/pve/0049-call-dump_cb-with-NULL-for-empty-blocks.patch
@@ -0,0 +1,40 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Reiter <s.reiter at proxmox.com>
+Date: Thu, 23 Jan 2020 16:25:47 +0100
+Subject: [PATCH] call dump_cb with NULL for empty blocks
+
+Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
+---
+ block/block-copy.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/block/block-copy.c b/block/block-copy.c
+index 64901f698c..1a8cab9b66 100644
+--- a/block/block-copy.c
++++ b/block/block-copy.c
+@@ -156,6 +156,7 @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
+     int ret;
+     int nbytes = MIN(end, s->len) - start;
+     void *bounce_buffer = NULL;
++    bool dump_zero;
+ 
+     assert(QEMU_IS_ALIGNED(start, s->cluster_size));
+     assert(QEMU_IS_ALIGNED(end, s->cluster_size));
+@@ -196,9 +197,14 @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
+         goto out;
+     }
+ 
+-    if (job->dump_cb) {
+-        ret = job->dump_cb(job->common.job.opaque, job->target, start, nbytes,
+-                           *bounce_buffer);
++    if (s->dump_cb) {
++        // pass NULL to indicate that we want to write [0u8; cluster_size]
++        // if buffer is zeros only
++        dump_zero = (nbytes == s->cluster_size) &&
++                    buffer_is_zero(bounce_buffer, nbytes);
++
++        ret = s->dump_cb(s->progress_opaque, NULL, start, nbytes,
++                           dump_zero ? NULL : bounce_buffer);
+     } else {
+         ret = bdrv_co_pwrite(s->target, start, nbytes, bounce_buffer,
+                              s->write_flags);
diff --git a/debian/patches/pve/0050-fixup-backup-for-4.2.patch b/debian/patches/pve/0050-fixup-backup-for-4.2.patch
new file mode 100644
index 0000000..5683bbb
--- /dev/null
+++ b/debian/patches/pve/0050-fixup-backup-for-4.2.patch
@@ -0,0 +1,285 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Stefan Reiter <s.reiter at proxmox.com>
+Date: Thu, 30 Jan 2020 14:09:34 +0100
+Subject: [PATCH] fixup: backup for 4.2
+
+QEMU changed it's internal backup mechanics quite a bit, so while the
+rebase made it build, it couldn't run backups yet. This fixes backups
+semantically to use the new APIs.
+
+Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
+---
+ block/backup-top.c         | 18 +++++++++++-------
+ block/backup.c             | 30 ++++++------------------------
+ block/block-copy.c         | 10 ++++++----
+ block/io.c                 |  8 +++++++-
+ blockdev.c                 | 19 ++++++++++++++-----
+ include/block/block-copy.h |  1 +
+ include/block/block_int.h  | 21 +++++++++++++++++++++
+ 7 files changed, 66 insertions(+), 41 deletions(-)
+
+diff --git a/block/backup-top.c b/block/backup-top.c
+index 7cdb1f8eba..7e1d1ec2e8 100644
+--- a/block/backup-top.c
++++ b/block/backup-top.c
+@@ -198,12 +198,14 @@ BlockDriverState *bdrv_backup_top_append(BlockDriverState *source,
+     top->total_sectors = source->total_sectors;
+     top->opaque = state = g_new0(BDRVBackupTopState, 1);
+ 
+-    bdrv_ref(target);
+-    state->target = bdrv_attach_child(top, target, "target", &child_file, errp);
+-    if (!state->target) {
+-        bdrv_unref(target);
+-        bdrv_unref(top);
+-        return NULL;
++    if (target) {
++        bdrv_ref(target);
++        state->target = bdrv_attach_child(top, target, "target", &child_file, errp);
++        if (!state->target) {
++            bdrv_unref(target);
++            bdrv_unref(top);
++            return NULL;
++        }
+     }
+ 
+     bdrv_drained_begin(source);
+@@ -245,7 +247,9 @@ failed_after_append:
+ 
+ append_failed:
+     bdrv_drained_end(source);
+-    bdrv_unref_child(top, state->target);
++    if (state->target) {
++        bdrv_unref_child(top, state->target);
++    }
+     bdrv_unref(top);
+     error_propagate(errp, local_err);
+ 
+diff --git a/block/backup.c b/block/backup.c
+index a06a5a4970..a6ad8a054d 100644
+--- a/block/backup.c
++++ b/block/backup.c
+@@ -32,26 +32,6 @@
+ 
+ #define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16)
+ 
+-typedef struct BackupBlockJob {
+-    BlockJob common;
+-    BlockDriverState *backup_top;
+-    BlockDriverState *source_bs;
+-
+-    BdrvDirtyBitmap *sync_bitmap;
+-
+-    BackupDumpFunc *dump_cb;
+-
+-    MirrorSyncMode sync_mode;
+-    BitmapSyncMode bitmap_mode;
+-    BlockdevOnError on_source_error;
+-    BlockdevOnError on_target_error;
+-    uint64_t len;
+-    uint64_t bytes_read;
+-    int64_t cluster_size;
+-
+-    BlockCopyState *bcs;
+-} BackupBlockJob;
+-
+ static const BlockJobDriver backup_job_driver;
+ 
+ static void backup_progress_bytes_callback(int64_t bytes, void *opaque)
+@@ -137,7 +117,7 @@ static void backup_abort(Job *job)
+ static void backup_clean(Job *job)
+ {
+     BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
+-    if (s->dump_cb) {
++    if (!s->bcs->target) {
+         return;
+     }
+     bdrv_backup_top_drop(s->backup_top);
+@@ -164,7 +144,7 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
+     if (read) {
+         return block_job_error_action(&job->common, job->on_source_error,
+                                       true, error);
+-    } else if (!job->dump_cb) {
++    } else if (job->bcs->target) {
+         return block_job_error_action(&job->common, job->on_target_error,
+                                       false, error);
+     } else {
+@@ -444,7 +424,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+      * For more information see commit f8d59dfb40bb and test
+      * tests/qemu-iotests/222
+      */
+-    write_flags = (bdrv_chain_contains(target, bs) ? BDRV_REQ_SERIALISING : 0) |
++    write_flags = (target && bdrv_chain_contains(target, bs) ? BDRV_REQ_SERIALISING : 0) |
+                     (compress ? BDRV_REQ_WRITE_COMPRESSED : 0),
+ 
+     backup_top = bdrv_backup_top_append(bs, target, filter_node_name,
+@@ -453,6 +433,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+         goto error;
+     }
+ 
++    bcs->dump_cb = dump_cb;
++
+     /* job->len is fixed, so we can't allow resize */
+     job = block_job_create(job_id, &backup_job_driver, txn,
+                            backup_top ? backup_top : bs, 0, BLK_PERM_ALL,
+@@ -461,7 +443,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+         goto error;
+     }
+ 
+-    job->dump_cb = dump_cb;
+     job->backup_top = backup_top;
+     job->source_bs = bs;
+     job->on_source_error = on_source_error;
+@@ -472,6 +453,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
+     job->bcs = bcs;
+     job->cluster_size = cluster_size;
+     job->len = len;
++    job->bcs->dump_cb_opaque = opaque;
+ 
+     block_copy_set_callbacks(bcs, backup_progress_bytes_callback,
+                              backup_progress_reset_callback, job);
+diff --git a/block/block-copy.c b/block/block-copy.c
+index 1a8cab9b66..aed86407c8 100644
+--- a/block/block-copy.c
++++ b/block/block-copy.c
+@@ -80,7 +80,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
+     uint32_t max_transfer =
+             MIN_NON_ZERO(INT_MAX,
+                          MIN_NON_ZERO(source->bs->bl.max_transfer,
+-                                      target->bs->bl.max_transfer));
++                                      target ? target->bs->bl.max_transfer : INT_MAX));
+ 
+     copy_bitmap = bdrv_create_dirty_bitmap(source->bs, cluster_size, NULL,
+                                            errp);
+@@ -203,7 +203,7 @@ static int coroutine_fn block_copy_do_copy(BlockCopyState *s,
+         dump_zero = (nbytes == s->cluster_size) &&
+                     buffer_is_zero(bounce_buffer, nbytes);
+ 
+-        ret = s->dump_cb(s->progress_opaque, NULL, start, nbytes,
++        ret = s->dump_cb(s->dump_cb_opaque, NULL, start, nbytes,
+                            dump_zero ? NULL : bounce_buffer);
+     } else {
+         ret = bdrv_co_pwrite(s->target, start, nbytes, bounce_buffer,
+@@ -307,8 +307,10 @@ int coroutine_fn block_copy(BlockCopyState *s,
+      * block_copy() user is responsible for keeping source and target in same
+      * aio context
+      */
+-    assert(bdrv_get_aio_context(s->source->bs) ==
+-           bdrv_get_aio_context(s->target->bs));
++    if (s->target) {
++        assert(bdrv_get_aio_context(s->source->bs) ==
++            bdrv_get_aio_context(s->target->bs));
++    }
+ 
+     assert(QEMU_IS_ALIGNED(start, s->cluster_size));
+     assert(QEMU_IS_ALIGNED(end, s->cluster_size));
+diff --git a/block/io.c b/block/io.c
+index f75777f5ea..75dea5ae33 100644
+--- a/block/io.c
++++ b/block/io.c
+@@ -381,7 +381,13 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
+ void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
+                                    BdrvChild *parent, bool ignore_bds_parents)
+ {
+-    assert(!qemu_in_coroutine());
++    // AFAICT this function is just an optimization, but sadly it doesn't play
++    // nice with the PVE backup code (when we're in a coroutine, even in
++    // pvebackup_co_start), so just call the full-blown drain begin instead
++    if (qemu_in_coroutine()) {
++        bdrv_do_drained_begin(bs, false, parent, ignore_bds_parents, false);
++        return;
++    }
+ 
+     /* Stop things in parent-to-child order */
+     if (atomic_fetch_inc(&bs->quiesce_counter) == 0) {
+diff --git a/blockdev.c b/blockdev.c
+index 3f90a4823d..8d4bebc0d1 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -3497,7 +3497,12 @@ static void coroutine_fn pvebackup_co_cancel(void *opaque)
+         l = g_list_next(l);
+         if (!di->completed && di->bs) {
+             for (BlockJob *job = block_job_next(NULL); job; job = block_job_next(job)) {
+-                if (block_job_has_bdrv(job, di->bs)) {
++                if (job->job.driver->job_type != JOB_TYPE_BACKUP) {
++                    continue;
++                }
++
++                BackupBlockJob *bjob = container_of(job, BackupBlockJob, common);
++                if (bjob && bjob->source_bs == di->bs) {
+                     AioContext *aio_context = job->job.aio_context;
+                     aio_context_acquire(aio_context);
+ 
+@@ -3583,12 +3588,16 @@ static void coroutine_fn pvebackup_co_run_next_job(void)
+         l = g_list_next(l);
+         if (!di->completed && di->bs) {
+             for (BlockJob *job = block_job_next(NULL); job; job = block_job_next(job)) {
+-                if (block_job_has_bdrv(job, di->bs)) {
++                if (job->job.driver->job_type != JOB_TYPE_BACKUP) {
++                    continue;
++                }
++
++                BackupBlockJob *bjob = container_of(job, BackupBlockJob, common);
++                if (bjob && bjob->source_bs == di->bs) {
+                     AioContext *aio_context = job->job.aio_context;
+                     qemu_co_mutex_unlock(&backup_state.backup_mutex);
+                     aio_context_acquire(aio_context);
+ 
+-
+                     if (job_should_pause(&job->job)) {
+                         qemu_co_rwlock_rdlock(&backup_state.stat.rwlock);
+                         bool error_or_canceled = backup_state.stat.error || backup_state.stat.cancel;
+@@ -3849,8 +3858,8 @@ static void coroutine_fn pvebackup_co_start(void *opaque)
+         PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
+         l = g_list_next(l);
+         job = backup_job_create(NULL, di->bs, di->target, backup_state.speed, MIRROR_SYNC_MODE_FULL, NULL,
+-                                false, NULL, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
+-                                JOB_DEFAULT, 0, pvebackup_co_dump_cb, dump_cb_block_size,
++                                BITMAP_SYNC_MODE_NEVER, false, NULL, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT,
++                                JOB_DEFAULT, pvebackup_co_dump_cb, dump_cb_block_size,
+                                 pvebackup_complete_cb, di, 1, NULL, &local_err);
+         if (!job || local_err != NULL) {
+             qemu_co_rwlock_wrlock(&backup_state.stat.rwlock);
+diff --git a/include/block/block-copy.h b/include/block/block-copy.h
+index f8c38eba36..88029faf7d 100644
+--- a/include/block/block-copy.h
++++ b/include/block/block-copy.h
+@@ -37,6 +37,7 @@ typedef struct BlockCopyState {
+     BdrvChild *source;
+     BdrvChild *target;
+     BackupDumpFunc *dump_cb;
++    void *dump_cb_opaque;
+     BdrvDirtyBitmap *copy_bitmap;
+     int64_t cluster_size;
+     bool use_copy_range;
+diff --git a/include/block/block_int.h b/include/block/block_int.h
+index ccb2838aa7..ec583b1c2b 100644
+--- a/include/block/block_int.h
++++ b/include/block/block_int.h
+@@ -63,6 +63,27 @@
+ typedef int BackupDumpFunc(void *opaque, BlockBackend *be,
+                            uint64_t offset, uint64_t bytes, const void *buf);
+ 
++// Needs to be defined here, since it's used in blockdev.c to detect PVE backup
++// jobs with source_bs
++typedef struct BlockCopyState BlockCopyState;
++typedef struct BackupBlockJob {
++    BlockJob common;
++    BlockDriverState *backup_top;
++    BlockDriverState *source_bs;
++
++    BdrvDirtyBitmap *sync_bitmap;
++
++    MirrorSyncMode sync_mode;
++    BitmapSyncMode bitmap_mode;
++    BlockdevOnError on_source_error;
++    BlockdevOnError on_target_error;
++    uint64_t len;
++    uint64_t bytes_read;
++    int64_t cluster_size;
++
++    BlockCopyState *bcs;
++} BackupBlockJob;
++
+ enum BdrvTrackedRequestType {
+     BDRV_TRACKED_READ,
+     BDRV_TRACKED_WRITE,
diff --git a/debian/patches/series b/debian/patches/series
index a736b06..cb3ff18 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,5 +1,3 @@
-extra/0001-monitor-qmp-resume-monitor-when-clearing-its-queue.patch
-extra/0002-virtio-blk-schedule-virtio_notify_config-to-run-on-m.patch
 pve/0001-PVE-Config-block-file-change-locking-default-to-off.patch
 pve/0002-PVE-Config-Adjust-network-script-path-to-etc-kvm.patch
 pve/0003-PVE-Config-set-the-CPU-model-to-kvm64-32-instead-of-.patch
@@ -35,18 +33,18 @@ pve/0032-qmp_backup-run-backup-related-code-inside-coroutines.patch
 pve/0033-qmp_backup-use-a-CoMutex-to-protect-access-to-backup.patch
 pve/0034-vma_writer_close-avoid-call-to-aio_poll-acquire-flus.patch
 pve/0035-backup_job_create-pass-cluster-size-for-dump.patch
-pve/0036-avoid-calling-dump_cb-with-NULL-data-pointer-for-sma.patch
-pve/0037-rename-config_to_vma-into-pvebackup_co_add_config.patch
-pve/0038-pvebackup_co_dump_cb-do-not-call-job-cancel.patch
-pve/0039-fix-backup-job-completion.patch
-pve/0040-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch
-pve/0041-PVE-backup-consider-source-cluster-size-as-well.patch
-pve/0042-PVE-fixup-vma-tool.patch
-pve/0043-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch
-pve/0044-Acquire-aio_context-before-calling-block_job_add_bdr.patch
-pve/0045-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
-pve/0046-PVE-Allow-version-code-in-machine-type.patch
-pve/0047-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch
-pve/0048-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch
-pve/0049-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch
-pve/0050-PVE-backup-move-backup_state.cancel-to-backup_state.patch
+pve/0036-rename-config_to_vma-into-pvebackup_co_add_config.patch
+pve/0037-pvebackup_co_dump_cb-do-not-call-job-cancel.patch
+pve/0038-fix-backup-job-completion.patch
+pve/0039-pvebackup_complete_cb-avoid-poll-loop-if-already-ins.patch
+pve/0040-PVE-fixup-vma-tool.patch
+pve/0041-PVE-fixup-blockdev-pvebackup-integration-fix-blockjo.patch
+pve/0042-Acquire-aio_context-before-calling-block_job_add_bdr.patch
+pve/0043-PVE-Compat-4.0-used-balloon-qemu-4-0-config-size-fal.patch
+pve/0044-PVE-Allow-version-code-in-machine-type.patch
+pve/0045-PVE-fix-hmp-info-backup-cmd-for-not-initialized-back.patch
+pve/0046-PVE-backup-use-separate-CoRwlock-for-data-accessed-b.patch
+pve/0047-PVE-backup-block_on_coroutine_wrapper-call-aio_wait.patch
+pve/0048-PVE-backup-move-backup_state.cancel-to-backup_state.patch
+pve/0049-call-dump_cb-with-NULL-for-empty-blocks.patch
+pve/0050-fixup-backup-for-4.2.patch
-- 
2.20.1





More information about the pve-devel mailing list