summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/parallels.c5
-rw-r--r--hw/block/virtio-blk.c13
-rw-r--r--tests/test-throttle.c8
-rw-r--r--util/throttle.c5
4 files changed, 27 insertions, 4 deletions
diff --git a/block/parallels.c b/block/parallels.c
index 807a80169f..2ccefa7d85 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -43,6 +43,7 @@
#define HEADER_MAGIC2 "WithouFreSpacExt"
#define HEADER_VERSION 2
#define HEADER_INUSE_MAGIC (0x746F6E59)
+#define MAX_PARALLELS_IMAGE_FACTOR (1ull << 32)
#define DEFAULT_CLUSTER_SIZE 1048576 /* 1 MiB */
@@ -475,6 +476,10 @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
BDRV_SECTOR_SIZE);
cl_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
DEFAULT_CLUSTER_SIZE), BDRV_SECTOR_SIZE);
+ if (total_size >= MAX_PARALLELS_IMAGE_FACTOR * cl_size) {
+ error_propagate(errp, local_err);
+ return -E2BIG;
+ }
ret = bdrv_create_file(filename, opts, &local_err);
if (ret < 0) {
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 475a822f5a..331d7667ec 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -654,15 +654,20 @@ static void virtio_blk_reset(VirtIODevice *vdev)
{
VirtIOBlock *s = VIRTIO_BLK(vdev);
AioContext *ctx;
+ VirtIOBlockReq *req;
- /*
- * This should cancel pending requests, but can't do nicely until there
- * are per-device request lists.
- */
ctx = blk_get_aio_context(s->blk);
aio_context_acquire(ctx);
blk_drain(s->blk);
+ /* We drop queued requests after blk_drain() because blk_drain() itself can
+ * produce them. */
+ while (s->rq) {
+ req = s->rq;
+ s->rq = req->next;
+ virtio_blk_free_request(req);
+ }
+
if (s->dataplane) {
virtio_blk_data_plane_stop(s->dataplane);
}
diff --git a/tests/test-throttle.c b/tests/test-throttle.c
index afe094bcc4..363b59a38f 100644
--- a/tests/test-throttle.c
+++ b/tests/test-throttle.c
@@ -394,6 +394,14 @@ static void test_max_is_missing_limit(void)
cfg.buckets[i].max = 0;
cfg.buckets[i].avg = 100;
g_assert(throttle_is_valid(&cfg, NULL));
+
+ cfg.buckets[i].max = 30;
+ cfg.buckets[i].avg = 100;
+ g_assert(!throttle_is_valid(&cfg, NULL));
+
+ cfg.buckets[i].max = 100;
+ cfg.buckets[i].avg = 100;
+ g_assert(throttle_is_valid(&cfg, NULL));
}
}
diff --git a/util/throttle.c b/util/throttle.c
index 654f95caf2..3817d9b904 100644
--- a/util/throttle.c
+++ b/util/throttle.c
@@ -348,6 +348,11 @@ bool throttle_is_valid(ThrottleConfig *cfg, Error **errp)
" bps/iops values");
return false;
}
+
+ if (cfg->buckets[i].max && cfg->buckets[i].max < cfg->buckets[i].avg) {
+ error_setg(errp, "bps_max/iops_max cannot be lower than bps/iops");
+ return false;
+ }
}
return true;