static int check_refcounts_l2(BlockDriverState *bs,

    uint16_t *refcount_table, int refcount_table_size, int64_t l2_offset,

    int check_copied)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t *l2_table, offset;

    int i, l2_size, nb_csectors, refcount;

    int errors = 0;



    /* Read L2 table from disk */

    l2_size = s->l2_size * sizeof(uint64_t);

    l2_table = qemu_malloc(l2_size);



    if (bdrv_pread(bs->file, l2_offset, l2_table, l2_size) != l2_size)

        goto fail;



    /* Do the actual checks */

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

        offset = be64_to_cpu(l2_table[i]);

        if (offset != 0) {

            if (offset & QCOW_OFLAG_COMPRESSED) {

                /* Compressed clusters don't have QCOW_OFLAG_COPIED */

                if (offset & QCOW_OFLAG_COPIED) {

                    fprintf(stderr, "ERROR: cluster %" PRId64 ": "

                        "copied flag must never be set for compressed "

                        "clusters\n", offset >> s->cluster_bits);

                    offset &= ~QCOW_OFLAG_COPIED;

                    errors++;

                }



                /* Mark cluster as used */

                nb_csectors = ((offset >> s->csize_shift) &

                               s->csize_mask) + 1;

                offset &= s->cluster_offset_mask;

                errors += inc_refcounts(bs, refcount_table,

                              refcount_table_size,

                              offset & ~511, nb_csectors * 512);

            } else {

                /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */

                if (check_copied) {

                    uint64_t entry = offset;

                    offset &= ~QCOW_OFLAG_COPIED;

                    refcount = get_refcount(bs, offset >> s->cluster_bits);

                    if (refcount < 0) {

                        fprintf(stderr, "Can't get refcount for offset %"

                            PRIx64 ": %s\n", entry, strerror(-refcount));

                    }

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

                        fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"

                            PRIx64 " refcount=%d\n", entry, refcount);

                        errors++;

                    }

                }



                /* Mark cluster as used */

                offset &= ~QCOW_OFLAG_COPIED;

                errors += inc_refcounts(bs, refcount_table,

                              refcount_table_size,

                              offset, s->cluster_size);



                /* Correct offsets are cluster aligned */

                if (offset & (s->cluster_size - 1)) {

                    fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "

                        "properly aligned; L2 entry corrupted.\n", offset);

                    errors++;

                }

            }

        }

    }



    qemu_free(l2_table);

    return errors;



fail:

    fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");

    qemu_free(l2_table);

    return -EIO;

}

static int check_refcounts_l2(BlockDriverState *bs,

    uint16_t *refcount_table, int refcount_table_size, int64_t l2_offset,

    int check_copied)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t *l2_table, offset;

    int i, l2_size, nb_csectors, refcount;

    int errors = 0;



    

    l2_size = s->l2_size * sizeof(uint64_t);

    l2_table = qemu_malloc(l2_size);



    if (bdrv_pread(bs->file, l2_offset, l2_table, l2_size) != l2_size)

        goto fail;



    

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

        offset = be64_to_cpu(l2_table[i]);

        if (offset != 0) {

            if (offset & QCOW_OFLAG_COMPRESSED) {

                

                if (offset & QCOW_OFLAG_COPIED) {

                    fprintf(stderr, "ERROR: cluster %" PRId64 ": "

                        "copied flag must never be set for compressed "

                        "clusters\n", offset >> s->cluster_bits);

                    offset &= ~QCOW_OFLAG_COPIED;

                    errors++;

                }



                

                nb_csectors = ((offset >> s->csize_shift) &

                               s->csize_mask) + 1;

                offset &= s->cluster_offset_mask;

                errors += inc_refcounts(bs, refcount_table,

                              refcount_table_size,

                              offset & ~511, nb_csectors * 512);

            } else {

                

                if (check_copied) {

                    uint64_t entry = offset;

                    offset &= ~QCOW_OFLAG_COPIED;

                    refcount = get_refcount(bs, offset >> s->cluster_bits);

                    if (refcount < 0) {

                        fprintf(stderr, "Can't get refcount for offset %"

                            PRIx64 ": %s\n", entry, strerror(-refcount));

                    }

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

                        fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"

                            PRIx64 " refcount=%d\n", entry, refcount);

                        errors++;

                    }

                }



                

                offset &= ~QCOW_OFLAG_COPIED;

                errors += inc_refcounts(bs, refcount_table,

                              refcount_table_size,

                              offset, s->cluster_size);



                

                if (offset & (s->cluster_size - 1)) {

                    fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "

                        "properly aligned; L2 entry corrupted.\n", offset);

                    errors++;

                }

            }

        }

    }



    qemu_free(l2_table);

    return errors;



fail:

    fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");

    qemu_free(l2_table);

    return -EIO;

}

    int errors = 0;     return errors; static int check_refcounts_l2(BlockDriverState *bs,     int errors = 0;                     errors++;                 errors += inc_refcounts(bs, refcount_table,                               refcount_table_size,                               offset & ~511, nb_csectors * 512);                         errors++;                 errors += inc_refcounts(bs, refcount_table,                               refcount_table_size,                               offset, s->cluster_size);                     errors++;     return errors;     fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");     int errors = 0;                     errors++;     return errors;     return errors;
static int FUNC_0(BlockDriverState *VAR_0,

    uint16_t *VAR_1, int VAR_2, int64_t VAR_3,

    int VAR_4)

{

    BDRVQcowState *s = VAR_0->opaque;

    uint64_t *l2_table, offset;

    int VAR_5, VAR_6, VAR_7, VAR_8;

    int VAR_9 = 0;



    

    VAR_6 = s->VAR_6 * sizeof(uint64_t);

    l2_table = qemu_malloc(VAR_6);



    if (bdrv_pread(VAR_0->file, VAR_3, l2_table, VAR_6) != VAR_6)

        goto fail;



    

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

        offset = be64_to_cpu(l2_table[VAR_5]);

        if (offset != 0) {

            if (offset & QCOW_OFLAG_COMPRESSED) {

                

                if (offset & QCOW_OFLAG_COPIED) {

                    fprintf(stderr, "ERROR: cluster %" PRId64 ": "

                        "copied flag must never be set for compressed "

                        "clusters\n", offset >> s->cluster_bits);

                    offset &= ~QCOW_OFLAG_COPIED;

                    VAR_9++;

                }



                

                VAR_7 = ((offset >> s->csize_shift) &

                               s->csize_mask) + 1;

                offset &= s->cluster_offset_mask;

                VAR_9 += inc_refcounts(VAR_0, VAR_1,

                              VAR_2,

                              offset & ~511, VAR_7 * 512);

            } else {

                

                if (VAR_4) {

                    uint64_t entry = offset;

                    offset &= ~QCOW_OFLAG_COPIED;

                    VAR_8 = get_refcount(VAR_0, offset >> s->cluster_bits);

                    if (VAR_8 < 0) {

                        fprintf(stderr, "Can't get VAR_8 for offset %"

                            PRIx64 ": %s\n", entry, strerror(-VAR_8));

                    }

                    if ((VAR_8 == 1) != ((entry & QCOW_OFLAG_COPIED) != 0)) {

                        fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"

                            PRIx64 " VAR_8=%d\n", entry, VAR_8);

                        VAR_9++;

                    }

                }



                

                offset &= ~QCOW_OFLAG_COPIED;

                VAR_9 += inc_refcounts(VAR_0, VAR_1,

                              VAR_2,

                              offset, s->cluster_size);



                

                if (offset & (s->cluster_size - 1)) {

                    fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "

                        "properly aligned; L2 entry corrupted.\n", offset);

                    VAR_9++;

                }

            }

        }

    }



    qemu_free(l2_table);

    return VAR_9;



fail:

    fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");

    qemu_free(l2_table);

    return -EIO;

}

static int FUNC_0(BlockDriverState *VAR_0,
uint16_t *VAR_1, int VAR_2, int64_t VAR_3,
int VAR_4)
{ BDRVQcowState *s = VAR_0->opaque; uint64_t *l2_table, offset; int VAR_5, VAR_6, VAR_7, VAR_8; int VAR_9 = 0; VAR_6 = s->VAR_6 * sizeof(uint64_t); l2_table = qemu_malloc(VAR_6); if (bdrv_pread(VAR_0->file, VAR_3, l2_table, VAR_6) != VAR_6)
goto fail; for(VAR_5 = 0; VAR_5 < s->VAR_6; VAR_5++) { offset = be64_to_cpu(l2_table[VAR_5]); if (offset != 0) { if (offset & QCOW_OFLAG_COMPRESSED) { if (offset & QCOW_OFLAG_COPIED) { fprintf(stderr, "ERROR: cluster %" PRId64 ": "
"copied flag must never be set for compressed "
"clusters\n", offset >> s->cluster_bits); offset &= ~QCOW_OFLAG_COPIED; VAR_9++; } VAR_7 = ((offset >> s->csize_shift) &
s->csize_mask) + 1; offset &= s->cluster_offset_mask; VAR_9 += inc_refcounts(VAR_0, VAR_1,
VAR_2,
offset & ~511, VAR_7 * 512); } else { if (VAR_4) { uint64_t entry = offset; offset &= ~QCOW_OFLAG_COPIED; VAR_8 = get_refcount(VAR_0, offset >> s->cluster_bits); if (VAR_8 < 0) { fprintf(stderr, "Can't get VAR_8 for offset %"
PRIx64 ": %s\n", entry, strerror(-VAR_8)); } if ((VAR_8 == 1) != ((entry & QCOW_OFLAG_COPIED) != 0)) { fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"
PRIx64 " VAR_8=%d\n", entry, VAR_8); VAR_9++; } } offset &= ~QCOW_OFLAG_COPIED; VAR_9 += inc_refcounts(VAR_0, VAR_1,
VAR_2,
offset, s->cluster_size); if (offset & (s->cluster_size - 1)) { fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "
"properly aligned; L2 entry corrupted.\n", offset); VAR_9++; } } } } qemu_free(l2_table); return VAR_9; fail:
fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n"); qemu_free(l2_table); return -EIO; }