[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 25/38] block/parallels: add prealloc-mode and preallo
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PULL 25/38] block/parallels: add prealloc-mode and prealloc-size open paramemets |
Date: |
Fri, 22 May 2015 10:01:57 +0100 |
From: "Denis V. Lunev" <address@hidden>
This is preparational commit for tweaks in Parallels image expansion.
The idea is that enlarge via truncate by one data block is slow. It
would be much better to use fallocate via bdrv_write_zeroes and
expand by some significant amount at once.
Original idea with sequential file writing to the end of the file without
fallocate/truncate would be slower than this approach if the image is
expanded with several operations:
- each image expanding means file metadata update, i.e. filesystem
journal write. Truncate/write to newly truncated space update file
metadata twice thus truncate removal helps. With fallocate call
inside bdrv_write_zeroes file metadata is updated only once and
this should happen infrequently thus this approach is the best one
for the image expansion
- tail writes are ordered, i.e. the guest IO queue could not be sent
immediately to the host introducing additional IO delays
This patch just adds proper parameters into BDRVParallelsState and
performs options parsing in parallels_open.
Signed-off-by: Denis V. Lunev <address@hidden>
Reviewed-by: Roman Kagan <address@hidden>
Signed-off-by: Roman Kagan <address@hidden>
Message-id: address@hidden
CC: Roman Kagan <address@hidden>
CC: Kevin Wolf <address@hidden>
CC: Stefan Hajnoczi <address@hidden>
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
block/parallels.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 77 insertions(+), 6 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index 05fe030..440938e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -31,6 +31,7 @@
#include "block/block_int.h"
#include "qemu/module.h"
#include "qemu/bitmap.h"
+#include "qapi/util.h"
/**************************************************************/
@@ -56,6 +57,20 @@ typedef struct ParallelsHeader {
char padding[12];
} QEMU_PACKED ParallelsHeader;
+
+typedef enum ParallelsPreallocMode {
+ PRL_PREALLOC_MODE_FALLOCATE = 0,
+ PRL_PREALLOC_MODE_TRUNCATE = 1,
+ PRL_PREALLOC_MODE_MAX = 2,
+} ParallelsPreallocMode;
+
+static const char *prealloc_mode_lookup[] = {
+ "falloc",
+ "truncate",
+ NULL,
+};
+
+
typedef struct BDRVParallelsState {
/** Locking is conservative, the lock protects
* - image file extending (truncate, fallocate)
@@ -73,14 +88,40 @@ typedef struct BDRVParallelsState {
uint32_t *bat_bitmap;
unsigned int bat_size;
+ uint64_t prealloc_size;
+ ParallelsPreallocMode prealloc_mode;
+
unsigned int tracks;
unsigned int off_multiplier;
-
- bool has_truncate;
} BDRVParallelsState;
+#define PARALLELS_OPT_PREALLOC_MODE "prealloc-mode"
+#define PARALLELS_OPT_PREALLOC_SIZE "prealloc-size"
+
+static QemuOptsList parallels_runtime_opts = {
+ .name = "parallels",
+ .head = QTAILQ_HEAD_INITIALIZER(parallels_runtime_opts.head),
+ .desc = {
+ {
+ .name = PARALLELS_OPT_PREALLOC_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Preallocation size on image expansion",
+ .def_value_str = "128MiB",
+ },
+ {
+ .name = PARALLELS_OPT_PREALLOC_MODE,
+ .type = QEMU_OPT_STRING,
+ .help = "Preallocation mode on image expansion "
+ "(allowed values: falloc, truncate)",
+ .def_value_str = "falloc",
+ },
+ { /* end of list */ },
+ },
+};
+
+
static int64_t bat2sect(BDRVParallelsState *s, uint32_t idx)
{
return (uint64_t)le32_to_cpu(s->bat_bitmap[idx]) * s->off_multiplier;
@@ -159,7 +200,7 @@ static int64_t allocate_cluster(BlockDriverState *bs,
int64_t sector_num)
}
pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
- if (s->has_truncate) {
+ if (s->prealloc_mode == PRL_PREALLOC_MODE_TRUNCATE) {
ret = bdrv_truncate(bs->file, (pos + s->tracks) << BDRV_SECTOR_BITS);
} else {
ret = bdrv_write_zeroes(bs->file, pos, s->tracks, 0);
@@ -509,6 +550,9 @@ static int parallels_open(BlockDriverState *bs, QDict
*options, int flags,
BDRVParallelsState *s = bs->opaque;
ParallelsHeader ph;
int ret, size;
+ QemuOpts *opts = NULL;
+ Error *local_err = NULL;
+ char *buf;
ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
if (ret < 0) {
@@ -567,9 +611,6 @@ static int parallels_open(BlockDriverState *bs, QDict
*options, int flags,
}
s->bat_bitmap = (uint32_t *)(s->header + 1);
- s->has_truncate = bdrv_has_zero_init(bs->file) &&
- bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
-
if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
/* Image was not closed correctly. The check is mandatory */
s->header_unclean = true;
@@ -581,6 +622,31 @@ static int parallels_open(BlockDriverState *bs, QDict
*options, int flags,
}
}
+ opts = qemu_opts_create(¶llels_runtime_opts, NULL, 0, &local_err);
+ if (local_err != NULL) {
+ goto fail_options;
+ }
+
+ qemu_opts_absorb_qdict(opts, options, &local_err);
+ if (local_err != NULL) {
+ goto fail_options;
+ }
+
+ s->prealloc_size =
+ qemu_opt_get_size_del(opts, PARALLELS_OPT_PREALLOC_SIZE, 0);
+ s->prealloc_size = MAX(s->tracks, s->prealloc_size >> BDRV_SECTOR_BITS);
+ buf = qemu_opt_get_del(opts, PARALLELS_OPT_PREALLOC_MODE);
+ s->prealloc_mode = qapi_enum_parse(prealloc_mode_lookup, buf,
+ PRL_PREALLOC_MODE_MAX, PRL_PREALLOC_MODE_FALLOCATE, &local_err);
+ g_free(buf);
+ if (local_err != NULL) {
+ goto fail_options;
+ }
+ if (!bdrv_has_zero_init(bs->file) ||
+ bdrv_truncate(bs->file, bdrv_getlength(bs->file)) != 0) {
+ s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
+ }
+
if (flags & BDRV_O_RDWR) {
s->header->inuse = cpu_to_le32(HEADER_INUSE_MAGIC);
ret = parallels_update_header(bs);
@@ -602,6 +668,11 @@ fail_format:
fail:
qemu_vfree(s->header);
return ret;
+
+fail_options:
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto fail;
}
--
2.1.0
- [Qemu-devel] [PULL 17/38] block/parallels: read parallels image header and BAT into single buffer, (continued)
- [Qemu-devel] [PULL 17/38] block/parallels: read parallels image header and BAT into single buffer, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 20/38] block/parallels: implement incorrect close detection, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 21/38] iotests, parallels: check for incorrectly closed image in tests, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 24/38] block/parallels: delay writing to BAT till bdrv_co_flush_to_os, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 22/38] block/parallels: improve image reading performance, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 23/38] block/parallels: create bat_entry_off helper, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 26/38] block/parallels: optimize linear image expansion, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 28/38] configure: handle clang -nopie argument warning, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 27/38] block/parallels: improve image writing performance further, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 29/38] configure: factor out supported flag check, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 25/38] block/parallels: add prealloc-mode and prealloc-size open paramemets,
Stefan Hajnoczi <=
- [Qemu-devel] [PULL 30/38] configure: silence glib unknown attribute __alloc_size__, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 31/38] configure: Add workaround for ccache and clang, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 33/38] block: minimal bounce buffer alignment, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 34/38] block: align bounce buffers to page, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 35/38] Revert "block: Fix unaligned zero write", Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 32/38] block: return EPERM on writes or discards to read-only devices, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 38/38] block: get_block_status: use "else" when testing the opposite condition, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 37/38] qemu-iotests: Test unaligned sub-block zero write, Stefan Hajnoczi, 2015/05/22
- [Qemu-devel] [PULL 36/38] block: Fix NULL deference for unaligned write if qiov is NULL, Stefan Hajnoczi, 2015/05/22
- Re: [Qemu-devel] [PULL 00/38] Block patches, Peter Maydell, 2015/05/22