]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/pve/0048-qapi-blockdev-backup-add-discard-source-parameter.patch
update submodule and patches to QEMU 8.2.2
[pve-qemu.git] / debian / patches / pve / 0048-qapi-blockdev-backup-add-discard-source-parameter.patch
CommitLineData
20209d8d
TL
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
3Date: Thu, 11 Apr 2024 11:29:25 +0200
4Subject: [PATCH] qapi: blockdev-backup: add discard-source parameter
5
6Add a parameter that enables discard-after-copy. That is mostly useful
7in "push backup with fleecing" scheme, when source is snapshot-access
8format driver node, based on copy-before-write filter snapshot-access
9API:
10
11[guest] [snapshot-access] ~~ blockdev-backup ~~> [backup target]
12 | |
13 | root | file
14 v v
15[copy-before-write]
16 | |
17 | file | target
18 v v
19[active disk] [temp.img]
20
21In this case discard-after-copy does two things:
22
23 - discard data in temp.img to save disk space
24 - avoid further copy-before-write operation in discarded area
25
26Note that we have to declare WRITE permission on source in
27copy-before-write filter, for discard to work. Still we can't take it
28unconditionally, as it will break normal backup from RO source. So, we
29have to add a parameter and pass it thorough bdrv_open flags.
30
31Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
32Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
33Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
34---
35 block/backup.c | 5 +++--
36 block/block-copy.c | 9 +++++++++
37 block/copy-before-write.c | 15 +++++++++++++--
38 block/copy-before-write.h | 1 +
39 block/replication.c | 4 ++--
40 blockdev.c | 2 +-
41 include/block/block-common.h | 2 ++
42 include/block/block-copy.h | 1 +
43 include/block/block_int-global-state.h | 2 +-
44 qapi/block-core.json | 4 ++++
45 10 files changed, 37 insertions(+), 8 deletions(-)
46
47diff --git a/block/backup.c b/block/backup.c
f1eed34a 48index aec140e0c8..f19b751fe6 100644
20209d8d
TL
49--- a/block/backup.c
50+++ b/block/backup.c
51@@ -332,7 +332,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
52 BlockDriverState *target, int64_t speed,
53 MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
54 BitmapSyncMode bitmap_mode,
55- bool compress,
56+ bool compress, bool discard_source,
57 const char *filter_node_name,
58 BackupPerf *perf,
59 BlockdevOnError on_source_error,
f1eed34a 60@@ -433,7 +433,8 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
20209d8d
TL
61 goto error;
62 }
63
64- cbw = bdrv_cbw_append(bs, target, filter_node_name, &bcs, errp);
65+ cbw = bdrv_cbw_append(bs, target, filter_node_name, discard_source,
66+ &bcs, errp);
67 if (!cbw) {
68 goto error;
69 }
70diff --git a/block/block-copy.c b/block/block-copy.c
f1eed34a 71index 8fca2c3698..7e3b378528 100644
20209d8d
TL
72--- a/block/block-copy.c
73+++ b/block/block-copy.c
74@@ -137,6 +137,7 @@ typedef struct BlockCopyState {
75 CoMutex lock;
76 int64_t in_flight_bytes;
77 BlockCopyMethod method;
78+ bool discard_source;
79 BlockReqList reqs;
80 QLIST_HEAD(, BlockCopyCallState) calls;
81 /*
f1eed34a 82@@ -353,6 +354,7 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target,
20209d8d
TL
83 BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
84 BlockDriverState *copy_bitmap_bs,
85 const BdrvDirtyBitmap *bitmap,
86+ bool discard_source,
87 Error **errp)
88 {
89 ERRP_GUARD();
f1eed34a 90@@ -418,6 +420,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
20209d8d
TL
91 cluster_size),
92 };
93
94+ s->discard_source = discard_source;
95 block_copy_set_copy_opts(s, false, false);
96
97 ratelimit_init(&s->rate_limit);
f1eed34a 98@@ -589,6 +592,12 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
20209d8d
TL
99 co_put_to_shres(s->mem, t->req.bytes);
100 block_copy_task_end(t, ret);
101
102+ if (s->discard_source && ret == 0) {
103+ int64_t nbytes =
104+ MIN(t->req.offset + t->req.bytes, s->len) - t->req.offset;
105+ bdrv_co_pdiscard(s->source, t->req.offset, nbytes);
106+ }
107+
108 return ret;
109 }
110
111diff --git a/block/copy-before-write.c b/block/copy-before-write.c
f1eed34a 112index afa5f473d2..5506f66857 100644
20209d8d
TL
113--- a/block/copy-before-write.c
114+++ b/block/copy-before-write.c
115@@ -44,6 +44,7 @@ typedef struct BDRVCopyBeforeWriteState {
116 BdrvChild *target;
117 OnCbwError on_cbw_error;
118 uint32_t cbw_timeout_ns;
119+ bool discard_source;
120
121 /*
122 * @lock: protects access to @access_bitmap, @done_bitmap and
f1eed34a
FE
123@@ -357,6 +358,8 @@ cbw_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role,
124 uint64_t perm, uint64_t shared,
125 uint64_t *nperm, uint64_t *nshared)
20209d8d
TL
126 {
127+ BDRVCopyBeforeWriteState *s = bs->opaque;
128+
129 if (!(role & BDRV_CHILD_FILTERED)) {
130 /*
131 * Target child
f1eed34a 132@@ -381,6 +384,10 @@ cbw_child_perm(BlockDriverState *bs, BdrvChild *c, BdrvChildRole role,
20209d8d
TL
133 * start
134 */
135 *nperm = *nperm | BLK_PERM_CONSISTENT_READ;
136+ if (s->discard_source) {
137+ *nperm = *nperm | BLK_PERM_WRITE;
138+ }
139+
140 *nshared &= ~(BLK_PERM_WRITE | BLK_PERM_RESIZE);
141 }
142 }
f1eed34a 143@@ -472,7 +479,9 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
20209d8d
TL
144 ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) &
145 bs->file->bs->supported_zero_flags);
146
147- s->bcs = block_copy_state_new(bs->file, s->target, bs, bitmap, errp);
148+ s->discard_source = flags & BDRV_O_CBW_DISCARD_SOURCE;
149+ s->bcs = block_copy_state_new(bs->file, s->target, bs, bitmap,
150+ flags & BDRV_O_CBW_DISCARD_SOURCE, errp);
151 if (!s->bcs) {
152 error_prepend(errp, "Cannot create block-copy-state: ");
153 ret = -EINVAL;
f1eed34a 154@@ -546,12 +555,14 @@ static BlockDriver bdrv_cbw_filter = {
20209d8d
TL
155 BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
156 BlockDriverState *target,
157 const char *filter_node_name,
158+ bool discard_source,
159 BlockCopyState **bcs,
160 Error **errp)
161 {
162 BDRVCopyBeforeWriteState *state;
163 BlockDriverState *top;
164 QDict *opts;
165+ int flags = BDRV_O_RDWR | (discard_source ? BDRV_O_CBW_DISCARD_SOURCE : 0);
166
167 assert(source->total_sectors == target->total_sectors);
168 GLOBAL_STATE_CODE();
f1eed34a 169@@ -564,7 +575,7 @@ BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
20209d8d
TL
170 qdict_put_str(opts, "file", bdrv_get_node_name(source));
171 qdict_put_str(opts, "target", bdrv_get_node_name(target));
172
173- top = bdrv_insert_node(source, opts, BDRV_O_RDWR, errp);
174+ top = bdrv_insert_node(source, opts, flags, errp);
175 if (!top) {
176 return NULL;
177 }
178diff --git a/block/copy-before-write.h b/block/copy-before-write.h
179index 6e72bb25e9..01af0cd3c4 100644
180--- a/block/copy-before-write.h
181+++ b/block/copy-before-write.h
182@@ -39,6 +39,7 @@
183 BlockDriverState *bdrv_cbw_append(BlockDriverState *source,
184 BlockDriverState *target,
185 const char *filter_node_name,
186+ bool discard_source,
187 BlockCopyState **bcs,
188 Error **errp);
189 void bdrv_cbw_drop(BlockDriverState *bs);
190diff --git a/block/replication.c b/block/replication.c
f1eed34a 191index 5ded5f1ca9..bd75a6aee3 100644
20209d8d
TL
192--- a/block/replication.c
193+++ b/block/replication.c
f1eed34a 194@@ -604,8 +604,8 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
20209d8d
TL
195
196 s->backup_job = backup_job_create(
197 NULL, s->secondary_disk->bs, s->hidden_disk->bs,
198- 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false, NULL,
199- &perf,
200+ 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false, false,
201+ NULL, &perf,
202 BLOCKDEV_ON_ERROR_REPORT,
203 BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
204 backup_job_completed, bs, NULL, &local_err);
205diff --git a/blockdev.c b/blockdev.c
f1eed34a 206index 3049811be8..e167ad1e54 100644
20209d8d
TL
207--- a/blockdev.c
208+++ b/blockdev.c
f1eed34a 209@@ -2854,7 +2854,7 @@ static BlockJob *do_backup_common(BackupCommon *backup,
20209d8d
TL
210
211 job = backup_job_create(backup->job_id, bs, target_bs, backup->speed,
212 backup->sync, bmap, backup->bitmap_mode,
213- backup->compress,
214+ backup->compress, backup->discard_source,
215 backup->filter_node_name,
216 &perf,
217 backup->on_source_error,
218diff --git a/include/block/block-common.h b/include/block/block-common.h
f1eed34a 219index d7599564db..7f56364e73 100644
20209d8d
TL
220--- a/include/block/block-common.h
221+++ b/include/block/block-common.h
f1eed34a 222@@ -246,6 +246,8 @@ typedef enum {
20209d8d
TL
223 read-write fails */
224 #define BDRV_O_IO_URING 0x40000 /* use io_uring instead of the thread pool */
225
226+#define BDRV_O_CBW_DISCARD_SOURCE 0x80000 /* for copy-before-write filter */
227+
228 #define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
229
230
231diff --git a/include/block/block-copy.h b/include/block/block-copy.h
232index 8b41643bfa..bdc703bacd 100644
233--- a/include/block/block-copy.h
234+++ b/include/block/block-copy.h
235@@ -27,6 +27,7 @@ typedef struct BlockCopyCallState BlockCopyCallState;
236 BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
237 BlockDriverState *copy_bitmap_bs,
238 const BdrvDirtyBitmap *bitmap,
239+ bool discard_source,
240 Error **errp);
241
242 /* Function should be called prior any actual copy request */
243diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
f1eed34a 244index 57265a617a..df731688b4 100644
20209d8d
TL
245--- a/include/block/block_int-global-state.h
246+++ b/include/block/block_int-global-state.h
247@@ -189,7 +189,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
248 MirrorSyncMode sync_mode,
249 BdrvDirtyBitmap *sync_bitmap,
250 BitmapSyncMode bitmap_mode,
251- bool compress,
252+ bool compress, bool discard_source,
253 const char *filter_node_name,
254 BackupPerf *perf,
255 BlockdevOnError on_source_error,
256diff --git a/qapi/block-core.json b/qapi/block-core.json
f1eed34a 257index 7b977459fa..82960797dc 100644
20209d8d
TL
258--- a/qapi/block-core.json
259+++ b/qapi/block-core.json
f1eed34a 260@@ -1834,6 +1834,9 @@
20209d8d
TL
261 # node specified by @drive. If this option is not given, a node
262 # name is autogenerated. (Since: 4.2)
263 #
264+# @discard-source: Discard blocks on source which are already copied
265+# to the target. (Since 9.0)
266+#
267 # @x-perf: Performance options. (Since 6.0)
268 #
269 # Features:
f1eed34a 270@@ -1855,6 +1858,7 @@
20209d8d
TL
271 '*on-target-error': 'BlockdevOnError',
272 '*auto-finalize': 'bool', '*auto-dismiss': 'bool',
273 '*filter-node-name': 'str',
274+ '*discard-source': 'bool',
275 '*x-perf': { 'type': 'BackupPerf',
276 'features': [ 'unstable' ] } } }
277