summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/backup.c28
-rw-r--r--block/replication.c2
-rw-r--r--blockdev.c8
-rw-r--r--qapi/block-core.json13
4 files changed, 43 insertions, 8 deletions
diff --git a/block/backup.c b/block/backup.c
index 09ff5a92ef..5522c0f3fe 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -388,6 +388,29 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
return NULL;
}
+ cluster_size = backup_calculate_cluster_size(target, errp);
+ if (cluster_size < 0) {
+ goto error;
+ }
+
+ if (perf->max_workers < 1) {
+ error_setg(errp, "max-workers must be greater than zero");
+ return NULL;
+ }
+
+ if (perf->max_chunk < 0) {
+ error_setg(errp, "max-chunk must be zero (which means no limit) or "
+ "positive");
+ return NULL;
+ }
+
+ if (perf->max_chunk && perf->max_chunk < cluster_size) {
+ error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
+ "cluster size (%" PRIi64 ")", perf->max_chunk, cluster_size);
+ return NULL;
+ }
+
+
if (sync_bitmap) {
/* If we need to write to this bitmap, check that we can: */
if (bitmap_mode != BITMAP_SYNC_MODE_NEVER &&
@@ -420,11 +443,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
goto error;
}
- cluster_size = backup_calculate_cluster_size(target, errp);
- if (cluster_size < 0) {
- goto error;
- }
-
/*
* If source is in backing chain of target assume that target is going to be
* used for "image fleecing", i.e. it should represent a kind of snapshot of
diff --git a/block/replication.c b/block/replication.c
index 22ffc811ee..97be7ef4de 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -454,7 +454,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
int64_t active_length, hidden_length, disk_length;
AioContext *aio_context;
Error *local_err = NULL;
- BackupPerf perf = { .use_copy_range = true };
+ BackupPerf perf = { .use_copy_range = true, .max_workers = 1 };
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
diff --git a/blockdev.c b/blockdev.c
index fc88dc03e1..25aaacf253 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2829,7 +2829,7 @@ static BlockJob *do_backup_common(BackupCommon *backup,
{
BlockJob *job = NULL;
BdrvDirtyBitmap *bmap = NULL;
- BackupPerf perf = { .use_copy_range = true };
+ BackupPerf perf = { .use_copy_range = true, .max_workers = 64 };
int job_flags = JOB_DEFAULT;
if (!backup->has_speed) {
@@ -2858,6 +2858,12 @@ static BlockJob *do_backup_common(BackupCommon *backup,
if (backup->x_perf->has_use_copy_range) {
perf.use_copy_range = backup->x_perf->use_copy_range;
}
+ if (backup->x_perf->has_max_workers) {
+ perf.max_workers = backup->x_perf->max_workers;
+ }
+ if (backup->x_perf->has_max_chunk) {
+ perf.max_chunk = backup->x_perf->max_chunk;
+ }
}
if ((backup->sync == MIRROR_SYNC_MODE_BITMAP) ||
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 83f661d7f6..abcd41ed63 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1379,10 +1379,21 @@
#
# @use-copy-range: Use copy offloading. Default true.
#
+# @max-workers: Maximum number of parallel requests for the sustained background
+# copying process. Doesn't influence copy-before-write operations.
+# Default 64.
+#
+# @max-chunk: Maximum request length for the sustained background copying
+# process. Doesn't influence copy-before-write operations.
+# 0 means unlimited. If max-chunk is non-zero then it should not be
+# less than job cluster size which is calculated as maximum of
+# target image cluster size and 64k. Default 0.
+#
# Since: 6.0
##
{ 'struct': 'BackupPerf',
- 'data': { '*use-copy-range': 'bool' }}
+ 'data': { '*use-copy-range': 'bool',
+ '*max-workers': 'int', '*max-chunk': 'int64' } }
##
# @BackupCommon: