mirror of
https://git.proxmox.com/git/pve-qemu
synced 2025-08-15 15:10:05 +00:00

Fix the two issues reported in the community forum[0][1], i.e. regression in LSI-53c895a controller and ignored boot order for USB storage (only possible via custom arguments in Proxmox VE), both causing boot failures, and pick up fixes for VirtIO, ARM emulation, char IO device and a graph lock fix for the block layer. The block-copy patches that serve as a preparation for fleecing are moved to the extra folder, because the graph lock fix requires them to be present first. They have been applied upstream in the meantime and should drop out with the rebase on 9.1. [0]: https://forum.proxmox.com/threads/149772/post-679433 [1]: https://forum.proxmox.com/threads/149772/post-683459 Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
134 lines
5.7 KiB
Diff
134 lines
5.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Fiona Ebner <f.ebner@proxmox.com>
|
|
Date: Thu, 11 Apr 2024 11:29:26 +0200
|
|
Subject: [PATCH] copy-before-write: allow specifying minimum cluster size
|
|
|
|
Useful to make discard-source work in the context of backup fleecing
|
|
when the fleecing image has a larger granularity than the backup
|
|
target.
|
|
|
|
Copy-before-write operations will use at least this granularity and in
|
|
particular, discard requests to the source node will too. If the
|
|
granularity is too small, they will just be aligned down in
|
|
cbw_co_pdiscard_snapshot() and thus effectively ignored.
|
|
|
|
The QAPI uses uint32 so the value will be non-negative, but still fit
|
|
into a uint64_t.
|
|
|
|
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
|
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
|
---
|
|
block/block-copy.c | 17 +++++++++++++----
|
|
block/copy-before-write.c | 3 ++-
|
|
include/block/block-copy.h | 1 +
|
|
qapi/block-core.json | 8 +++++++-
|
|
4 files changed, 23 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/block/block-copy.c b/block/block-copy.c
|
|
index cc618e4561..12d662e9d4 100644
|
|
--- a/block/block-copy.c
|
|
+++ b/block/block-copy.c
|
|
@@ -310,6 +310,7 @@ void block_copy_set_copy_opts(BlockCopyState *s, bool use_copy_range,
|
|
}
|
|
|
|
static int64_t block_copy_calculate_cluster_size(BlockDriverState *target,
|
|
+ int64_t min_cluster_size,
|
|
Error **errp)
|
|
{
|
|
int ret;
|
|
@@ -335,7 +336,7 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target,
|
|
"used. If the actual block size of the target exceeds "
|
|
"this default, the backup may be unusable",
|
|
BLOCK_COPY_CLUSTER_SIZE_DEFAULT);
|
|
- return BLOCK_COPY_CLUSTER_SIZE_DEFAULT;
|
|
+ return MAX(min_cluster_size, BLOCK_COPY_CLUSTER_SIZE_DEFAULT);
|
|
} else if (ret < 0 && !target_does_cow) {
|
|
error_setg_errno(errp, -ret,
|
|
"Couldn't determine the cluster size of the target image, "
|
|
@@ -345,16 +346,18 @@ static int64_t block_copy_calculate_cluster_size(BlockDriverState *target,
|
|
return ret;
|
|
} else if (ret < 0 && target_does_cow) {
|
|
/* Not fatal; just trudge on ahead. */
|
|
- return BLOCK_COPY_CLUSTER_SIZE_DEFAULT;
|
|
+ return MAX(min_cluster_size, BLOCK_COPY_CLUSTER_SIZE_DEFAULT);
|
|
}
|
|
|
|
- return MAX(BLOCK_COPY_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);
|
|
+ return MAX(min_cluster_size,
|
|
+ MAX(BLOCK_COPY_CLUSTER_SIZE_DEFAULT, bdi.cluster_size));
|
|
}
|
|
|
|
BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
|
|
BlockDriverState *copy_bitmap_bs,
|
|
const BdrvDirtyBitmap *bitmap,
|
|
bool discard_source,
|
|
+ int64_t min_cluster_size,
|
|
Error **errp)
|
|
{
|
|
ERRP_GUARD();
|
|
@@ -365,7 +368,13 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
|
|
|
|
GLOBAL_STATE_CODE();
|
|
|
|
- cluster_size = block_copy_calculate_cluster_size(target->bs, errp);
|
|
+ if (min_cluster_size && !is_power_of_2(min_cluster_size)) {
|
|
+ error_setg(errp, "min-cluster-size needs to be a power of 2");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ cluster_size = block_copy_calculate_cluster_size(target->bs,
|
|
+ min_cluster_size, errp);
|
|
if (cluster_size < 0) {
|
|
return NULL;
|
|
}
|
|
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
|
|
index 853e01a1eb..47b3cdd09f 100644
|
|
--- a/block/copy-before-write.c
|
|
+++ b/block/copy-before-write.c
|
|
@@ -477,7 +477,8 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
|
|
|
|
s->discard_source = flags & BDRV_O_CBW_DISCARD_SOURCE;
|
|
s->bcs = block_copy_state_new(bs->file, s->target, bs, bitmap,
|
|
- flags & BDRV_O_CBW_DISCARD_SOURCE, errp);
|
|
+ flags & BDRV_O_CBW_DISCARD_SOURCE,
|
|
+ opts->min_cluster_size, errp);
|
|
if (!s->bcs) {
|
|
error_prepend(errp, "Cannot create block-copy-state: ");
|
|
return -EINVAL;
|
|
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
|
|
index bdc703bacd..77857c6c68 100644
|
|
--- a/include/block/block-copy.h
|
|
+++ b/include/block/block-copy.h
|
|
@@ -28,6 +28,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
|
|
BlockDriverState *copy_bitmap_bs,
|
|
const BdrvDirtyBitmap *bitmap,
|
|
bool discard_source,
|
|
+ int64_t min_cluster_size,
|
|
Error **errp);
|
|
|
|
/* Function should be called prior any actual copy request */
|
|
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
|
index 282e2e8a8c..9caf04cbe9 100644
|
|
--- a/qapi/block-core.json
|
|
+++ b/qapi/block-core.json
|
|
@@ -4926,12 +4926,18 @@
|
|
# @on-cbw-error parameter will decide how this failure is handled.
|
|
# Default 0. (Since 7.1)
|
|
#
|
|
+# @min-cluster-size: Minimum size of blocks used by copy-before-write
|
|
+# operations. Has to be a power of 2. No effect if smaller than
|
|
+# the maximum of the target's cluster size and 64 KiB. Default 0.
|
|
+# (Since 8.1)
|
|
+#
|
|
# Since: 6.2
|
|
##
|
|
{ 'struct': 'BlockdevOptionsCbw',
|
|
'base': 'BlockdevOptionsGenericFormat',
|
|
'data': { 'target': 'BlockdevRef', '*bitmap': 'BlockDirtyBitmap',
|
|
- '*on-cbw-error': 'OnCbwError', '*cbw-timeout': 'uint32' } }
|
|
+ '*on-cbw-error': 'OnCbwError', '*cbw-timeout': 'uint32',
|
|
+ '*min-cluster-size': 'uint32' } }
|
|
|
|
##
|
|
# @BlockdevOptions:
|