static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,

                              BdrvCheckMode fix)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t *l2_table = qemu_blockalign(bs, s->cluster_size);

    int ret;

    uint64_t refcount;

    int i, j;



    for (i = 0; i < s->l1_size; i++) {

        uint64_t l1_entry = s->l1_table[i];

        uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;

        bool l2_dirty = false;



        if (!l2_offset) {

            continue;

        }



        ret = qcow2_get_refcount(bs, l2_offset >> s->cluster_bits,

                                 &refcount);

        if (ret < 0) {

            /* don't print message nor increment check_errors */

            continue;

        }

        if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {

            fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "

                    "l1_entry=%" PRIx64 " refcount=%" PRIu64 "\n",

                    fix & BDRV_FIX_ERRORS ? "Repairing" :

                                            "ERROR",

                    i, l1_entry, refcount);

            if (fix & BDRV_FIX_ERRORS) {

                s->l1_table[i] = refcount == 1

                               ? l1_entry |  QCOW_OFLAG_COPIED

                               : l1_entry & ~QCOW_OFLAG_COPIED;

                ret = qcow2_write_l1_entry(bs, i);

                if (ret < 0) {

                    res->check_errors++;

                    goto fail;

                }

                res->corruptions_fixed++;

            } else {

                res->corruptions++;

            }

        }



        ret = bdrv_pread(bs->file, l2_offset, l2_table,

                         s->l2_size * sizeof(uint64_t));

        if (ret < 0) {

            fprintf(stderr, "ERROR: Could not read L2 table: %s\n",

                    strerror(-ret));

            res->check_errors++;

            goto fail;

        }



        for (j = 0; j < s->l2_size; j++) {

            uint64_t l2_entry = be64_to_cpu(l2_table[j]);

            uint64_t data_offset = l2_entry & L2E_OFFSET_MASK;

            QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry);



            if ((cluster_type == QCOW2_CLUSTER_NORMAL) ||

                ((cluster_type == QCOW2_CLUSTER_ZERO) && (data_offset != 0))) {

                ret = qcow2_get_refcount(bs,

                                         data_offset >> s->cluster_bits,

                                         &refcount);

                if (ret < 0) {

                    /* don't print message nor increment check_errors */

                    continue;

                }

                if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {

                    fprintf(stderr, "%s OFLAG_COPIED data cluster: "

                            "l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n",

                            fix & BDRV_FIX_ERRORS ? "Repairing" :

                                                    "ERROR",

                            l2_entry, refcount);

                    if (fix & BDRV_FIX_ERRORS) {

                        l2_table[j] = cpu_to_be64(refcount == 1

                                    ? l2_entry |  QCOW_OFLAG_COPIED

                                    : l2_entry & ~QCOW_OFLAG_COPIED);

                        l2_dirty = true;

                        res->corruptions_fixed++;

                    } else {

                        res->corruptions++;

                    }

                }

            }

        }



        if (l2_dirty) {

            ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,

                                                l2_offset, s->cluster_size);

            if (ret < 0) {

                fprintf(stderr, "ERROR: Could not write L2 table; metadata "

                        "overlap check failed: %s\n", strerror(-ret));

                res->check_errors++;

                goto fail;

            }



            ret = bdrv_pwrite(bs->file, l2_offset, l2_table,

                              s->cluster_size);

            if (ret < 0) {

                fprintf(stderr, "ERROR: Could not write L2 table: %s\n",

                        strerror(-ret));

                res->check_errors++;

                goto fail;

            }

        }

    }



    ret = 0;



fail:

    qemu_vfree(l2_table);

    return ret;

}

static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,

                              BdrvCheckMode fix)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t *l2_table = qemu_blockalign(bs, s->cluster_size);

    int ret;

    uint64_t refcount;

    int i, j;



    for (i = 0; i < s->l1_size; i++) {

        uint64_t l1_entry = s->l1_table[i];

        uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;

        bool l2_dirty = false;



        if (!l2_offset) {

            continue;

        }



        ret = qcow2_get_refcount(bs, l2_offset >> s->cluster_bits,

                                 &refcount);

        if (ret < 0) {

            

            continue;

        }

        if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {

            fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "

                    "l1_entry=%" PRIx64 " refcount=%" PRIu64 "\n",

                    fix & BDRV_FIX_ERRORS ? "Repairing" :

                                            "ERROR",

                    i, l1_entry, refcount);

            if (fix & BDRV_FIX_ERRORS) {

                s->l1_table[i] = refcount == 1

                               ? l1_entry |  QCOW_OFLAG_COPIED

                               : l1_entry & ~QCOW_OFLAG_COPIED;

                ret = qcow2_write_l1_entry(bs, i);

                if (ret < 0) {

                    res->check_errors++;

                    goto fail;

                }

                res->corruptions_fixed++;

            } else {

                res->corruptions++;

            }

        }



        ret = bdrv_pread(bs->file, l2_offset, l2_table,

                         s->l2_size * sizeof(uint64_t));

        if (ret < 0) {

            fprintf(stderr, "ERROR: Could not read L2 table: %s\n",

                    strerror(-ret));

            res->check_errors++;

            goto fail;

        }



        for (j = 0; j < s->l2_size; j++) {

            uint64_t l2_entry = be64_to_cpu(l2_table[j]);

            uint64_t data_offset = l2_entry & L2E_OFFSET_MASK;

            QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry);



            if ((cluster_type == QCOW2_CLUSTER_NORMAL) ||

                ((cluster_type == QCOW2_CLUSTER_ZERO) && (data_offset != 0))) {

                ret = qcow2_get_refcount(bs,

                                         data_offset >> s->cluster_bits,

                                         &refcount);

                if (ret < 0) {

                    

                    continue;

                }

                if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {

                    fprintf(stderr, "%s OFLAG_COPIED data cluster: "

                            "l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n",

                            fix & BDRV_FIX_ERRORS ? "Repairing" :

                                                    "ERROR",

                            l2_entry, refcount);

                    if (fix & BDRV_FIX_ERRORS) {

                        l2_table[j] = cpu_to_be64(refcount == 1

                                    ? l2_entry |  QCOW_OFLAG_COPIED

                                    : l2_entry & ~QCOW_OFLAG_COPIED);

                        l2_dirty = true;

                        res->corruptions_fixed++;

                    } else {

                        res->corruptions++;

                    }

                }

            }

        }



        if (l2_dirty) {

            ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,

                                                l2_offset, s->cluster_size);

            if (ret < 0) {

                fprintf(stderr, "ERROR: Could not write L2 table; metadata "

                        "overlap check failed: %s\n", strerror(-ret));

                res->check_errors++;

                goto fail;

            }



            ret = bdrv_pwrite(bs->file, l2_offset, l2_table,

                              s->cluster_size);

            if (ret < 0) {

                fprintf(stderr, "ERROR: Could not write L2 table: %s\n",

                        strerror(-ret));

                res->check_errors++;

                goto fail;

            }

        }

    }



    ret = 0;



fail:

    qemu_vfree(l2_table);

    return ret;

}

static int FUNC_0(BlockDriverState *VAR_0, BdrvCheckResult *VAR_1,

                              BdrvCheckMode VAR_2)

{

    BDRVQcow2State *s = VAR_0->opaque;

    uint64_t *l2_table = qemu_blockalign(VAR_0, s->cluster_size);

    int VAR_3;

    uint64_t refcount;

    int VAR_4, VAR_5;



    for (VAR_4 = 0; VAR_4 < s->l1_size; VAR_4++) {

        uint64_t l1_entry = s->l1_table[VAR_4];

        uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;

        bool l2_dirty = false;



        if (!l2_offset) {

            continue;

        }



        VAR_3 = qcow2_get_refcount(VAR_0, l2_offset >> s->cluster_bits,

                                 &refcount);

        if (VAR_3 < 0) {

            

            continue;

        }

        if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {

            fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "

                    "l1_entry=%" PRIx64 " refcount=%" PRIu64 "\n",

                    VAR_2 & BDRV_FIX_ERRORS ? "Repairing" :

                                            "ERROR",

                    VAR_4, l1_entry, refcount);

            if (VAR_2 & BDRV_FIX_ERRORS) {

                s->l1_table[VAR_4] = refcount == 1

                               ? l1_entry |  QCOW_OFLAG_COPIED

                               : l1_entry & ~QCOW_OFLAG_COPIED;

                VAR_3 = qcow2_write_l1_entry(VAR_0, VAR_4);

                if (VAR_3 < 0) {

                    VAR_1->check_errors++;

                    goto fail;

                }

                VAR_1->corruptions_fixed++;

            } else {

                VAR_1->corruptions++;

            }

        }



        VAR_3 = bdrv_pread(VAR_0->file, l2_offset, l2_table,

                         s->l2_size * sizeof(uint64_t));

        if (VAR_3 < 0) {

            fprintf(stderr, "ERROR: Could not read L2 table: %s\n",

                    strerror(-VAR_3));

            VAR_1->check_errors++;

            goto fail;

        }



        for (VAR_5 = 0; VAR_5 < s->l2_size; VAR_5++) {

            uint64_t l2_entry = be64_to_cpu(l2_table[VAR_5]);

            uint64_t data_offset = l2_entry & L2E_OFFSET_MASK;

            QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry);



            if ((cluster_type == QCOW2_CLUSTER_NORMAL) ||

                ((cluster_type == QCOW2_CLUSTER_ZERO) && (data_offset != 0))) {

                VAR_3 = qcow2_get_refcount(VAR_0,

                                         data_offset >> s->cluster_bits,

                                         &refcount);

                if (VAR_3 < 0) {

                    

                    continue;

                }

                if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {

                    fprintf(stderr, "%s OFLAG_COPIED data cluster: "

                            "l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n",

                            VAR_2 & BDRV_FIX_ERRORS ? "Repairing" :

                                                    "ERROR",

                            l2_entry, refcount);

                    if (VAR_2 & BDRV_FIX_ERRORS) {

                        l2_table[VAR_5] = cpu_to_be64(refcount == 1

                                    ? l2_entry |  QCOW_OFLAG_COPIED

                                    : l2_entry & ~QCOW_OFLAG_COPIED);

                        l2_dirty = true;

                        VAR_1->corruptions_fixed++;

                    } else {

                        VAR_1->corruptions++;

                    }

                }

            }

        }



        if (l2_dirty) {

            VAR_3 = qcow2_pre_write_overlap_check(VAR_0, QCOW2_OL_ACTIVE_L2,

                                                l2_offset, s->cluster_size);

            if (VAR_3 < 0) {

                fprintf(stderr, "ERROR: Could not write L2 table; metadata "

                        "overlap check failed: %s\n", strerror(-VAR_3));

                VAR_1->check_errors++;

                goto fail;

            }



            VAR_3 = bdrv_pwrite(VAR_0->file, l2_offset, l2_table,

                              s->cluster_size);

            if (VAR_3 < 0) {

                fprintf(stderr, "ERROR: Could not write L2 table: %s\n",

                        strerror(-VAR_3));

                VAR_1->check_errors++;

                goto fail;

            }

        }

    }



    VAR_3 = 0;



fail:

    qemu_vfree(l2_table);

    return VAR_3;

}

static int FUNC_0(BlockDriverState *VAR_0, BdrvCheckResult *VAR_1,
BdrvCheckMode VAR_2)
{ BDRVQcow2State *s = VAR_0->opaque; uint64_t *l2_table = qemu_blockalign(VAR_0, s->cluster_size); int VAR_3; uint64_t refcount; int VAR_4, VAR_5; for (VAR_4 = 0; VAR_4 < s->l1_size; VAR_4++) { uint64_t l1_entry = s->l1_table[VAR_4]; uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK; bool l2_dirty = false; if (!l2_offset) { continue; } VAR_3 = qcow2_get_refcount(VAR_0, l2_offset >> s->cluster_bits,
&refcount); if (VAR_3 < 0) { continue; } if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) { fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "
"l1_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
VAR_2 & BDRV_FIX_ERRORS ? "Repairing" :
"ERROR",
VAR_4, l1_entry, refcount); if (VAR_2 & BDRV_FIX_ERRORS) { s->l1_table[VAR_4] = refcount == 1
? l1_entry |  QCOW_OFLAG_COPIED
: l1_entry & ~QCOW_OFLAG_COPIED; VAR_3 = qcow2_write_l1_entry(VAR_0, VAR_4); if (VAR_3 < 0) { VAR_1->check_errors++; goto fail; } VAR_1->corruptions_fixed++; } else { VAR_1->corruptions++; } } VAR_3 = bdrv_pread(VAR_0->file, l2_offset, l2_table,
s->l2_size * sizeof(uint64_t)); if (VAR_3 < 0) { fprintf(stderr, "ERROR: Could not read L2 table: %s\n",
strerror(-VAR_3)); VAR_1->check_errors++; goto fail; } for (VAR_5 = 0; VAR_5 < s->l2_size; VAR_5++) { uint64_t l2_entry = be64_to_cpu(l2_table[VAR_5]); uint64_t data_offset = l2_entry & L2E_OFFSET_MASK; QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry); if ((cluster_type == QCOW2_CLUSTER_NORMAL) ||
((cluster_type == QCOW2_CLUSTER_ZERO) && (data_offset != 0))) { VAR_3 = qcow2_get_refcount(VAR_0,
data_offset >> s->cluster_bits,
&refcount); if (VAR_3 < 0) { continue; } if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) { fprintf(stderr, "%s OFLAG_COPIED data cluster: "
"l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
VAR_2 & BDRV_FIX_ERRORS ? "Repairing" :
"ERROR",
l2_entry, refcount); if (VAR_2 & BDRV_FIX_ERRORS) { l2_table[VAR_5] = cpu_to_be64(refcount == 1
? l2_entry |  QCOW_OFLAG_COPIED
: l2_entry & ~QCOW_OFLAG_COPIED); l2_dirty = true; VAR_1->corruptions_fixed++; } else { VAR_1->corruptions++; } } } } if (l2_dirty) { VAR_3 = qcow2_pre_write_overlap_check(VAR_0, QCOW2_OL_ACTIVE_L2,
l2_offset, s->cluster_size); if (VAR_3 < 0) { fprintf(stderr, "ERROR: Could not write L2 table; metadata " "overlap check failed: %s\n", strerror(-VAR_3)); VAR_1->check_errors++; goto fail; } VAR_3 = bdrv_pwrite(VAR_0->file, l2_offset, l2_table,
s->cluster_size); if (VAR_3 < 0) { fprintf(stderr, "ERROR: Could not write L2 table: %s\n",
strerror(-VAR_3)); VAR_1->check_errors++; goto fail; } } } VAR_3 = 0; fail:
qemu_vfree(l2_table); return VAR_3; }