Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1307012/?format=api
{ "id": 1307012, "url": "http://patchwork.ozlabs.org/api/patches/1307012/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/cbd8ffdad19657ca15bee42914d2f3502981b561.1591801197.git.berto@igalia.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<cbd8ffdad19657ca15bee42914d2f3502981b561.1591801197.git.berto@igalia.com>", "list_archive_url": null, "date": "2020-06-10T15:02:50", "name": "[v8,12/34] qcow2: Add l2_entry_size()", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "75ae6c9e3e85fb31c87671ea6924c0c748b1ce22", "submitter": { "id": 65704, "url": "http://patchwork.ozlabs.org/api/people/65704/?format=api", "name": "Alberto Garcia", "email": "berto@igalia.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/cbd8ffdad19657ca15bee42914d2f3502981b561.1591801197.git.berto@igalia.com/mbox/", "series": [ { "id": 182563, "url": "http://patchwork.ozlabs.org/api/series/182563/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=182563", "date": "2020-06-10T15:02:49", "name": "Add subcluster allocation to qcow2", "version": 8, "mbox": "http://patchwork.ozlabs.org/series/182563/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1307012/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1307012/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=<UNKNOWN>)", "ozlabs.org;\n dmarc=none (p=none dis=none) header.from=igalia.com", "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=igalia.com header.i=@igalia.com header.a=rsa-sha256\n header.s=20170329 header.b=NrPvu61k;\n\tdkim-atps=neutral" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 49hr8B1HY3z9sRW\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 11 Jun 2020 01:12:42 +1000 (AEST)", "from localhost ([::1]:46370 helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1jj2P9-0005it-Tn\n\tfor incoming@patchwork.ozlabs.org; Wed, 10 Jun 2020 11:12:39 -0400", "from eggs.gnu.org ([2001:470:142:3::10]:35982)\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <berto@igalia.com>)\n id 1jj2Gf-0002Mq-JV; Wed, 10 Jun 2020 11:03:53 -0400", "from fanzine.igalia.com ([178.60.130.6]:58129)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)\n (Exim 4.90_1) (envelope-from <berto@igalia.com>)\n id 1jj2GX-0006wG-Sw; Wed, 10 Jun 2020 11:03:52 -0400", "from [81.0.38.199] (helo=perseus.local)\n by fanzine.igalia.com with esmtpsa\n (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim)\n id 1jj2GR-0007gs-Ju; Wed, 10 Jun 2020 17:03:39 +0200", "from berto by perseus.local with local (Exim 4.92)\n (envelope-from <berto@igalia.com>)\n id 1jj2GC-0007Mv-0a; Wed, 10 Jun 2020 17:03:24 +0200" ], "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com;\n s=20170329;\n h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From;\n bh=klQ45ryJ+cILygGi7eA01MXJRrciQEMWh7Cb8En30cg=;\n b=NrPvu61klV2RbVLNd7/Sm2cyNItBUiVsvbWjV+3eXSFcfhqhg14eGNbsJ3V0Hdv6b7J5+F0Xd1JPjCnby3rAm6tQGsOAMUpQnCzVTF5heRIXoD2cIuCdKFIRvuKAGHvQKS2EHPKP/doeAFgWi5/sEtJp4ugy2PrZJamg8Ucr2sNJWf/H7CPQ8UtbkyprdddhVGjIWdEjJ6nbSeQmhnCJ9GaJL1mDOjcRH0F3WYOo2fXmZPl/W73H4NHtZew81VB9yQm9XOdsQmdN5y1pG76AazflyHd2eZNJnWhESPgwbUXOXox0gMx+cK6nt/wB7ratw0d1WgBxAjChCajEZbKtbw==;", "From": "Alberto Garcia <berto@igalia.com>", "To": "qemu-devel@nongnu.org", "Subject": "[PATCH v8 12/34] qcow2: Add l2_entry_size()", "Date": "Wed, 10 Jun 2020 17:02:50 +0200", "Message-Id": "\n <cbd8ffdad19657ca15bee42914d2f3502981b561.1591801197.git.berto@igalia.com>", "X-Mailer": "git-send-email 2.20.1", "In-Reply-To": "<cover.1591801197.git.berto@igalia.com>", "References": "<cover.1591801197.git.berto@igalia.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=178.60.130.6; envelope-from=berto@igalia.com;\n helo=fanzine.igalia.com", "X-detected-operating-system": "by eggs.gnu.org: First seen = 2020/06/10 11:03:39", "X-ACL-Warn": "Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy]", "X-Spam_score_int": "-20", "X-Spam_score": "-2.1", "X-Spam_bar": "--", "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=_AUTOLEARN", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.23", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Cc": "Kevin Wolf <kwolf@redhat.com>,\n Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,\n Alberto Garcia <berto@igalia.com>, qemu-block@nongnu.org,\n Derek Su <dereksu@qnap.com>, Max Reitz <mreitz@redhat.com>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "\"Qemu-devel\"\n <qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>" }, "content": "qcow2 images with subclusters have 128-bit L2 entries. The first 64\nbits contain the same information as traditional images and the last\n64 bits form a bitmap with the status of each individual subcluster.\n\nBecause of that we cannot assume that L2 entries are sizeof(uint64_t)\nanymore. This function returns the proper value for the image.\n\nSigned-off-by: Alberto Garcia <berto@igalia.com>\nReviewed-by: Max Reitz <mreitz@redhat.com>\n---\n block/qcow2.h | 9 +++++++++\n block/qcow2-cluster.c | 12 ++++++------\n block/qcow2-refcount.c | 14 ++++++++------\n block/qcow2.c | 8 ++++----\n 4 files changed, 27 insertions(+), 16 deletions(-)", "diff": "diff --git a/block/qcow2.h b/block/qcow2.h\nindex 4fe31adfd3..46b351229a 100644\n--- a/block/qcow2.h\n+++ b/block/qcow2.h\n@@ -80,6 +80,10 @@\n \n #define QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER 32\n \n+/* Size of normal and extended L2 entries */\n+#define L2E_SIZE_NORMAL (sizeof(uint64_t))\n+#define L2E_SIZE_EXTENDED (sizeof(uint64_t) * 2)\n+\n #define MIN_CLUSTER_BITS 9\n #define MAX_CLUSTER_BITS 21\n \n@@ -521,6 +525,11 @@ static inline bool has_subclusters(BDRVQcow2State *s)\n return false;\n }\n \n+static inline size_t l2_entry_size(BDRVQcow2State *s)\n+{\n+ return has_subclusters(s) ? L2E_SIZE_EXTENDED : L2E_SIZE_NORMAL;\n+}\n+\n static inline uint64_t get_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,\n int idx)\n {\ndiff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c\nindex 76fd0f3cdb..8b2fc550b7 100644\n--- a/block/qcow2-cluster.c\n+++ b/block/qcow2-cluster.c\n@@ -208,7 +208,7 @@ static int l2_load(BlockDriverState *bs, uint64_t offset,\n uint64_t l2_offset, uint64_t **l2_slice)\n {\n BDRVQcow2State *s = bs->opaque;\n- int start_of_slice = sizeof(uint64_t) *\n+ int start_of_slice = l2_entry_size(s) *\n (offset_to_l2_index(s, offset) - offset_to_l2_slice_index(s, offset));\n \n return qcow2_cache_get(bs, s->l2_table_cache, l2_offset + start_of_slice,\n@@ -281,7 +281,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index)\n \n /* allocate a new l2 entry */\n \n- l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));\n+ l2_offset = qcow2_alloc_clusters(bs, s->l2_size * l2_entry_size(s));\n if (l2_offset < 0) {\n ret = l2_offset;\n goto fail;\n@@ -305,7 +305,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index)\n \n /* allocate a new entry in the l2 cache */\n \n- slice_size2 = s->l2_slice_size * sizeof(uint64_t);\n+ slice_size2 = s->l2_slice_size * l2_entry_size(s);\n n_slices = s->cluster_size / slice_size2;\n \n trace_qcow2_l2_allocate_get_empty(bs, l1_index);\n@@ -369,7 +369,7 @@ fail:\n }\n s->l1_table[l1_index] = old_l2_offset;\n if (l2_offset > 0) {\n- qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t),\n+ qcow2_free_clusters(bs, l2_offset, s->l2_size * l2_entry_size(s),\n QCOW2_DISCARD_ALWAYS);\n }\n return ret;\n@@ -716,7 +716,7 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,\n \n /* Then decrease the refcount of the old table */\n if (l2_offset) {\n- qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t),\n+ qcow2_free_clusters(bs, l2_offset, s->l2_size * l2_entry_size(s),\n QCOW2_DISCARD_OTHER);\n }\n \n@@ -1913,7 +1913,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,\n int ret;\n int i, j;\n \n- slice_size2 = s->l2_slice_size * sizeof(uint64_t);\n+ slice_size2 = s->l2_slice_size * l2_entry_size(s);\n n_slices = s->cluster_size / slice_size2;\n \n if (!is_active_l1) {\ndiff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c\nindex 04546838e8..770c5dbc83 100644\n--- a/block/qcow2-refcount.c\n+++ b/block/qcow2-refcount.c\n@@ -1254,7 +1254,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,\n l2_slice = NULL;\n l1_table = NULL;\n l1_size2 = l1_size * sizeof(uint64_t);\n- slice_size2 = s->l2_slice_size * sizeof(uint64_t);\n+ slice_size2 = s->l2_slice_size * l2_entry_size(s);\n n_slices = s->cluster_size / slice_size2;\n \n s->cache_discards = true;\n@@ -1605,7 +1605,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,\n int i, l2_size, nb_csectors, ret;\n \n /* Read L2 table from disk */\n- l2_size = s->l2_size * sizeof(uint64_t);\n+ l2_size = s->l2_size * l2_entry_size(s);\n l2_table = g_malloc(l2_size);\n \n ret = bdrv_pread(bs->file, l2_offset, l2_table, l2_size);\n@@ -1680,15 +1680,16 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,\n fix & BDRV_FIX_ERRORS ? \"Repairing\" : \"ERROR\",\n offset);\n if (fix & BDRV_FIX_ERRORS) {\n+ int idx = i * (l2_entry_size(s) / sizeof(uint64_t));\n uint64_t l2e_offset =\n- l2_offset + (uint64_t)i * sizeof(uint64_t);\n+ l2_offset + (uint64_t)i * l2_entry_size(s);\n int ign = active ? QCOW2_OL_ACTIVE_L2 :\n QCOW2_OL_INACTIVE_L2;\n \n l2_entry = QCOW_OFLAG_ZERO;\n set_l2_entry(s, l2_table, i, l2_entry);\n ret = qcow2_pre_write_overlap_check(bs, ign,\n- l2e_offset, sizeof(uint64_t), false);\n+ l2e_offset, l2_entry_size(s), false);\n if (ret < 0) {\n fprintf(stderr, \"ERROR: Overlap check failed\\n\");\n res->check_errors++;\n@@ -1698,7 +1699,8 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,\n }\n \n ret = bdrv_pwrite_sync(bs->file, l2e_offset,\n- &l2_table[i], sizeof(uint64_t));\n+ &l2_table[idx],\n+ l2_entry_size(s));\n if (ret < 0) {\n fprintf(stderr, \"ERROR: Failed to overwrite L2 \"\n \"table entry: %s\\n\", strerror(-ret));\n@@ -1905,7 +1907,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,\n }\n \n ret = bdrv_pread(bs->file, l2_offset, l2_table,\n- s->l2_size * sizeof(uint64_t));\n+ s->l2_size * l2_entry_size(s));\n if (ret < 0) {\n fprintf(stderr, \"ERROR: Could not read L2 table: %s\\n\",\n strerror(-ret));\ndiff --git a/block/qcow2.c b/block/qcow2.c\nindex 5c175a314c..7df55a88a8 100644\n--- a/block/qcow2.c\n+++ b/block/qcow2.c\n@@ -870,7 +870,7 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,\n uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, s->cluster_size);\n /* An L2 table is always one cluster in size so the max cache size\n * should be a multiple of the cluster size. */\n- uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t),\n+ uint64_t max_l2_cache = ROUND_UP(max_l2_entries * l2_entry_size(s),\n s->cluster_size);\n \n combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);\n@@ -1031,7 +1031,7 @@ static int qcow2_update_options_prepare(BlockDriverState *bs,\n }\n }\n \n- r->l2_slice_size = l2_cache_entry_size / sizeof(uint64_t);\n+ r->l2_slice_size = l2_cache_entry_size / l2_entry_size(s);\n r->l2_table_cache = qcow2_cache_create(bs, l2_cache_size,\n l2_cache_entry_size);\n r->refcount_block_cache = qcow2_cache_create(bs, refcount_cache_size,\n@@ -1478,7 +1478,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,\n bs->encrypted = true;\n }\n \n- s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */\n+ s->l2_bits = s->cluster_bits - ctz32(l2_entry_size(s));\n s->l2_size = 1 << s->l2_bits;\n /* 2^(s->refcount_order - 3) is the refcount width in bytes */\n s->refcount_block_bits = s->cluster_bits - (s->refcount_order - 3);\n@@ -4245,7 +4245,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,\n * preallocation. All that matters is that we will not have to allocate\n * new refcount structures for them.) */\n nb_new_l2_tables = DIV_ROUND_UP(nb_new_data_clusters,\n- s->cluster_size / sizeof(uint64_t));\n+ s->cluster_size / l2_entry_size(s));\n /* The cluster range may not be aligned to L2 boundaries, so add one L2\n * table for a potential head/tail */\n nb_new_l2_tables++;\n", "prefixes": [ "v8", "12/34" ] }