get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/1307033/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1307033,
    "url": "http://patchwork.ozlabs.org/api/patches/1307033/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/e5e12a2aec11aa344aa331b5f418529368d45e12.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": "<e5e12a2aec11aa344aa331b5f418529368d45e12.1591801197.git.berto@igalia.com>",
    "list_archive_url": null,
    "date": "2020-06-10T15:02:59",
    "name": "[v8,21/34] qcow2: Add subcluster support to qcow2_get_host_offset()",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "a3ec7696a9f18f5a33b66dabe161a54630411ee3",
    "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/e5e12a2aec11aa344aa331b5f418529368d45e12.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/1307033/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/1307033/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=dXV4Stkl;\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 49hrT61Vp0z9sQx\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 11 Jun 2020 01:27:22 +1000 (AEST)",
            "from localhost ([::1]:38292 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 1jj2dL-0002ur-PM\n\tfor incoming@patchwork.ozlabs.org; Wed, 10 Jun 2020 11:27:19 -0400",
            "from eggs.gnu.org ([2001:470:142:3::10]:36188)\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 1jj2H4-0002ot-6D; Wed, 10 Jun 2020 11:04:18 -0400",
            "from fanzine.igalia.com ([178.60.130.6]:58237)\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 1jj2Gs-0006wV-LU; Wed, 10 Jun 2020 11:04:15 -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-0007h1-MX; 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-0007NN-9Q; 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=HX/BNY9+fnF3/IdpMYeBixighVMLrzZ1bFMk4+G70IU=;\n b=dXV4Stkl/KnM30XvDXpUp6kg1kb89n4EaV7fpGcVRzqOgupcTDnLLZfMlZ9QOb6w/Evzl+z34qu8Yb1tKAnyNQDShm5dZaKamA8cBaqtCLAh4oKlPPBtuMdaxUKabj7Zkbvviyflq0NG/znvNJ0vC7rqfx8I77WF8/fYaje2old+2ibiOTBrBuq9/qMy9aeqv2RLledLrMgXGVBcs99SLZkQhXM5jGYrBkPVrnscwuIy1qcoR+pvuHaUlesNfAl5MZnKM4Nbxak65s36BhW1RMVzxY3X1vKXFSZm7pmNSYMbcW0ZiM1st7XBj7H6r3owybR+4+WzZk2kiEJ/L6j4Tg==;",
        "From": "Alberto Garcia <berto@igalia.com>",
        "To": "qemu-devel@nongnu.org",
        "Subject": "[PATCH v8 21/34] qcow2: Add subcluster support to\n qcow2_get_host_offset()",
        "Date": "Wed, 10 Jun 2020 17:02:59 +0200",
        "Message-Id": "\n <e5e12a2aec11aa344aa331b5f418529368d45e12.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": "The logic of this function remains pretty much the same, except that\nit uses count_contiguous_subclusters(), which combines the logic of\ncount_contiguous_clusters() / count_contiguous_clusters_unallocated()\nand checks individual subclusters.\n\nqcow2_cluster_to_subcluster_type() is not necessary as a separate\nfunction anymore so it's inlined into its caller.\n\nSigned-off-by: Alberto Garcia <berto@igalia.com>\nReviewed-by: Eric Blake <eblake@redhat.com>\n---\n block/qcow2.h         |  38 ++++-------\n block/qcow2-cluster.c | 150 ++++++++++++++++++++++--------------------\n 2 files changed, 92 insertions(+), 96 deletions(-)",
    "diff": "diff --git a/block/qcow2.h b/block/qcow2.h\nindex 5df761edc3..4fad40b96b 100644\n--- a/block/qcow2.h\n+++ b/block/qcow2.h\n@@ -710,29 +710,6 @@ static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs,\n     }\n }\n \n-/*\n- * For an image without extended L2 entries, return the\n- * QCow2SubclusterType equivalent of a given QCow2ClusterType.\n- */\n-static inline\n-QCow2SubclusterType qcow2_cluster_to_subcluster_type(QCow2ClusterType type)\n-{\n-    switch (type) {\n-    case QCOW2_CLUSTER_COMPRESSED:\n-        return QCOW2_SUBCLUSTER_COMPRESSED;\n-    case QCOW2_CLUSTER_ZERO_PLAIN:\n-        return QCOW2_SUBCLUSTER_ZERO_PLAIN;\n-    case QCOW2_CLUSTER_ZERO_ALLOC:\n-        return QCOW2_SUBCLUSTER_ZERO_ALLOC;\n-    case QCOW2_CLUSTER_NORMAL:\n-        return QCOW2_SUBCLUSTER_NORMAL;\n-    case QCOW2_CLUSTER_UNALLOCATED:\n-        return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;\n-    default:\n-        g_assert_not_reached();\n-    }\n-}\n-\n /*\n  * In an image without subsclusters @l2_bitmap is ignored and\n  * @sc_index must be 0.\n@@ -776,7 +753,20 @@ QCow2SubclusterType qcow2_get_subcluster_type(BlockDriverState *bs,\n             g_assert_not_reached();\n         }\n     } else {\n-        return qcow2_cluster_to_subcluster_type(type);\n+        switch (type) {\n+        case QCOW2_CLUSTER_COMPRESSED:\n+            return QCOW2_SUBCLUSTER_COMPRESSED;\n+        case QCOW2_CLUSTER_ZERO_PLAIN:\n+            return QCOW2_SUBCLUSTER_ZERO_PLAIN;\n+        case QCOW2_CLUSTER_ZERO_ALLOC:\n+            return QCOW2_SUBCLUSTER_ZERO_ALLOC;\n+        case QCOW2_CLUSTER_NORMAL:\n+            return QCOW2_SUBCLUSTER_NORMAL;\n+        case QCOW2_CLUSTER_UNALLOCATED:\n+            return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;\n+        default:\n+            g_assert_not_reached();\n+        }\n     }\n }\n \ndiff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c\nindex 59dd9bda29..2f3bd3a882 100644\n--- a/block/qcow2-cluster.c\n+++ b/block/qcow2-cluster.c\n@@ -426,66 +426,66 @@ static int qcow2_get_subcluster_range_type(BlockDriverState *bs,\n }\n \n /*\n- * Checks how many clusters in a given L2 slice are contiguous in the image\n- * file. As soon as one of the flags in the bitmask stop_flags changes compared\n- * to the first cluster, the search is stopped and the cluster is not counted\n- * as contiguous. (This allows it, for example, to stop at the first compressed\n- * cluster which may require a different handling)\n+ * Return the number of contiguous subclusters of the exact same type\n+ * in a given L2 slice, starting from cluster @l2_index, subcluster\n+ * @sc_index. Allocated subclusters are required to be contiguous in\n+ * the image file.\n+ * At most @nb_clusters are checked (note that this means clusters,\n+ * not subclusters).\n+ * Compressed clusters are always processed one by one but for the\n+ * purpose of this count they are treated as if they were divided into\n+ * subclusters of size s->subcluster_size.\n+ * On failure return -errno and update @l2_index to point to the\n+ * invalid entry.\n  */\n-static int count_contiguous_clusters(BlockDriverState *bs, int nb_clusters,\n-        int cluster_size, uint64_t *l2_slice, int l2_index, uint64_t stop_flags)\n+static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters,\n+                                        unsigned sc_index, uint64_t *l2_slice,\n+                                        unsigned *l2_index)\n {\n     BDRVQcow2State *s = bs->opaque;\n-    int i;\n-    QCow2ClusterType first_cluster_type;\n-    uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW_OFLAG_COMPRESSED;\n-    uint64_t first_entry = get_l2_entry(s, l2_slice, l2_index);\n-    uint64_t offset = first_entry & mask;\n+    int i, count = 0;\n+    bool check_offset;\n+    uint64_t expected_offset;\n+    QCow2SubclusterType expected_type, type;\n \n-    first_cluster_type = qcow2_get_cluster_type(bs, first_entry);\n-    if (first_cluster_type == QCOW2_CLUSTER_UNALLOCATED) {\n-        return 0;\n-    }\n-\n-    /* must be allocated */\n-    assert(first_cluster_type == QCOW2_CLUSTER_NORMAL ||\n-           first_cluster_type == QCOW2_CLUSTER_ZERO_ALLOC);\n+    assert(*l2_index + nb_clusters <= s->l2_size);\n \n     for (i = 0; i < nb_clusters; i++) {\n-        uint64_t l2_entry = get_l2_entry(s, l2_slice, l2_index + i) & mask;\n-        if (offset + (uint64_t) i * cluster_size != l2_entry) {\n+        unsigned first_sc = (i == 0) ? sc_index : 0;\n+        uint64_t l2_entry = get_l2_entry(s, l2_slice, *l2_index + i);\n+        uint64_t l2_bitmap = get_l2_bitmap(s, l2_slice, *l2_index + i);\n+        int ret = qcow2_get_subcluster_range_type(bs, l2_entry, l2_bitmap,\n+                                                  first_sc, &type);\n+        if (ret < 0) {\n+            *l2_index += i; /* Point to the invalid entry */\n+            return -EIO;\n+        }\n+        if (i == 0) {\n+            if (type == QCOW2_SUBCLUSTER_COMPRESSED) {\n+                /* Compressed clusters are always processed one by one */\n+                return ret;\n+            }\n+            expected_type = type;\n+            expected_offset = l2_entry & L2E_OFFSET_MASK;\n+            check_offset = (type == QCOW2_SUBCLUSTER_NORMAL ||\n+                            type == QCOW2_SUBCLUSTER_ZERO_ALLOC ||\n+                            type == QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC);\n+        } else if (type != expected_type) {\n             break;\n+        } else if (check_offset) {\n+            expected_offset += s->cluster_size;\n+            if (expected_offset != (l2_entry & L2E_OFFSET_MASK)) {\n+                break;\n+            }\n         }\n-    }\n-\n-        return i;\n-}\n-\n-/*\n- * Checks how many consecutive unallocated clusters in a given L2\n- * slice have the same cluster type.\n- */\n-static int count_contiguous_clusters_unallocated(BlockDriverState *bs,\n-                                                 int nb_clusters,\n-                                                 uint64_t *l2_slice,\n-                                                 int l2_index,\n-                                                 QCow2ClusterType wanted_type)\n-{\n-    BDRVQcow2State *s = bs->opaque;\n-    int i;\n-\n-    assert(wanted_type == QCOW2_CLUSTER_ZERO_PLAIN ||\n-           wanted_type == QCOW2_CLUSTER_UNALLOCATED);\n-    for (i = 0; i < nb_clusters; i++) {\n-        uint64_t entry = get_l2_entry(s, l2_slice, l2_index + i);\n-        QCow2ClusterType type = qcow2_get_cluster_type(bs, entry);\n-\n-        if (type != wanted_type) {\n+        count += ret;\n+        /* Stop if there are type changes before the end of the cluster */\n+        if (first_sc + ret < s->subclusters_per_cluster) {\n             break;\n         }\n     }\n \n-    return i;\n+    return count;\n }\n \n static int coroutine_fn do_perform_cow_read(BlockDriverState *bs,\n@@ -574,12 +574,12 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,\n                           QCow2SubclusterType *subcluster_type)\n {\n     BDRVQcow2State *s = bs->opaque;\n-    unsigned int l2_index;\n-    uint64_t l1_index, l2_offset, *l2_slice, l2_entry;\n-    int c;\n+    unsigned int l2_index, sc_index;\n+    uint64_t l1_index, l2_offset, *l2_slice, l2_entry, l2_bitmap;\n+    int sc;\n     unsigned int offset_in_cluster;\n     uint64_t bytes_available, bytes_needed, nb_clusters;\n-    QCow2ClusterType type;\n+    QCow2SubclusterType type;\n     int ret;\n \n     offset_in_cluster = offset_into_cluster(s, offset);\n@@ -600,13 +600,13 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,\n \n     l1_index = offset_to_l1_index(s, offset);\n     if (l1_index >= s->l1_size) {\n-        type = QCOW2_CLUSTER_UNALLOCATED;\n+        type = QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;\n         goto out;\n     }\n \n     l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;\n     if (!l2_offset) {\n-        type = QCOW2_CLUSTER_UNALLOCATED;\n+        type = QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;\n         goto out;\n     }\n \n@@ -627,7 +627,9 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,\n     /* find the cluster offset for the given disk offset */\n \n     l2_index = offset_to_l2_slice_index(s, offset);\n+    sc_index = offset_to_sc_index(s, offset);\n     l2_entry = get_l2_entry(s, l2_slice, l2_index);\n+    l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index);\n \n     nb_clusters = size_to_clusters(s, bytes_needed);\n     /* bytes_needed <= *bytes + offset_in_cluster, both of which are unsigned\n@@ -635,9 +637,9 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,\n      * true */\n     assert(nb_clusters <= INT_MAX);\n \n-    type = qcow2_get_cluster_type(bs, l2_entry);\n-    if (s->qcow_version < 3 && (type == QCOW2_CLUSTER_ZERO_PLAIN ||\n-                                type == QCOW2_CLUSTER_ZERO_ALLOC)) {\n+    type = qcow2_get_subcluster_type(bs, l2_entry, l2_bitmap, sc_index);\n+    if (s->qcow_version < 3 && (type == QCOW2_SUBCLUSTER_ZERO_PLAIN ||\n+                                type == QCOW2_SUBCLUSTER_ZERO_ALLOC)) {\n         qcow2_signal_corruption(bs, true, -1, -1, \"Zero cluster entry found\"\n                                 \" in pre-v3 image (L2 offset: %#\" PRIx64\n                                 \", L2 index: %#x)\", l2_offset, l2_index);\n@@ -645,7 +647,9 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,\n         goto fail;\n     }\n     switch (type) {\n-    case QCOW2_CLUSTER_COMPRESSED:\n+    case QCOW2_SUBCLUSTER_INVALID:\n+        break; /* This is handled by count_contiguous_subclusters() below */\n+    case QCOW2_SUBCLUSTER_COMPRESSED:\n         if (has_data_file(bs)) {\n             qcow2_signal_corruption(bs, true, -1, -1, \"Compressed cluster \"\n                                     \"entry found in image with external data \"\n@@ -654,24 +658,17 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,\n             ret = -EIO;\n             goto fail;\n         }\n-        /* Compressed clusters can only be processed one by one */\n-        c = 1;\n         *host_offset = l2_entry & L2E_COMPRESSED_OFFSET_SIZE_MASK;\n         break;\n-    case QCOW2_CLUSTER_ZERO_PLAIN:\n-    case QCOW2_CLUSTER_UNALLOCATED:\n-        /* how many empty clusters ? */\n-        c = count_contiguous_clusters_unallocated(bs, nb_clusters,\n-                                                  l2_slice, l2_index, type);\n+    case QCOW2_SUBCLUSTER_ZERO_PLAIN:\n+    case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN:\n         *host_offset = 0;\n         break;\n-    case QCOW2_CLUSTER_ZERO_ALLOC:\n-    case QCOW2_CLUSTER_NORMAL: {\n+    case QCOW2_SUBCLUSTER_ZERO_ALLOC:\n+    case QCOW2_SUBCLUSTER_NORMAL:\n+    case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC: {\n         uint64_t host_cluster_offset = l2_entry & L2E_OFFSET_MASK;\n         *host_offset = host_cluster_offset + offset_in_cluster;\n-        /* how many allocated clusters ? */\n-        c = count_contiguous_clusters(bs, nb_clusters, s->cluster_size,\n-                                      l2_slice, l2_index, QCOW_OFLAG_ZERO);\n         if (offset_into_cluster(s, host_cluster_offset)) {\n             qcow2_signal_corruption(bs, true, -1, -1,\n                                     \"Cluster allocation offset %#\"\n@@ -697,9 +694,18 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,\n         abort();\n     }\n \n+    sc = count_contiguous_subclusters(bs, nb_clusters, sc_index,\n+                                      l2_slice, &l2_index);\n+    if (sc < 0) {\n+        qcow2_signal_corruption(bs, true, -1, -1, \"Invalid cluster entry found \"\n+                                \" (L2 offset: %#\" PRIx64 \", L2 index: %#x)\",\n+                                l2_offset, l2_index);\n+        ret = -EIO;\n+        goto fail;\n+    }\n     qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);\n \n-    bytes_available = (int64_t)c * s->cluster_size;\n+    bytes_available = ((int64_t)sc + sc_index) << s->subcluster_bits;\n \n out:\n     if (bytes_available > bytes_needed) {\n@@ -712,7 +718,7 @@ out:\n     assert(bytes_available - offset_in_cluster <= UINT_MAX);\n     *bytes = bytes_available - offset_in_cluster;\n \n-    *subcluster_type = qcow2_cluster_to_subcluster_type(type);\n+    *subcluster_type = type;\n \n     return 0;\n \n",
    "prefixes": [
        "v8",
        "21/34"
    ]
}