uint64_t qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,

    int *num)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int l1_index, l2_index;

    uint64_t l2_offset, *l2_table, cluster_offset;

    int l1_bits, c;

    unsigned int index_in_cluster, nb_clusters;

    uint64_t nb_available, nb_needed;



    index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);

    nb_needed = *num + index_in_cluster;



    l1_bits = s->l2_bits + s->cluster_bits;



    /* compute how many bytes there are between the offset and

     * the end of the l1 entry

     */



    nb_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1));



    /* compute the number of available sectors */



    nb_available = (nb_available >> 9) + index_in_cluster;



    if (nb_needed > nb_available) {

        nb_needed = nb_available;

    }



    cluster_offset = 0;



    /* seek the the l2 offset in the l1 table */



    l1_index = offset >> l1_bits;

    if (l1_index >= s->l1_size)

        goto out;



    l2_offset = s->l1_table[l1_index];



    /* seek the l2 table of the given l2 offset */



    if (!l2_offset)

        goto out;



    /* load the l2 table in memory */



    l2_offset &= ~QCOW_OFLAG_COPIED;

    l2_table = l2_load(bs, l2_offset);

    if (l2_table == NULL)

        return 0;



    /* find the cluster offset for the given disk offset */



    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);

    cluster_offset = be64_to_cpu(l2_table[l2_index]);

    nb_clusters = size_to_clusters(s, nb_needed << 9);



    if (!cluster_offset) {

        /* how many empty clusters ? */

        c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]);

    } else {

        /* how many allocated clusters ? */

        c = count_contiguous_clusters(nb_clusters, s->cluster_size,

                &l2_table[l2_index], 0, QCOW_OFLAG_COPIED);

    }



   nb_available = (c * s->cluster_sectors);

out:

    if (nb_available > nb_needed)

        nb_available = nb_needed;



    *num = nb_available - index_in_cluster;



    return cluster_offset & ~QCOW_OFLAG_COPIED;

}

uint64_t qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,

    int *num)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int l1_index, l2_index;

    uint64_t l2_offset, *l2_table, cluster_offset;

    int l1_bits, c;

    unsigned int index_in_cluster, nb_clusters;

    uint64_t nb_available, nb_needed;



    index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);

    nb_needed = *num + index_in_cluster;



    l1_bits = s->l2_bits + s->cluster_bits;



    







    nb_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1));



    



    nb_available = (nb_available >> 9) + index_in_cluster;



    if (nb_needed > nb_available) {

        nb_needed = nb_available;

    }



    cluster_offset = 0;



    



    l1_index = offset >> l1_bits;

    if (l1_index >= s->l1_size)

        goto out;



    l2_offset = s->l1_table[l1_index];



    



    if (!l2_offset)

        goto out;



    



    l2_offset &= ~QCOW_OFLAG_COPIED;

    l2_table = l2_load(bs, l2_offset);

    if (l2_table == NULL)

        return 0;



    



    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);

    cluster_offset = be64_to_cpu(l2_table[l2_index]);

    nb_clusters = size_to_clusters(s, nb_needed << 9);



    if (!cluster_offset) {

        

        c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]);

    } else {

        

        c = count_contiguous_clusters(nb_clusters, s->cluster_size,

                &l2_table[l2_index], 0, QCOW_OFLAG_COPIED);

    }



   nb_available = (c * s->cluster_sectors);

out:

    if (nb_available > nb_needed)

        nb_available = nb_needed;



    *num = nb_available - index_in_cluster;



    return cluster_offset & ~QCOW_OFLAG_COPIED;

}

uint64_t FUNC_0(BlockDriverState *bs, uint64_t offset,

    int *num)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int VAR_0, VAR_1;

    uint64_t l2_offset, *l2_table, cluster_offset;

    int VAR_2, VAR_3;

    unsigned int VAR_4, VAR_5;

    uint64_t nb_available, nb_needed;



    VAR_4 = (offset >> 9) & (s->cluster_sectors - 1);

    nb_needed = *num + VAR_4;



    VAR_2 = s->l2_bits + s->cluster_bits;



    







    nb_available = (1ULL << VAR_2) - (offset & ((1ULL << VAR_2) - 1));



    



    nb_available = (nb_available >> 9) + VAR_4;



    if (nb_needed > nb_available) {

        nb_needed = nb_available;

    }



    cluster_offset = 0;



    



    VAR_0 = offset >> VAR_2;

    if (VAR_0 >= s->l1_size)

        goto out;



    l2_offset = s->l1_table[VAR_0];



    



    if (!l2_offset)

        goto out;



    



    l2_offset &= ~QCOW_OFLAG_COPIED;

    l2_table = l2_load(bs, l2_offset);

    if (l2_table == NULL)

        return 0;



    



    VAR_1 = (offset >> s->cluster_bits) & (s->l2_size - 1);

    cluster_offset = be64_to_cpu(l2_table[VAR_1]);

    VAR_5 = size_to_clusters(s, nb_needed << 9);



    if (!cluster_offset) {

        

        VAR_3 = count_contiguous_free_clusters(VAR_5, &l2_table[VAR_1]);

    } else {

        

        VAR_3 = count_contiguous_clusters(VAR_5, s->cluster_size,

                &l2_table[VAR_1], 0, QCOW_OFLAG_COPIED);

    }



   nb_available = (VAR_3 * s->cluster_sectors);

out:

    if (nb_available > nb_needed)

        nb_available = nb_needed;



    *num = nb_available - VAR_4;



    return cluster_offset & ~QCOW_OFLAG_COPIED;

}

uint64_t FUNC_0(BlockDriverState *bs, uint64_t offset,
int *num)
{ BDRVQcowState *s = bs->opaque; unsigned int VAR_0, VAR_1; uint64_t l2_offset, *l2_table, cluster_offset; int VAR_2, VAR_3; unsigned int VAR_4, VAR_5; uint64_t nb_available, nb_needed; VAR_4 = (offset >> 9) & (s->cluster_sectors - 1); nb_needed = *num + VAR_4; VAR_2 = s->l2_bits + s->cluster_bits; nb_available = (1ULL << VAR_2) - (offset & ((1ULL << VAR_2) - 1)); nb_available = (nb_available >> 9) + VAR_4; if (nb_needed > nb_available) { nb_needed = nb_available; } cluster_offset = 0; VAR_0 = offset >> VAR_2; if (VAR_0 >= s->l1_size)
goto out; l2_offset = s->l1_table[VAR_0]; if (!l2_offset)
goto out; l2_offset &= ~QCOW_OFLAG_COPIED; l2_table = l2_load(bs, l2_offset); if (l2_table == NULL)
return 0; VAR_1 = (offset >> s->cluster_bits) & (s->l2_size - 1); cluster_offset = be64_to_cpu(l2_table[VAR_1]); VAR_5 = size_to_clusters(s, nb_needed << 9); if (!cluster_offset) { VAR_3 = count_contiguous_free_clusters(VAR_5, &l2_table[VAR_1]); } else { VAR_3 = count_contiguous_clusters(VAR_5, s->cluster_size,
&l2_table[VAR_1], 0, QCOW_OFLAG_COPIED); } nb_available = (VAR_3 * s->cluster_sectors); out:
if (nb_available > nb_needed)
nb_available = nb_needed; *num = nb_available - VAR_4; return cluster_offset & ~QCOW_OFLAG_COPIED; }