]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/pve/0046-PVE-handle-PBS-write-callback-with-big-blocks-correc.patch
d45a455d13f4fd6de3076b070624f0356c53f92a
[pve-qemu.git] / debian / patches / pve / 0046-PVE-handle-PBS-write-callback-with-big-blocks-correc.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Stefan Reiter <s.reiter@proxmox.com>
3 Date: Wed, 19 Aug 2020 12:33:17 +0200
4 Subject: [PATCH] PVE: handle PBS write callback with big blocks correctly
5
6 Under certain conditions QEMU will push more than the given blocksize
7 into the callback at once. Handle it like VMA does, by iterating the
8 data until all is written.
9
10 The block size is stored per backup device to be used in the callback.
11 This avoids relying on PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE, in case it is
12 made configurable in the future.
13
14 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
15 ---
16 pve-backup.c | 30 ++++++++++++++++++++++--------
17 1 file changed, 22 insertions(+), 8 deletions(-)
18
19 diff --git a/pve-backup.c b/pve-backup.c
20 index cd3a132d8b..f14273645a 100644
21 --- a/pve-backup.c
22 +++ b/pve-backup.c
23 @@ -67,6 +67,7 @@ opts_init(pvebackup_init);
24 typedef struct PVEBackupDevInfo {
25 BlockDriverState *bs;
26 size_t size;
27 + uint64_t block_size;
28 uint8_t dev_id;
29 bool completed;
30 char targetfile[PATH_MAX];
31 @@ -147,17 +148,28 @@ pvebackup_co_dump_pbs_cb(
32 return -1;
33 }
34
35 - pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id, buf, start, size, &local_err);
36 - qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
37 + uint64_t transferred = 0;
38 + uint64_t reused = 0;
39 + while (transferred < size) {
40 + uint64_t left = size - transferred;
41 + uint64_t to_transfer = left < di->block_size ? left : di->block_size;
42
43 - if (pbs_res < 0) {
44 - pvebackup_propagate_error(local_err);
45 - return pbs_res;
46 - } else {
47 - size_t reused = (pbs_res == 0) ? size : 0;
48 - pvebackup_add_transfered_bytes(size, !buf ? size : 0, reused);
49 + pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id,
50 + buf ? buf + transferred : NULL, start + transferred, to_transfer, &local_err);
51 + transferred += to_transfer;
52 +
53 + if (pbs_res < 0) {
54 + pvebackup_propagate_error(local_err);
55 + qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
56 + return pbs_res;
57 + }
58 +
59 + reused += pbs_res == 0 ? to_transfer : 0;
60 }
61
62 + qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
63 + pvebackup_add_transfered_bytes(size, !buf ? size : 0, reused);
64 +
65 return size;
66 }
67
68 @@ -726,6 +738,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
69 PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data;
70 l = g_list_next(l);
71
72 + di->block_size = dump_cb_block_size;
73 +
74 const char *devname = bdrv_get_device_name(di->bs);
75
76 BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(di->bs, PBS_BITMAP_NAME);