int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,

                                 int64_t size)

{

    BDRVQcowState *s = bs->opaque;

    int i, j;



    if (!size) {

        return 0;

    }



    if (chk & QCOW2_OL_MAIN_HEADER) {

        if (offset < s->cluster_size) {

            return QCOW2_OL_MAIN_HEADER;

        }

    }



    /* align range to test to cluster boundaries */

    size = align_offset(offset_into_cluster(s, offset) + size, s->cluster_size);

    offset = start_of_cluster(s, offset);



    if ((chk & QCOW2_OL_ACTIVE_L1) && s->l1_size) {

        if (overlaps_with(s->l1_table_offset, s->l1_size * sizeof(uint64_t))) {

            return QCOW2_OL_ACTIVE_L1;

        }

    }



    if ((chk & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) {

        if (overlaps_with(s->refcount_table_offset,

            s->refcount_table_size * sizeof(uint64_t))) {

            return QCOW2_OL_REFCOUNT_TABLE;

        }

    }



    if ((chk & QCOW2_OL_SNAPSHOT_TABLE) && s->snapshots_size) {

        if (overlaps_with(s->snapshots_offset, s->snapshots_size)) {

            return QCOW2_OL_SNAPSHOT_TABLE;

        }

    }



    if ((chk & QCOW2_OL_INACTIVE_L1) && s->snapshots) {

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

            if (s->snapshots[i].l1_size &&

                overlaps_with(s->snapshots[i].l1_table_offset,

                s->snapshots[i].l1_size * sizeof(uint64_t))) {

                return QCOW2_OL_INACTIVE_L1;

            }

        }

    }



    if ((chk & QCOW2_OL_ACTIVE_L2) && s->l1_table) {

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

            if ((s->l1_table[i] & L1E_OFFSET_MASK) &&

                overlaps_with(s->l1_table[i] & L1E_OFFSET_MASK,

                s->cluster_size)) {

                return QCOW2_OL_ACTIVE_L2;

            }

        }

    }



    if ((chk & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) {

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

            if ((s->refcount_table[i] & REFT_OFFSET_MASK) &&

                overlaps_with(s->refcount_table[i] & REFT_OFFSET_MASK,

                s->cluster_size)) {

                return QCOW2_OL_REFCOUNT_BLOCK;

            }

        }

    }



    if ((chk & QCOW2_OL_INACTIVE_L2) && s->snapshots) {

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

            uint64_t l1_ofs = s->snapshots[i].l1_table_offset;

            uint32_t l1_sz  = s->snapshots[i].l1_size;

            uint64_t l1_sz2 = l1_sz * sizeof(uint64_t);

            uint64_t *l1 = g_malloc(l1_sz2);

            int ret;



            ret = bdrv_pread(bs->file, l1_ofs, l1, l1_sz2);

            if (ret < 0) {

                g_free(l1);

                return ret;

            }



            for (j = 0; j < l1_sz; j++) {

                uint64_t l2_ofs = be64_to_cpu(l1[j]) & L1E_OFFSET_MASK;

                if (l2_ofs && overlaps_with(l2_ofs, s->cluster_size)) {

                    g_free(l1);

                    return QCOW2_OL_INACTIVE_L2;

                }

            }



            g_free(l1);

        }

    }



    return 0;

}

int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,

                                 int64_t size)

{

    BDRVQcowState *s = bs->opaque;

    int i, j;



    if (!size) {

        return 0;

    }



    if (chk & QCOW2_OL_MAIN_HEADER) {

        if (offset < s->cluster_size) {

            return QCOW2_OL_MAIN_HEADER;

        }

    }



    

    size = align_offset(offset_into_cluster(s, offset) + size, s->cluster_size);

    offset = start_of_cluster(s, offset);



    if ((chk & QCOW2_OL_ACTIVE_L1) && s->l1_size) {

        if (overlaps_with(s->l1_table_offset, s->l1_size * sizeof(uint64_t))) {

            return QCOW2_OL_ACTIVE_L1;

        }

    }



    if ((chk & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) {

        if (overlaps_with(s->refcount_table_offset,

            s->refcount_table_size * sizeof(uint64_t))) {

            return QCOW2_OL_REFCOUNT_TABLE;

        }

    }



    if ((chk & QCOW2_OL_SNAPSHOT_TABLE) && s->snapshots_size) {

        if (overlaps_with(s->snapshots_offset, s->snapshots_size)) {

            return QCOW2_OL_SNAPSHOT_TABLE;

        }

    }



    if ((chk & QCOW2_OL_INACTIVE_L1) && s->snapshots) {

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

            if (s->snapshots[i].l1_size &&

                overlaps_with(s->snapshots[i].l1_table_offset,

                s->snapshots[i].l1_size * sizeof(uint64_t))) {

                return QCOW2_OL_INACTIVE_L1;

            }

        }

    }



    if ((chk & QCOW2_OL_ACTIVE_L2) && s->l1_table) {

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

            if ((s->l1_table[i] & L1E_OFFSET_MASK) &&

                overlaps_with(s->l1_table[i] & L1E_OFFSET_MASK,

                s->cluster_size)) {

                return QCOW2_OL_ACTIVE_L2;

            }

        }

    }



    if ((chk & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) {

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

            if ((s->refcount_table[i] & REFT_OFFSET_MASK) &&

                overlaps_with(s->refcount_table[i] & REFT_OFFSET_MASK,

                s->cluster_size)) {

                return QCOW2_OL_REFCOUNT_BLOCK;

            }

        }

    }



    if ((chk & QCOW2_OL_INACTIVE_L2) && s->snapshots) {

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

            uint64_t l1_ofs = s->snapshots[i].l1_table_offset;

            uint32_t l1_sz  = s->snapshots[i].l1_size;

            uint64_t l1_sz2 = l1_sz * sizeof(uint64_t);

            uint64_t *l1 = g_malloc(l1_sz2);

            int ret;



            ret = bdrv_pread(bs->file, l1_ofs, l1, l1_sz2);

            if (ret < 0) {

                g_free(l1);

                return ret;

            }



            for (j = 0; j < l1_sz; j++) {

                uint64_t l2_ofs = be64_to_cpu(l1[j]) & L1E_OFFSET_MASK;

                if (l2_ofs && overlaps_with(l2_ofs, s->cluster_size)) {

                    g_free(l1);

                    return QCOW2_OL_INACTIVE_L2;

                }

            }



            g_free(l1);

        }

    }



    return 0;

}

int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset, int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
int FUNC_0(BlockDriverState *VAR_0, int VAR_1, int64_t VAR_2,

                                 int64_t VAR_3)

{

    BDRVQcowState *s = VAR_0->opaque;

    int VAR_4, VAR_5;



    if (!VAR_3) {

        return 0;

    }



    if (VAR_1 & QCOW2_OL_MAIN_HEADER) {

        if (VAR_2 < s->cluster_size) {

            return QCOW2_OL_MAIN_HEADER;

        }

    }



    

    VAR_3 = align_offset(offset_into_cluster(s, VAR_2) + VAR_3, s->cluster_size);

    VAR_2 = start_of_cluster(s, VAR_2);



    if ((VAR_1 & QCOW2_OL_ACTIVE_L1) && s->l1_size) {

        if (overlaps_with(s->l1_table_offset, s->l1_size * sizeof(uint64_t))) {

            return QCOW2_OL_ACTIVE_L1;

        }

    }



    if ((VAR_1 & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) {

        if (overlaps_with(s->refcount_table_offset,

            s->refcount_table_size * sizeof(uint64_t))) {

            return QCOW2_OL_REFCOUNT_TABLE;

        }

    }



    if ((VAR_1 & QCOW2_OL_SNAPSHOT_TABLE) && s->snapshots_size) {

        if (overlaps_with(s->snapshots_offset, s->snapshots_size)) {

            return QCOW2_OL_SNAPSHOT_TABLE;

        }

    }



    if ((VAR_1 & QCOW2_OL_INACTIVE_L1) && s->snapshots) {

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

            if (s->snapshots[VAR_4].l1_size &&

                overlaps_with(s->snapshots[VAR_4].l1_table_offset,

                s->snapshots[VAR_4].l1_size * sizeof(uint64_t))) {

                return QCOW2_OL_INACTIVE_L1;

            }

        }

    }



    if ((VAR_1 & QCOW2_OL_ACTIVE_L2) && s->l1_table) {

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

            if ((s->l1_table[VAR_4] & L1E_OFFSET_MASK) &&

                overlaps_with(s->l1_table[VAR_4] & L1E_OFFSET_MASK,

                s->cluster_size)) {

                return QCOW2_OL_ACTIVE_L2;

            }

        }

    }



    if ((VAR_1 & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) {

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

            if ((s->refcount_table[VAR_4] & REFT_OFFSET_MASK) &&

                overlaps_with(s->refcount_table[VAR_4] & REFT_OFFSET_MASK,

                s->cluster_size)) {

                return QCOW2_OL_REFCOUNT_BLOCK;

            }

        }

    }



    if ((VAR_1 & QCOW2_OL_INACTIVE_L2) && s->snapshots) {

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

            uint64_t l1_ofs = s->snapshots[VAR_4].l1_table_offset;

            uint32_t l1_sz  = s->snapshots[VAR_4].l1_size;

            uint64_t l1_sz2 = l1_sz * sizeof(uint64_t);

            uint64_t *l1 = g_malloc(l1_sz2);

            int ret;



            ret = bdrv_pread(VAR_0->file, l1_ofs, l1, l1_sz2);

            if (ret < 0) {

                g_free(l1);

                return ret;

            }



            for (VAR_5 = 0; VAR_5 < l1_sz; VAR_5++) {

                uint64_t l2_ofs = be64_to_cpu(l1[VAR_5]) & L1E_OFFSET_MASK;

                if (l2_ofs && overlaps_with(l2_ofs, s->cluster_size)) {

                    g_free(l1);

                    return QCOW2_OL_INACTIVE_L2;

                }

            }



            g_free(l1);

        }

    }



    return 0;

}

int FUNC_0(BlockDriverState *VAR_0, int VAR_1, int64_t VAR_2,
int64_t VAR_3)
{ BDRVQcowState *s = VAR_0->opaque; int VAR_4, VAR_5; if (!VAR_3) { return 0; } if (VAR_1 & QCOW2_OL_MAIN_HEADER) { if (VAR_2 < s->cluster_size) { return QCOW2_OL_MAIN_HEADER; } } VAR_3 = align_offset(offset_into_cluster(s, VAR_2) + VAR_3, s->cluster_size); VAR_2 = start_of_cluster(s, VAR_2); if ((VAR_1 & QCOW2_OL_ACTIVE_L1) && s->l1_size) { if (overlaps_with(s->l1_table_offset, s->l1_size * sizeof(uint64_t))) { return QCOW2_OL_ACTIVE_L1; } } if ((VAR_1 & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) { if (overlaps_with(s->refcount_table_offset,
s->refcount_table_size * sizeof(uint64_t))) { return QCOW2_OL_REFCOUNT_TABLE; } } if ((VAR_1 & QCOW2_OL_SNAPSHOT_TABLE) && s->snapshots_size) { if (overlaps_with(s->snapshots_offset, s->snapshots_size)) { return QCOW2_OL_SNAPSHOT_TABLE; } } if ((VAR_1 & QCOW2_OL_INACTIVE_L1) && s->snapshots) { for (VAR_4 = 0; VAR_4 < s->nb_snapshots; VAR_4++) { if (s->snapshots[VAR_4].l1_size &&
overlaps_with(s->snapshots[VAR_4].l1_table_offset,
s->snapshots[VAR_4].l1_size * sizeof(uint64_t))) { return QCOW2_OL_INACTIVE_L1; } } } if ((VAR_1 & QCOW2_OL_ACTIVE_L2) && s->l1_table) { for (VAR_4 = 0; VAR_4 < s->l1_size; VAR_4++) { if ((s->l1_table[VAR_4] & L1E_OFFSET_MASK) &&
overlaps_with(s->l1_table[VAR_4] & L1E_OFFSET_MASK,
s->cluster_size)) { return QCOW2_OL_ACTIVE_L2; } } } if ((VAR_1 & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) { for (VAR_4 = 0; VAR_4 < s->refcount_table_size; VAR_4++) { if ((s->refcount_table[VAR_4] & REFT_OFFSET_MASK) &&
overlaps_with(s->refcount_table[VAR_4] & REFT_OFFSET_MASK,
s->cluster_size)) { return QCOW2_OL_REFCOUNT_BLOCK; } } } if ((VAR_1 & QCOW2_OL_INACTIVE_L2) && s->snapshots) { for (VAR_4 = 0; VAR_4 < s->nb_snapshots; VAR_4++) { uint64_t l1_ofs = s->snapshots[VAR_4].l1_table_offset; uint32_t l1_sz  = s->snapshots[VAR_4].l1_size; uint64_t l1_sz2 = l1_sz * sizeof(uint64_t); uint64_t *l1 = g_malloc(l1_sz2); int ret; ret = bdrv_pread(VAR_0->file, l1_ofs, l1, l1_sz2); if (ret < 0) { g_free(l1); return ret; } for (VAR_5 = 0; VAR_5 < l1_sz; VAR_5++) { uint64_t l2_ofs = be64_to_cpu(l1[VAR_5]) & L1E_OFFSET_MASK; if (l2_ofs && overlaps_with(l2_ofs, s->cluster_size)) { g_free(l1); return QCOW2_OL_INACTIVE_L2; } } g_free(l1); } } return 0; }