From patchwork Sun Aug 25 16:06:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Wang X-Patchwork-Id: 269716 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 81CCF2C00B6 for ; Mon, 26 Aug 2013 02:11:32 +1000 (EST) Received: from localhost ([::1]:46729 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VDcuY-0000WD-Cs for incoming@patchwork.ozlabs.org; Sun, 25 Aug 2013 12:11:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44597) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VDcq8-0002Lp-Mj for qemu-devel@nongnu.org; Sun, 25 Aug 2013 12:07:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VDcq0-0002CB-5I for qemu-devel@nongnu.org; Sun, 25 Aug 2013 12:06:56 -0400 Received: from mail-pd0-x231.google.com ([2607:f8b0:400e:c02::231]:43539) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VDcpz-0002C2-S9 for qemu-devel@nongnu.org; Sun, 25 Aug 2013 12:06:48 -0400 Received: by mail-pd0-f177.google.com with SMTP id y10so2514544pdj.36 for ; Sun, 25 Aug 2013 09:06:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=RwOYLg2bj5UaEJHijdNmhCN4kyxFFRfoLOdl96q7h3g=; b=JFqzfd59s1vQQM619guVNvq7e2vWETWdhX9jSg2nmNaGyu4HMYTunLfRtjjWDGJVmZ SVBAC1U+REKr956Zv3mwNCmU8smd02byFvOvmE8VtDJ6CHf7xChvOCVYi3nZDsRdWL7P KIH3z3TC6VhUGvyLgtwC50k8UTV1c1o3jp7KlBpLkLvtgs42oX3oZN/iUA51o+aFHGsa ivUDwFCwaqWna0w+LU/nHp0YVTlgP0g0yxkTRFi7C1fCvfoqQPR7svsRVyWH7BiZ3ZaU QLu/176py038tPLfR0A2fddDO7f2oThyu86xzSyO5YEQQ46h4CAjLj4jMrbQWYVmfoXz PlJg== X-Received: by 10.68.228.230 with SMTP id sl6mr10575443pbc.98.1377446807251; Sun, 25 Aug 2013 09:06:47 -0700 (PDT) Received: from 11.wdongxu.kvm58 ([202.108.130.153]) by mx.google.com with ESMTPSA id oc10sm12666416pbb.3.1969.12.31.16.00.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Sun, 25 Aug 2013 09:06:46 -0700 (PDT) From: Dong Xu Wang To: qemu-devel@nongnu.org Date: Mon, 26 Aug 2013 00:06:18 +0800 Message-Id: <1377446780-15360-7-git-send-email-wdongxu@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1377446780-15360-1-git-send-email-wdongxu@linux.vnet.ibm.com> References: <1377446780-15360-1-git-send-email-wdongxu@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400e:c02::231 Cc: kwolf@redhat.com, Dong Xu Wang , wdongxu@cn.ibm.com, stefanha@redhat.com Subject: [Qemu-devel] [PATCH V20 6/8] Make block-cache.c be common interface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org To use block-cache.c be common cache interface, we need to add some parameter to identify cache's type. Define a struct named BlockTableType, pass BlockTableType and table size parameters to block cache initialization function. v17-v18: 1) move struct to source file. 2) cluster_size->table_size. Signed-off-by: Dong Xu Wang --- block/block-cache.c | 85 +++++++++++++++++++++++++++++++-------------------- block/block-cache.h | 59 +++++++++++++++++++++++++++++++++++ block/qcow2.c | 7 +++-- block/qcow2.h | 25 ++------------- include/block/block.h | 3 ++ 5 files changed, 122 insertions(+), 57 deletions(-) create mode 100644 block/block-cache.h diff --git a/block/block-cache.c b/block/block-cache.c index bc057a8..a05418f 100644 --- a/block/block-cache.c +++ b/block/block-cache.c @@ -1,4 +1,8 @@ /* + * QEMU Block Layer Cache + * + * This file is based on qcow2-cache.c, see its copyrights below: + * * L2/refcount table cache for the QCOW2 format * * Copyright (c) 2010 Kevin Wolf @@ -24,11 +28,11 @@ #include "block/block_int.h" #include "qemu-common.h" -#include "qcow2.h" #include "trace.h" +#include "block/block-cache.h" typedef struct BlockCachedTable { - void* table; + void *table; int64_t offset; bool dirty; int cache_hits; @@ -36,30 +40,34 @@ typedef struct BlockCachedTable { } BlockCachedTable; struct BlockCache { - BlockCachedTable* entries; - struct BlockCache* depends; - int size; - bool depends_on_flush; + BlockCachedTable *entries; + struct BlockCache *depends; + int size; + size_t table_size; + BlockTableType table_type; + bool depends_on_flush; }; -BlockCache *block_cache_create(BlockDriverState *bs, int num_tables) +BlockCache *block_cache_create(BlockDriverState *bs, int num_tables, + size_t table_size, BlockTableType type) { - BDRVQcowState *s = bs->opaque; BlockCache *c; int i; c = g_malloc0(sizeof(*c)); c->size = num_tables; c->entries = g_malloc0(sizeof(*c->entries) * num_tables); + c->table_type = type; + c->table_size = table_size; for (i = 0; i < c->size; i++) { - c->entries[i].table = qemu_blockalign(bs, s->cluster_size); + c->entries[i].table = qemu_blockalign(bs, table_size); } return c; } -int block_cache_destroy(BlockDriverState* bs, BlockCache *c) +int block_cache_destroy(BlockDriverState *bs, BlockCache *c) { int i; @@ -91,15 +99,13 @@ static int block_cache_flush_dependency(BlockDriverState *bs, BlockCache *c) static int block_cache_entry_flush(BlockDriverState *bs, BlockCache *c, int i) { - BDRVQcowState *s = bs->opaque; int ret = 0; if (!c->entries[i].dirty || !c->entries[i].offset) { return 0; } - trace_block_cache_entry_flush(qemu_coroutine_self(), - c == s->l2_table_cache, i); + trace_block_cache_entry_flush(qemu_coroutine_self(), c->table_type, i); if (c->depends) { ret = block_cache_flush_dependency(bs, c); @@ -114,14 +120,16 @@ static int block_cache_entry_flush(BlockDriverState *bs, BlockCache *c, int i) return ret; } - if (c == s->refcount_block_cache) { + if (c->table_type == BLOCK_TABLE_REF) { BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART); - } else if (c == s->l2_table_cache) { + } else if (c->table_type == BLOCK_TABLE_L2) { BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); + } else if (c->table_type == BLOCK_TABLE_BITMAP) { + BLKDBG_EVENT(bs->file, BLKDBG_ADDCOW_WRITE); } - ret = bdrv_pwrite(bs->file, c->entries[i].offset, c->entries[i].table, - s->cluster_size); + ret = bdrv_pwrite(bs->file, c->entries[i].offset, + c->entries[i].table, c->table_size); if (ret < 0) { return ret; } @@ -133,12 +141,11 @@ static int block_cache_entry_flush(BlockDriverState *bs, BlockCache *c, int i) int block_cache_flush(BlockDriverState *bs, BlockCache *c) { - BDRVQcowState *s = bs->opaque; int result = 0; int ret; int i; - trace_block_cache_flush(qemu_coroutine_self(), c == s->l2_table_cache); + trace_block_cache_flush(qemu_coroutine_self(), c->table_type); for (i = 0; i < c->size; i++) { ret = block_cache_entry_flush(bs, c, i); @@ -157,13 +164,15 @@ int block_cache_flush(BlockDriverState *bs, BlockCache *c) return result; } -int block_cache_set_dependency(BlockDriverState *bs, BlockCache *c, - BlockCache *dependency) +int block_cache_set_dependency_two_bs(BlockDriverState *bs, + BlockCache *c, + BlockDriverState *depend_bs, + BlockCache *dependency) { int ret; if (dependency->depends) { - ret = block_cache_flush_dependency(bs, dependency); + ret = block_cache_flush_dependency(depend_bs, dependency); if (ret < 0) { return ret; } @@ -180,6 +189,13 @@ int block_cache_set_dependency(BlockDriverState *bs, BlockCache *c, return 0; } +int block_cache_set_dependency(BlockDriverState *bs, + BlockCache *c, + BlockCache *dependency) +{ + return block_cache_set_dependency_two_bs(bs, c, bs, dependency); +} + void block_cache_depends_on_flush(BlockCache *c) { c->depends_on_flush = true; @@ -216,13 +232,13 @@ static int block_cache_find_entry_to_replace(BlockCache *c) } static int block_cache_do_get(BlockDriverState *bs, BlockCache *c, - uint64_t offset, void **table, bool read_from_disk) + uint64_t offset, void **table, + bool read_from_disk) { - BDRVQcowState *s = bs->opaque; int i; int ret; - trace_block_cache_get(qemu_coroutine_self(), c == s->l2_table_cache, + trace_block_cache_get(qemu_coroutine_self(), c->table_type, offset, read_from_disk); /* Check if the table is already cached */ @@ -235,7 +251,7 @@ static int block_cache_do_get(BlockDriverState *bs, BlockCache *c, /* If not, write a table back and replace it */ i = block_cache_find_entry_to_replace(c); trace_block_cache_get_replace_entry(qemu_coroutine_self(), - c == s->l2_table_cache, i); + c->table_type, i); if (i < 0) { return i; } @@ -246,14 +262,17 @@ static int block_cache_do_get(BlockDriverState *bs, BlockCache *c, } trace_block_cache_get_read(qemu_coroutine_self(), - c == s->l2_table_cache, i); + c->table_type, i); c->entries[i].offset = 0; if (read_from_disk) { - if (c == s->l2_table_cache) { + if (c->table_type == BLOCK_TABLE_L2) { BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD); + } else if (c->table_type == BLOCK_TABLE_BITMAP) { + BLKDBG_EVENT(bs->file, BLKDBG_ADDCOW_READ); } - ret = bdrv_pread(bs->file, offset, c->entries[i].table, s->cluster_size); + ret = bdrv_pread(bs->file, offset, c->entries[i].table, + c->table_size); if (ret < 0) { return ret; } @@ -271,19 +290,19 @@ found: *table = c->entries[i].table; trace_block_cache_get_done(qemu_coroutine_self(), - c == s->l2_table_cache, i); + c->table_type, i); return 0; } int block_cache_get(BlockDriverState *bs, BlockCache *c, uint64_t offset, - void **table) + void **table) { return block_cache_do_get(bs, c, offset, table, true); } -int block_cache_get_empty(BlockDriverState *bs, BlockCache *c, uint64_t offset, - void **table) +int block_cache_get_empty(BlockDriverState *bs, BlockCache *c, + uint64_t offset, void **table) { return block_cache_do_get(bs, c, offset, table, false); } diff --git a/block/block-cache.h b/block/block-cache.h new file mode 100644 index 0000000..d057d9e --- /dev/null +++ b/block/block-cache.h @@ -0,0 +1,59 @@ +/* + * QEMU Block Layer Cache + * + * This file is based on qcow2-cache.c, see its copyrights below: + * + * L2/refcount table cache for the QCOW2 format + * + * Copyright (c) 2010 Kevin Wolf + * + * 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. + */ + +#ifndef BLOCK_CACHE_H +#define BLOCK_CACHE_H + +typedef enum { + BLOCK_TABLE_REF, + BLOCK_TABLE_L2, + BLOCK_TABLE_BITMAP, +} BlockTableType; + +struct BlockCache; +typedef struct BlockCache BlockCache; + +BlockCache *block_cache_create(BlockDriverState *bs, int num_tables, + size_t table_size, BlockTableType type); +int block_cache_destroy(BlockDriverState *bs, BlockCache *c); +int block_cache_flush(BlockDriverState *bs, BlockCache *c); +int block_cache_set_dependency(BlockDriverState *bs, + BlockCache *c, + BlockCache *dependency); +int block_cache_set_dependency_two_bs(BlockDriverState *bs, + BlockCache *c, + BlockDriverState *depend_bs, + BlockCache *dependency); +void block_cache_depends_on_flush(BlockCache *c); +int block_cache_get(BlockDriverState *bs, BlockCache *c, uint64_t offset, + void **table); +int block_cache_get_empty(BlockDriverState *bs, BlockCache *c, + uint64_t offset, void **table); +int block_cache_put(BlockDriverState *bs, BlockCache *c, void **table); +void block_cache_entry_mark_dirty(BlockCache *c, void *table); +#endif /* BLOCK_CACHE_H */ diff --git a/block/qcow2.c b/block/qcow2.c index a93df45..be4a1c3 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -470,8 +470,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags) } /* alloc L2 table/refcount block cache */ - s->l2_table_cache = block_cache_create(bs, L2_CACHE_SIZE); - s->refcount_block_cache = block_cache_create(bs, REFCOUNT_CACHE_SIZE); + s->l2_table_cache = block_cache_create(bs, L2_CACHE_SIZE, + s->cluster_size, BLOCK_TABLE_L2); + s->refcount_block_cache = block_cache_create(bs, REFCOUNT_CACHE_SIZE, + s->cluster_size, + BLOCK_TABLE_REF); s->cluster_cache = g_malloc(s->cluster_size); /* one more sector for decompressed data alignment */ diff --git a/block/qcow2.h b/block/qcow2.h index 8cc851a..1ed91fc 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -27,6 +27,7 @@ #include "qemu/aes.h" #include "block/coroutine.h" +#include "block/block-cache.h" //#define DEBUG_ALLOC //#define DEBUG_ALLOC2 @@ -100,9 +101,6 @@ typedef struct QCowSnapshot { uint64_t vm_clock_nsec; } QCowSnapshot; -struct BlockCache; -typedef struct BlockCache BlockCache; - typedef struct Qcow2UnknownHeaderExtension { uint32_t magic; uint32_t len; @@ -168,8 +166,8 @@ typedef struct BDRVQcowState { uint64_t l1_table_offset; uint64_t *l1_table; - BlockCache* l2_table_cache; - BlockCache* refcount_block_cache; + BlockCache *l2_table_cache; + BlockCache *refcount_block_cache; uint8_t *cluster_cache; uint8_t *cluster_data; @@ -417,21 +415,4 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name); void qcow2_free_snapshots(BlockDriverState *bs); int qcow2_read_snapshots(BlockDriverState *bs); - -/* block-cache.c functions */ -BlockCache *block_cache_create(BlockDriverState *bs, int num_tables); -int block_cache_destroy(BlockDriverState* bs, BlockCache *c); - -void block_cache_entry_mark_dirty(BlockCache *c, void *table); -int block_cache_flush(BlockDriverState *bs, BlockCache *c); -int block_cache_set_dependency(BlockDriverState *bs, BlockCache *c, - BlockCache *dependency); -void block_cache_depends_on_flush(BlockCache *c); - -int block_cache_get(BlockDriverState *bs, BlockCache *c, uint64_t offset, - void **table); -int block_cache_get_empty(BlockDriverState *bs, BlockCache *c, uint64_t offset, - void **table); -int block_cache_put(BlockDriverState *bs, BlockCache *c, void **table); - #endif diff --git a/include/block/block.h b/include/block/block.h index 30c8e1a..709b5b6 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -413,6 +413,9 @@ typedef enum { BLKDBG_COW_READ, BLKDBG_COW_WRITE, + BLKDBG_ADDCOW_READ, + BLKDBG_ADDCOW_WRITE, + BLKDBG_REFTABLE_LOAD, BLKDBG_REFTABLE_GROW,