aboutsummaryrefslogtreecommitdiff
path: root/block/qcow2-cache.c
diff options
context:
space:
mode:
authorAlberto Garcia <berto@igalia.com>2015-05-11 15:54:54 +0300
committerKevin Wolf <kwolf@redhat.com>2015-05-22 17:08:01 +0200
commitbaf07d60f5c5d5d0f0c9e844cde75691f1ceb3d1 (patch)
tree795df88d7f949ffd0ccc8f93463383d3a3e6cf6f /block/qcow2-cache.c
parent72e80b89015bab196f0f0e83b12b0eee75fa0574 (diff)
qcow2: simplify qcow2_cache_put() and qcow2_cache_entry_mark_dirty()
Since all tables are now stored together, it is possible to obtain the position of a particular table directly from its address, so the operation becomes O(1). Signed-off-by: Alberto Garcia <berto@igalia.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/qcow2-cache.c')
-rw-r--r--block/qcow2-cache.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
index f0dfb69cc1..6e78c8ffba 100644
--- a/block/qcow2-cache.c
+++ b/block/qcow2-cache.c
@@ -49,6 +49,16 @@ static inline void *qcow2_cache_get_table_addr(BlockDriverState *bs,
return (uint8_t *) c->table_array + (size_t) table * s->cluster_size;
}
+static inline int qcow2_cache_get_table_idx(BlockDriverState *bs,
+ Qcow2Cache *c, void *table)
+{
+ BDRVQcowState *s = bs->opaque;
+ ptrdiff_t table_offset = (uint8_t *) table - (uint8_t *) c->table_array;
+ int idx = table_offset / s->cluster_size;
+ assert(idx >= 0 && idx < c->size && table_offset % s->cluster_size == 0);
+ return idx;
+}
+
Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
{
BDRVQcowState *s = bs->opaque;
@@ -337,16 +347,12 @@ int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table)
{
- int i;
+ int i = qcow2_cache_get_table_idx(bs, c, *table);
- for (i = 0; i < c->size; i++) {
- if (qcow2_cache_get_table_addr(bs, c, i) == *table) {
- goto found;
- }
+ if (c->entries[i].offset == 0) {
+ return -ENOENT;
}
- return -ENOENT;
-found:
c->entries[i].ref--;
*table = NULL;
@@ -357,15 +363,7 @@ found:
void qcow2_cache_entry_mark_dirty(BlockDriverState *bs, Qcow2Cache *c,
void *table)
{
- int i;
-
- for (i = 0; i < c->size; i++) {
- if (qcow2_cache_get_table_addr(bs, c, i) == table) {
- goto found;
- }
- }
- abort();
-
-found:
+ int i = qcow2_cache_get_table_idx(bs, c, table);
+ assert(c->entries[i].offset != 0);
c->entries[i].dirty = true;
}