From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Cc: kwolf@redhat.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH V12 4/6] rename qcow2-cache.c to block-cache.c
Date: Thu, 6 Sep 2012 12:52:26 -0500 [thread overview]
Message-ID: <20120906175226.GD522@illuin> (raw)
In-Reply-To: <1344613185-12308-5-git-send-email-wdongxu@linux.vnet.ibm.com>
On Fri, Aug 10, 2012 at 11:39:43PM +0800, Dong Xu Wang wrote:
> add-cow and qcow2 file format will share the same cache code, so rename
> block-cache.c to block-cache.c. And related structure and qcow2 code also
"qcow2-cache.c to block-cache.c"
But I've scanned through the rest of your patches and can't seem to find
where block-cache.c gets introduced. Did you forget to git add it?
> are changed.
>
> Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
> ---
> block.h | 3 +
> block/Makefile.objs | 3 +-
> block/qcow2-cache.c | 323 ------------------------------------------------
> block/qcow2-cluster.c | 66 ++++++----
> block/qcow2-refcount.c | 66 ++++++-----
> block/qcow2.c | 36 +++---
> block/qcow2.h | 24 +---
> trace-events | 13 +-
> 8 files changed, 109 insertions(+), 425 deletions(-)
> delete mode 100644 block/qcow2-cache.c
>
> diff --git a/block.h b/block.h
> index e5dfcd7..c325661 100644
> --- a/block.h
> +++ b/block.h
> @@ -401,6 +401,9 @@ typedef enum {
> BLKDBG_CLUSTER_ALLOC_BYTES,
> BLKDBG_CLUSTER_FREE,
>
> + BLKDBG_ADD_COW_UPDATE,
> + BLKDBG_ADD_COW_LOAD,
> +
> BLKDBG_EVENT_MAX,
> } BlkDebugEvent;
>
> diff --git a/block/Makefile.objs b/block/Makefile.objs
> index b5754d3..23bdfc8 100644
> --- a/block/Makefile.objs
> +++ b/block/Makefile.objs
> @@ -1,7 +1,8 @@
> block-obj-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
> -block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
> +block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o
> block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
> block-obj-y += qed-check.o
> +block-obj-y += block-cache.o
> block-obj-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
> block-obj-y += stream.o
> block-obj-$(CONFIG_WIN32) += raw-win32.o
> diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
> deleted file mode 100644
> index 2d4322a..0000000
> --- a/block/qcow2-cache.c
> +++ /dev/null
> @@ -1,323 +0,0 @@
> -/*
> - * L2/refcount table cache for the QCOW2 format
> - *
> - * Copyright (c) 2010 Kevin Wolf <kwolf@redhat.com>
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a copy
> - * of this software and associated documentation files (the "Software"), to deal
> - * in the Software without restriction, including without limitation the rights
> - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> - * copies of the Software, and to permit persons to whom the Software is
> - * furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice shall be included in
> - * all copies or substantial portions of the Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> - * THE SOFTWARE.
> - */
> -
> -#include "block_int.h"
> -#include "qemu-common.h"
> -#include "qcow2.h"
> -#include "trace.h"
> -
> -typedef struct Qcow2CachedTable {
> - void* table;
> - int64_t offset;
> - bool dirty;
> - int cache_hits;
> - int ref;
> -} Qcow2CachedTable;
> -
> -struct Qcow2Cache {
> - Qcow2CachedTable* entries;
> - struct Qcow2Cache* depends;
> - int size;
> - bool depends_on_flush;
> -};
> -
> -Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables)
> -{
> - BDRVQcowState *s = bs->opaque;
> - Qcow2Cache *c;
> - int i;
> -
> - c = g_malloc0(sizeof(*c));
> - c->size = num_tables;
> - c->entries = g_malloc0(sizeof(*c->entries) * num_tables);
> -
> - for (i = 0; i < c->size; i++) {
> - c->entries[i].table = qemu_blockalign(bs, s->cluster_size);
> - }
> -
> - return c;
> -}
> -
> -int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c)
> -{
> - int i;
> -
> - for (i = 0; i < c->size; i++) {
> - assert(c->entries[i].ref == 0);
> - qemu_vfree(c->entries[i].table);
> - }
> -
> - g_free(c->entries);
> - g_free(c);
> -
> - return 0;
> -}
> -
> -static int qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow2Cache *c)
> -{
> - int ret;
> -
> - ret = qcow2_cache_flush(bs, c->depends);
> - if (ret < 0) {
> - return ret;
> - }
> -
> - c->depends = NULL;
> - c->depends_on_flush = false;
> -
> - return 0;
> -}
> -
> -static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
> -{
> - BDRVQcowState *s = bs->opaque;
> - int ret = 0;
> -
> - if (!c->entries[i].dirty || !c->entries[i].offset) {
> - return 0;
> - }
> -
> - trace_qcow2_cache_entry_flush(qemu_coroutine_self(),
> - c == s->l2_table_cache, i);
> -
> - if (c->depends) {
> - ret = qcow2_cache_flush_dependency(bs, c);
> - } else if (c->depends_on_flush) {
> - ret = bdrv_flush(bs->file);
> - if (ret >= 0) {
> - c->depends_on_flush = false;
> - }
> - }
> -
> - if (ret < 0) {
> - return ret;
> - }
> -
> - if (c == s->refcount_block_cache) {
> - BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART);
> - } else if (c == s->l2_table_cache) {
> - BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
> - }
> -
> - ret = bdrv_pwrite(bs->file, c->entries[i].offset, c->entries[i].table,
> - s->cluster_size);
> - if (ret < 0) {
> - return ret;
> - }
> -
> - c->entries[i].dirty = false;
> -
> - return 0;
> -}
> -
> -int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
> -{
> - BDRVQcowState *s = bs->opaque;
> - int result = 0;
> - int ret;
> - int i;
> -
> - trace_qcow2_cache_flush(qemu_coroutine_self(), c == s->l2_table_cache);
> -
> - for (i = 0; i < c->size; i++) {
> - ret = qcow2_cache_entry_flush(bs, c, i);
> - if (ret < 0 && result != -ENOSPC) {
> - result = ret;
> - }
> - }
> -
> - if (result == 0) {
> - ret = bdrv_flush(bs->file);
> - if (ret < 0) {
> - result = ret;
> - }
> - }
> -
> - return result;
> -}
> -
> -int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
> - Qcow2Cache *dependency)
> -{
> - int ret;
> -
> - if (dependency->depends) {
> - ret = qcow2_cache_flush_dependency(bs, dependency);
> - if (ret < 0) {
> - return ret;
> - }
> - }
> -
> - if (c->depends && (c->depends != dependency)) {
> - ret = qcow2_cache_flush_dependency(bs, c);
> - if (ret < 0) {
> - return ret;
> - }
> - }
> -
> - c->depends = dependency;
> - return 0;
> -}
> -
> -void qcow2_cache_depends_on_flush(Qcow2Cache *c)
> -{
> - c->depends_on_flush = true;
> -}
> -
> -static int qcow2_cache_find_entry_to_replace(Qcow2Cache *c)
> -{
> - int i;
> - int min_count = INT_MAX;
> - int min_index = -1;
> -
> -
> - for (i = 0; i < c->size; i++) {
> - if (c->entries[i].ref) {
> - continue;
> - }
> -
> - if (c->entries[i].cache_hits < min_count) {
> - min_index = i;
> - min_count = c->entries[i].cache_hits;
> - }
> -
> - /* Give newer hits priority */
> - /* TODO Check how to optimize the replacement strategy */
> - c->entries[i].cache_hits /= 2;
> - }
> -
> - if (min_index == -1) {
> - /* This can't happen in current synchronous code, but leave the check
> - * here as a reminder for whoever starts using AIO with the cache */
> - abort();
> - }
> - return min_index;
> -}
> -
> -static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c,
> - uint64_t offset, void **table, bool read_from_disk)
> -{
> - BDRVQcowState *s = bs->opaque;
> - int i;
> - int ret;
> -
> - trace_qcow2_cache_get(qemu_coroutine_self(), c == s->l2_table_cache,
> - offset, read_from_disk);
> -
> - /* Check if the table is already cached */
> - for (i = 0; i < c->size; i++) {
> - if (c->entries[i].offset == offset) {
> - goto found;
> - }
> - }
> -
> - /* If not, write a table back and replace it */
> - i = qcow2_cache_find_entry_to_replace(c);
> - trace_qcow2_cache_get_replace_entry(qemu_coroutine_self(),
> - c == s->l2_table_cache, i);
> - if (i < 0) {
> - return i;
> - }
> -
> - ret = qcow2_cache_entry_flush(bs, c, i);
> - if (ret < 0) {
> - return ret;
> - }
> -
> - trace_qcow2_cache_get_read(qemu_coroutine_self(),
> - c == s->l2_table_cache, i);
> - c->entries[i].offset = 0;
> - if (read_from_disk) {
> - if (c == s->l2_table_cache) {
> - BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
> - }
> -
> - ret = bdrv_pread(bs->file, offset, c->entries[i].table, s->cluster_size);
> - if (ret < 0) {
> - return ret;
> - }
> - }
> -
> - /* Give the table some hits for the start so that it won't be replaced
> - * immediately. The number 32 is completely arbitrary. */
> - c->entries[i].cache_hits = 32;
> - c->entries[i].offset = offset;
> -
> - /* And return the right table */
> -found:
> - c->entries[i].cache_hits++;
> - c->entries[i].ref++;
> - *table = c->entries[i].table;
> -
> - trace_qcow2_cache_get_done(qemu_coroutine_self(),
> - c == s->l2_table_cache, i);
> -
> - return 0;
> -}
> -
> -int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
> - void **table)
> -{
> - return qcow2_cache_do_get(bs, c, offset, table, true);
> -}
> -
> -int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
> - void **table)
> -{
> - return qcow2_cache_do_get(bs, c, offset, table, false);
> -}
> -
> -int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table)
> -{
> - int i;
> -
> - for (i = 0; i < c->size; i++) {
> - if (c->entries[i].table == *table) {
> - goto found;
> - }
> - }
> - return -ENOENT;
> -
> -found:
> - c->entries[i].ref--;
> - *table = NULL;
> -
> - assert(c->entries[i].ref >= 0);
> - return 0;
> -}
> -
> -void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table)
> -{
> - int i;
> -
> - for (i = 0; i < c->size; i++) {
> - if (c->entries[i].table == table) {
> - goto found;
> - }
> - }
> - abort();
> -
> -found:
> - c->entries[i].dirty = true;
> -}
> diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
> index e179211..335dc7a 100644
> --- a/block/qcow2-cluster.c
> +++ b/block/qcow2-cluster.c
> @@ -28,6 +28,7 @@
> #include "block_int.h"
> #include "block/qcow2.h"
> #include "trace.h"
> +#include "block-cache.h"
>
> int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
> {
> @@ -69,7 +70,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
> return new_l1_table_offset;
> }
>
> - ret = qcow2_cache_flush(bs, s->refcount_block_cache);
> + ret = block_cache_flush(bs, s->refcount_block_cache,
> + BLOCK_TABLE_REF, s->cluster_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -119,7 +121,8 @@ static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
> BDRVQcowState *s = bs->opaque;
> int ret;
>
> - ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset, (void**) l2_table);
> + ret = block_cache_get(bs, s->l2_table_cache, l2_offset,
> + (void **) l2_table, BLOCK_TABLE_L2, s->cluster_size);
>
> return ret;
> }
> @@ -180,7 +183,8 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
> return l2_offset;
> }
>
> - ret = qcow2_cache_flush(bs, s->refcount_block_cache);
> + ret = block_cache_flush(bs, s->refcount_block_cache,
> + BLOCK_TABLE_REF, s->cluster_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -188,7 +192,8 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
> /* allocate a new entry in the l2 cache */
>
> trace_qcow2_l2_allocate_get_empty(bs, l1_index);
> - ret = qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void**) table);
> + ret = block_cache_get_empty(bs, s->l2_table_cache, l2_offset,
> + (void **) table, BLOCK_TABLE_L2, s->cluster_size);
> if (ret < 0) {
> return ret;
> }
> @@ -203,16 +208,17 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
>
> /* if there was an old l2 table, read it from the disk */
> BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ);
> - ret = qcow2_cache_get(bs, s->l2_table_cache,
> + ret = block_cache_get(bs, s->l2_table_cache,
> old_l2_offset & L1E_OFFSET_MASK,
> - (void**) &old_table);
> + (void **) &old_table, BLOCK_TABLE_L2, s->cluster_size);
> if (ret < 0) {
> goto fail;
> }
>
> memcpy(l2_table, old_table, s->cluster_size);
>
> - ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &old_table);
> + ret = block_cache_put(bs, s->l2_table_cache,
> + (void **) &old_table, BLOCK_TABLE_L2);
> if (ret < 0) {
> goto fail;
> }
> @@ -222,8 +228,9 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
> BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE);
>
> trace_qcow2_l2_allocate_write_l2(bs, l1_index);
> - qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> - ret = qcow2_cache_flush(bs, s->l2_table_cache);
> + block_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> + ret = block_cache_flush(bs, s->l2_table_cache,
> + BLOCK_TABLE_L2, s->cluster_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -242,7 +249,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
>
> fail:
> trace_qcow2_l2_allocate_done(bs, l1_index, ret);
> - qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
> + block_cache_put(bs, s->l2_table_cache, (void **) table, BLOCK_TABLE_L2);
> s->l1_table[l1_index] = old_l2_offset;
> return ret;
> }
> @@ -475,7 +482,7 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
> abort();
> }
>
> - qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + block_cache_put(bs, s->l2_table_cache, (void **) &l2_table, BLOCK_TABLE_L2);
>
> nb_available = (c * s->cluster_sectors);
>
> @@ -584,13 +591,15 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
> * allocated. */
> cluster_offset = be64_to_cpu(l2_table[l2_index]);
> if (cluster_offset & L2E_OFFSET_MASK) {
> - qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> return 0;
> }
>
> cluster_offset = qcow2_alloc_bytes(bs, compressed_size);
> if (cluster_offset < 0) {
> - qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> return 0;
> }
>
> @@ -605,9 +614,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
> /* compressed clusters never have the copied flag */
>
> BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
> - qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> + block_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> l2_table[l2_index] = cpu_to_be64(cluster_offset);
> - ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + ret = block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> if (ret < 0) {
> return 0;
> }
> @@ -659,18 +669,16 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
> * handled.
> */
> if (cow) {
> - qcow2_cache_depends_on_flush(s->l2_table_cache);
> + block_cache_depends_on_flush(s->l2_table_cache);
> }
>
> - if (qcow2_need_accurate_refcounts(s)) {
> - qcow2_cache_set_dependency(bs, s->l2_table_cache,
> - s->refcount_block_cache);
> - }
> + block_cache_set_dependency(bs, s->l2_table_cache, BLOCK_TABLE_L2,
> + s->refcount_block_cache, s->cluster_size);
> ret = get_cluster_table(bs, m->offset, &l2_table, &l2_index);
> if (ret < 0) {
> goto err;
> }
> - qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> + block_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
>
> for (i = 0; i < m->nb_clusters; i++) {
> /* if two concurrent writes happen to the same unallocated cluster
> @@ -687,7 +695,8 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
> }
>
>
> - ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + ret = block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> if (ret < 0) {
> goto err;
> }
> @@ -913,7 +922,8 @@ again:
> * request to complete. If we still had the reference, we could use up the
> * whole cache with sleeping requests.
> */
> - ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + ret = block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> if (ret < 0) {
> return ret;
> }
> @@ -1077,14 +1087,15 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
> }
>
> /* First remove L2 entries */
> - qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> + block_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> l2_table[l2_index + i] = cpu_to_be64(0);
>
> /* Then decrease the refcount */
> qcow2_free_any_clusters(bs, old_offset, 1);
> }
>
> - ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + ret = block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> if (ret < 0) {
> return ret;
> }
> @@ -1154,7 +1165,7 @@ static int zero_single_l2(BlockDriverState *bs, uint64_t offset,
> old_offset = be64_to_cpu(l2_table[l2_index + i]);
>
> /* Update L2 entries */
> - qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> + block_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> if (old_offset & QCOW_OFLAG_COMPRESSED) {
> l2_table[l2_index + i] = cpu_to_be64(QCOW_OFLAG_ZERO);
> qcow2_free_any_clusters(bs, old_offset, 1);
> @@ -1163,7 +1174,8 @@ static int zero_single_l2(BlockDriverState *bs, uint64_t offset,
> }
> }
>
> - ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + ret = block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> if (ret < 0) {
> return ret;
> }
> diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
> index 5e3f915..728bfc1 100644
> --- a/block/qcow2-refcount.c
> +++ b/block/qcow2-refcount.c
> @@ -25,6 +25,7 @@
> #include "qemu-common.h"
> #include "block_int.h"
> #include "block/qcow2.h"
> +#include "block-cache.h"
>
> static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size);
> static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
> @@ -71,8 +72,8 @@ static int load_refcount_block(BlockDriverState *bs,
> int ret;
>
> BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_LOAD);
> - ret = qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
> - refcount_block);
> + ret = block_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
> + refcount_block, BLOCK_TABLE_REF, s->cluster_size);
>
> return ret;
> }
> @@ -98,8 +99,8 @@ static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
> if (!refcount_block_offset)
> return 0;
>
> - ret = qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
> - (void**) &refcount_block);
> + ret = block_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
> + (void **) &refcount_block, BLOCK_TABLE_REF, s->cluster_size);
> if (ret < 0) {
> return ret;
> }
> @@ -108,8 +109,8 @@ static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
> ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
> refcount = be16_to_cpu(refcount_block[block_index]);
>
> - ret = qcow2_cache_put(bs, s->refcount_block_cache,
> - (void**) &refcount_block);
> + ret = block_cache_put(bs, s->refcount_block_cache,
> + (void **) &refcount_block, BLOCK_TABLE_REF);
> if (ret < 0) {
> return ret;
> }
> @@ -201,7 +202,8 @@ static int alloc_refcount_block(BlockDriverState *bs,
> *refcount_block = NULL;
>
> /* We write to the refcount table, so we might depend on L2 tables */
> - qcow2_cache_flush(bs, s->l2_table_cache);
> + block_cache_flush(bs, s->l2_table_cache,
> + BLOCK_TABLE_L2, s->cluster_size);
>
> /* Allocate the refcount block itself and mark it as used */
> int64_t new_block = alloc_clusters_noref(bs, s->cluster_size);
> @@ -217,8 +219,8 @@ static int alloc_refcount_block(BlockDriverState *bs,
>
> if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) {
> /* Zero the new refcount block before updating it */
> - ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,
> - (void**) refcount_block);
> + ret = block_cache_get_empty(bs, s->refcount_block_cache, new_block,
> + (void **) refcount_block, BLOCK_TABLE_REF, s->cluster_size);
> if (ret < 0) {
> goto fail_block;
> }
> @@ -241,8 +243,8 @@ static int alloc_refcount_block(BlockDriverState *bs,
>
> /* Initialize the new refcount block only after updating its refcount,
> * update_refcount uses the refcount cache itself */
> - ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,
> - (void**) refcount_block);
> + ret = block_cache_get_empty(bs, s->refcount_block_cache, new_block,
> + (void **) refcount_block, BLOCK_TABLE_REF, s->cluster_size);
> if (ret < 0) {
> goto fail_block;
> }
> @@ -252,8 +254,9 @@ static int alloc_refcount_block(BlockDriverState *bs,
>
> /* Now the new refcount block needs to be written to disk */
> BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE);
> - qcow2_cache_entry_mark_dirty(s->refcount_block_cache, *refcount_block);
> - ret = qcow2_cache_flush(bs, s->refcount_block_cache);
> + block_cache_entry_mark_dirty(s->refcount_block_cache, *refcount_block);
> + ret = block_cache_flush(bs, s->refcount_block_cache,
> + BLOCK_TABLE_REF, s->cluster_size);
> if (ret < 0) {
> goto fail_block;
> }
> @@ -273,7 +276,8 @@ static int alloc_refcount_block(BlockDriverState *bs,
> return 0;
> }
>
> - ret = qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);
> + ret = block_cache_put(bs, s->refcount_block_cache,
> + (void **) refcount_block, BLOCK_TABLE_REF);
> if (ret < 0) {
> goto fail_block;
> }
> @@ -406,7 +410,8 @@ fail_table:
> g_free(new_table);
> fail_block:
> if (*refcount_block != NULL) {
> - qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);
> + block_cache_put(bs, s->refcount_block_cache,
> + (void **) refcount_block, BLOCK_TABLE_REF);
> }
> return ret;
> }
> @@ -432,8 +437,8 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
> }
>
> if (addend < 0) {
> - qcow2_cache_set_dependency(bs, s->refcount_block_cache,
> - s->l2_table_cache);
> + block_cache_set_dependency(bs, s->refcount_block_cache, BLOCK_TABLE_REF,
> + s->l2_table_cache, s->cluster_size);
> }
>
> start = offset & ~(s->cluster_size - 1);
> @@ -449,8 +454,8 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
> /* Load the refcount block and allocate it if needed */
> if (table_index != old_table_index) {
> if (refcount_block) {
> - ret = qcow2_cache_put(bs, s->refcount_block_cache,
> - (void**) &refcount_block);
> + ret = block_cache_put(bs, s->refcount_block_cache,
> + (void **) &refcount_block, BLOCK_TABLE_REF);
> if (ret < 0) {
> goto fail;
> }
> @@ -463,7 +468,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
> }
> old_table_index = table_index;
>
> - qcow2_cache_entry_mark_dirty(s->refcount_block_cache, refcount_block);
> + block_cache_entry_mark_dirty(s->refcount_block_cache, refcount_block);
>
> /* we can update the count and save it */
> block_index = cluster_index &
> @@ -486,8 +491,8 @@ fail:
> /* Write last changed block to disk */
> if (refcount_block) {
> int wret;
> - wret = qcow2_cache_put(bs, s->refcount_block_cache,
> - (void**) &refcount_block);
> + wret = block_cache_put(bs, s->refcount_block_cache,
> + (void **) &refcount_block, BLOCK_TABLE_REF);
> if (wret < 0) {
> return ret < 0 ? ret : wret;
> }
> @@ -763,8 +768,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
> old_l2_offset = l2_offset;
> l2_offset &= L1E_OFFSET_MASK;
>
> - ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset,
> - (void**) &l2_table);
> + ret = block_cache_get(bs, s->l2_table_cache, l2_offset,
> + (void **) &l2_table, BLOCK_TABLE_L2, s->cluster_size);
> if (ret < 0) {
> goto fail;
> }
> @@ -811,16 +816,18 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
> }
> if (offset != old_offset) {
> if (addend > 0) {
> - qcow2_cache_set_dependency(bs, s->l2_table_cache,
> - s->refcount_block_cache);
> + block_cache_set_dependency(bs, s->l2_table_cache,
> + BLOCK_TABLE_L2, s->refcount_block_cache,
> + s->cluster_size);
> }
> l2_table[j] = cpu_to_be64(offset);
> - qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> + block_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
> }
> }
> }
>
> - ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + ret = block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> if (ret < 0) {
> goto fail;
> }
> @@ -847,7 +854,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
> ret = 0;
> fail:
> if (l2_table) {
> - qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
> + block_cache_put(bs, s->l2_table_cache,
> + (void **) &l2_table, BLOCK_TABLE_L2);
> }
>
> /* Update L1 only if it isn't deleted anyway (addend = -1) */
> diff --git a/block/qcow2.c b/block/qcow2.c
> index fd5e214..b89d312 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -30,6 +30,7 @@
> #include "qemu-error.h"
> #include "qerror.h"
> #include "trace.h"
> +#include "block-cache.h"
>
> /*
> Differences with QCOW:
> @@ -415,8 +416,9 @@ static int qcow2_open(BlockDriverState *bs, int flags)
> }
>
> /* alloc L2 table/refcount block cache */
> - s->l2_table_cache = qcow2_cache_create(bs, L2_CACHE_SIZE);
> - s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE);
> + s->l2_table_cache = block_cache_create(bs, L2_CACHE_SIZE, s->cluster_size);
> + s->refcount_block_cache =
> + block_cache_create(bs, REFCOUNT_CACHE_SIZE, s->cluster_size);
>
> s->cluster_cache = g_malloc(s->cluster_size);
> /* one more sector for decompressed data alignment */
> @@ -500,7 +502,7 @@ static int qcow2_open(BlockDriverState *bs, int flags)
> qcow2_refcount_close(bs);
> g_free(s->l1_table);
> if (s->l2_table_cache) {
> - qcow2_cache_destroy(bs, s->l2_table_cache);
> + block_cache_destroy(bs, s->l2_table_cache, BLOCK_TABLE_L2);
> }
> g_free(s->cluster_cache);
> qemu_vfree(s->cluster_data);
> @@ -860,13 +862,13 @@ static void qcow2_close(BlockDriverState *bs)
> BDRVQcowState *s = bs->opaque;
> g_free(s->l1_table);
>
> - qcow2_cache_flush(bs, s->l2_table_cache);
> - qcow2_cache_flush(bs, s->refcount_block_cache);
> -
> + block_cache_flush(bs, s->l2_table_cache,
> + BLOCK_TABLE_L2, s->cluster_size);
> + block_cache_flush(bs, s->refcount_block_cache,
> + BLOCK_TABLE_REF, s->cluster_size);
> qcow2_mark_clean(bs);
> -
> - qcow2_cache_destroy(bs, s->l2_table_cache);
> - qcow2_cache_destroy(bs, s->refcount_block_cache);
> + block_cache_destroy(bs, s->l2_table_cache, BLOCK_TABLE_L2);
> + block_cache_destroy(bs, s->refcount_block_cache, BLOCK_TABLE_REF);
>
> g_free(s->unknown_header_fields);
> cleanup_unknown_header_ext(bs);
> @@ -1339,8 +1341,6 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
> options->value.s);
> return -EINVAL;
> }
> - } else if (!strcmp(options->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
> - flags |= options->value.n ? BLOCK_FLAG_LAZY_REFCOUNTS : 0;
> }
> options++;
> }
> @@ -1537,18 +1537,18 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
> int ret;
>
> qemu_co_mutex_lock(&s->lock);
> - ret = qcow2_cache_flush(bs, s->l2_table_cache);
> + ret = block_cache_flush(bs, s->l2_table_cache,
> + BLOCK_TABLE_L2, s->cluster_size);
> if (ret < 0) {
> qemu_co_mutex_unlock(&s->lock);
> return ret;
> }
>
> - if (qcow2_need_accurate_refcounts(s)) {
> - ret = qcow2_cache_flush(bs, s->refcount_block_cache);
> - if (ret < 0) {
> - qemu_co_mutex_unlock(&s->lock);
> - return ret;
> - }
> + ret = block_cache_flush(bs, s->refcount_block_cache,
> + BLOCK_TABLE_REF, s->cluster_size);
> + if (ret < 0) {
> + qemu_co_mutex_unlock(&s->lock);
> + return ret;
> }
> qemu_co_mutex_unlock(&s->lock);
>
> diff --git a/block/qcow2.h b/block/qcow2.h
> index b4eb654..cb6fd7a 100644
> --- a/block/qcow2.h
> +++ b/block/qcow2.h
> @@ -27,6 +27,7 @@
>
> #include "aes.h"
> #include "qemu-coroutine.h"
> +#include "block-cache.h"
>
> //#define DEBUG_ALLOC
> //#define DEBUG_ALLOC2
> @@ -94,8 +95,6 @@ typedef struct QCowSnapshot {
> uint64_t vm_clock_nsec;
> } QCowSnapshot;
>
> -struct Qcow2Cache;
> -typedef struct Qcow2Cache Qcow2Cache;
>
> typedef struct Qcow2UnknownHeaderExtension {
> uint32_t magic;
> @@ -146,8 +145,8 @@ typedef struct BDRVQcowState {
> uint64_t l1_table_offset;
> uint64_t *l1_table;
>
> - Qcow2Cache* l2_table_cache;
> - Qcow2Cache* refcount_block_cache;
> + BlockCache *l2_table_cache;
> + BlockCache *refcount_block_cache;
>
> uint8_t *cluster_cache;
> uint8_t *cluster_data;
> @@ -316,21 +315,4 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name);
>
> void qcow2_free_snapshots(BlockDriverState *bs);
> int qcow2_read_snapshots(BlockDriverState *bs);
> -
> -/* qcow2-cache.c functions */
> -Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables);
> -int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
> -
> -void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
> -int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
> -int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
> - Qcow2Cache *dependency);
> -void qcow2_cache_depends_on_flush(Qcow2Cache *c);
> -
> -int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
> - void **table);
> -int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
> - void **table);
> -int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table);
> -
> #endif
> diff --git a/trace-events b/trace-events
> index 6b12f83..52b6438 100644
> --- a/trace-events
> +++ b/trace-events
> @@ -439,12 +439,13 @@ qcow2_l2_allocate_write_l2(void *bs, int l1_index) "bs %p l1_index %d"
> qcow2_l2_allocate_write_l1(void *bs, int l1_index) "bs %p l1_index %d"
> qcow2_l2_allocate_done(void *bs, int l1_index, int ret) "bs %p l1_index %d ret %d"
>
> -qcow2_cache_get(void *co, int c, uint64_t offset, bool read_from_disk) "co %p is_l2_cache %d offset %" PRIx64 " read_from_disk %d"
> -qcow2_cache_get_replace_entry(void *co, int c, int i) "co %p is_l2_cache %d index %d"
> -qcow2_cache_get_read(void *co, int c, int i) "co %p is_l2_cache %d index %d"
> -qcow2_cache_get_done(void *co, int c, int i) "co %p is_l2_cache %d index %d"
> -qcow2_cache_flush(void *co, int c) "co %p is_l2_cache %d"
> -qcow2_cache_entry_flush(void *co, int c, int i) "co %p is_l2_cache %d index %d"
> +# block/block-cache.c
> +block_cache_get(void *co, int c, uint64_t offset, bool read_from_disk) "co %p is_l2_cache %d offset %" PRIx64 " read_from_disk %d"
> +block_cache_get_replace_entry(void *co, int c, int i) "co %p is_l2_cache %d index %d"
> +block_cache_get_read(void *co, int c, int i) "co %p is_l2_cache %d index %d"
> +block_cache_get_done(void *co, int c, int i) "co %p is_l2_cache %d index %d"
> +block_cache_flush(void *co, int c) "co %p is_l2_cache %d"
> +block_cache_entry_flush(void *co, int c, int i) "co %p is_l2_cache %d index %d"
>
> # block/qed-l2-cache.c
> qed_alloc_l2_cache_entry(void *l2_cache, void *entry) "l2_cache %p entry %p"
> --
> 1.7.1
>
>
next prev parent reply other threads:[~2012-09-06 17:52 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-10 15:39 [Qemu-devel] [PATCH V12 0/6] add-cow file format Dong Xu Wang
2012-08-10 15:39 ` [Qemu-devel] [PATCH V12 1/6] docs: document for " Dong Xu Wang
2012-09-06 17:27 ` Michael Roth
2012-09-10 1:48 ` Dong Xu Wang
2012-09-10 15:23 ` Kevin Wolf
2012-09-11 2:12 ` Dong Xu Wang
2012-08-10 15:39 ` [Qemu-devel] [PATCH V12 2/6] make path_has_protocol non-static Dong Xu Wang
2012-09-06 17:27 ` Michael Roth
2012-08-10 15:39 ` [Qemu-devel] [PATCH V12 3/6] qed_read_string to bdrv_read_string Dong Xu Wang
2012-09-06 17:32 ` Michael Roth
2012-09-10 1:49 ` Dong Xu Wang
2012-08-10 15:39 ` [Qemu-devel] [PATCH V12 4/6] rename qcow2-cache.c to block-cache.c Dong Xu Wang
2012-09-06 17:52 ` Michael Roth [this message]
2012-09-10 2:14 ` Dong Xu Wang
2012-09-11 8:41 ` Kevin Wolf
2012-08-10 15:39 ` [Qemu-devel] [PATCH V12 5/6] add-cow file format Dong Xu Wang
2012-09-06 20:19 ` Michael Roth
2012-09-10 2:25 ` Dong Xu Wang
2012-09-11 9:44 ` Kevin Wolf
2012-09-11 9:40 ` Kevin Wolf
2012-09-12 7:28 ` Dong Xu Wang
2012-09-12 7:50 ` Kevin Wolf
2012-08-10 15:39 ` [Qemu-devel] [PATCH V12 6/6] add-cow: add qemu-iotests support Dong Xu Wang
2012-09-11 9:55 ` Kevin Wolf
2012-08-23 5:34 ` [Qemu-devel] [PATCH V12 0/6] add-cow file format Dong Xu Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120906175226.GD522@illuin \
--to=mdroth@linux.vnet.ibm.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=wdongxu@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.