aboutsummaryrefslogtreecommitdiff
path: root/block/qcow2.h
diff options
context:
space:
mode:
authorAlberto Garcia <berto@igalia.com>2017-02-01 14:38:28 +0200
committerMax Reitz <mreitz@redhat.com>2017-02-12 00:47:43 +0100
commit7061a078984ba7d08b8b80686ad98c5162e56fbd (patch)
tree3d4e6b6144af862c2b1ecbc115938340dc05372b /block/qcow2.h
parentbf68bcb18e65e2fc6aaa55079740feee4c8b474c (diff)
downloadqemu-7061a078984ba7d08b8b80686ad98c5162e56fbd.zip
qemu-7061a078984ba7d08b8b80686ad98c5162e56fbd.tar.gz
qemu-7061a078984ba7d08b8b80686ad98c5162e56fbd.tar.bz2
qcow2: Optimize the refcount-block overlap check
The metadata overlap checks introduced in a40f1c2add help detect corruption in the qcow2 image by verifying that data writes don't overlap with existing metadata sections. The 'refcount-block' check in particular iterates over the refcount table in order to get the addresses of all refcount blocks and check that none of them overlap with the region where we want to write. The problem with the refcount table is that since it always occupies complete clusters its size is usually very big. With the default values of cluster_size=64KB and refcount_bits=16 this table holds 8192 entries, each one of them enough to map 2GB worth of host clusters. So unless we're using images with several TB of allocated data this table is going to be mostly empty, and iterating over it is a waste of CPU. If the storage backend is fast enough this can have an effect on I/O performance. This patch keeps the index of the last used (i.e. non-zero) entry in the refcount table and updates it every time the table changes. The refcount-block overlap check then uses that index instead of reading the whole table. In my tests with a 4GB qcow2 file stored in RAM this doubles the amount of write IOPS. Signed-off-by: Alberto Garcia <berto@igalia.com> Message-id: 20170201123828.4815-1-berto@igalia.com Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block/qcow2.h')
-rw-r--r--block/qcow2.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/block/qcow2.h b/block/qcow2.h
index 1823414..f8aeb08 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -251,6 +251,7 @@ typedef struct BDRVQcow2State {
uint64_t *refcount_table;
uint64_t refcount_table_offset;
uint32_t refcount_table_size;
+ uint32_t max_refcount_table_index; /* Last used entry in refcount_table */
uint64_t free_cluster_index;
uint64_t free_byte_offset;