aboutsummaryrefslogtreecommitdiff
path: root/include/block/block.h
diff options
context:
space:
mode:
authorAlberto Garcia <berto@igalia.com>2020-10-26 17:58:27 +0100
committerKevin Wolf <kwolf@redhat.com>2020-10-27 15:26:20 +0100
commit46cd1e8a4752379b1b9d24d43d7be7d5aba03e76 (patch)
tree80e3cdb749aa69fdaeef588a6e9603634a7d33c2 /include/block/block.h
parentd40f4a565aa64a1ef1e1ff73caf53d61cac9a67f (diff)
qcow2: Skip copy-on-write when allocating a zero cluster
Since commit c8bb23cbdbe32f5c326365e0a82e1b0e68cdcd8a when a write request results in a new allocation QEMU first tries to see if the rest of the cluster outside the written area contains only zeroes. In that case, instead of doing a normal copy-on-write operation and writing explicit zero buffers to disk, the code zeroes the whole cluster efficiently using pwrite_zeroes() with BDRV_REQ_NO_FALLBACK. This improves performance very significantly but it only happens when we are writing to an area that was completely unallocated before. Zero clusters (QCOW2_CLUSTER_ZERO_*) are treated like normal clusters and are therefore slower to allocate. This happens because the code uses bdrv_is_allocated_above() rather bdrv_block_status_above(). The former is not as accurate for this purpose but it is faster. However in the case of qcow2 the underlying call does already report zero clusters just fine so there is no reason why we cannot use that information. After testing 4KB writes on an image that only contains zero clusters this patch results in almost five times more IOPS. Signed-off-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-Id: <6d77cab968c501c44d6e1089b9bc91b04170b49e.1603731354.git.berto@igalia.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'include/block/block.h')
-rw-r--r--include/block/block.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/include/block/block.h b/include/block/block.h
index d16c401cb4..c9d7c58765 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -508,6 +508,8 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
bool include_base, int64_t offset, int64_t bytes,
int64_t *pnum);
+int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
+ int64_t bytes);
bool bdrv_is_read_only(BlockDriverState *bs);
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,