int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,

    int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t start, remaining;

    uint64_t cluster_offset;

    uint64_t cur_bytes;

    int ret;



    trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset,

                                      n_start, n_end);



    assert(n_start * BDRV_SECTOR_SIZE == offset_into_cluster(s, offset));

    offset = start_of_cluster(s, offset);



again:

    start = offset + (n_start << BDRV_SECTOR_BITS);

    remaining = (n_end - n_start) << BDRV_SECTOR_BITS;

    cluster_offset = 0;

    *host_offset = 0;



    while (true) {

        /*

         * Now start gathering as many contiguous clusters as possible:

         *

         * 1. Check for overlaps with in-flight allocations

         *

         *      a) Overlap not in the first cluster -> shorten this request and

         *         let the caller handle the rest in its next loop iteration.

         *

         *      b) Real overlaps of two requests. Yield and restart the search

         *         for contiguous clusters (the situation could have changed

         *         while we were sleeping)

         *

         *      c) TODO: Request starts in the same cluster as the in-flight

         *         allocation ends. Shorten the COW of the in-fight allocation,

         *         set cluster_offset to write to the same cluster and set up

         *         the right synchronisation between the in-flight request and

         *         the new one.

         */

        cur_bytes = remaining;

        ret = handle_dependencies(bs, start, &cur_bytes);

        if (ret == -EAGAIN) {

            goto again;

        } else if (ret < 0) {

            return ret;

        } else {

            /* handle_dependencies() may have decreased cur_bytes (shortened

             * the allocations below) so that the next dependency is processed

             * correctly during the next loop iteration. */

        }



        /*

         * 2. Count contiguous COPIED clusters.

         */

        ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m);

        if (ret < 0) {

            return ret;

        } else if (ret) {

            if (!*host_offset) {

                *host_offset = start_of_cluster(s, cluster_offset);

            }



            start           += cur_bytes;

            remaining       -= cur_bytes;

            cluster_offset  += cur_bytes;



            cur_bytes = remaining;

        } else if (cur_bytes == 0) {

            break;

        }



        /* If there is something left to allocate, do that now */

        if (remaining == 0) {

            break;

        }



        /*

         * 3. If the request still hasn't completed, allocate new clusters,

         *    considering any cluster_offset of steps 1c or 2.

         */

        ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m);

        if (ret < 0) {

            return ret;

        } else if (ret) {

            if (!*host_offset) {

                *host_offset = start_of_cluster(s, cluster_offset);

            }



            start           += cur_bytes;

            remaining       -= cur_bytes;

            cluster_offset  += cur_bytes;



            break;

        } else {

            assert(cur_bytes == 0);

            break;

        }

    }



    *num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS);

    assert(*num > 0);

    assert(*host_offset != 0);



    return 0;

}

int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,

    int n_start, int n_end, int *num, uint64_t *host_offset, QCowL2Meta **m)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t start, remaining;

    uint64_t cluster_offset;

    uint64_t cur_bytes;

    int ret;



    trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset,

                                      n_start, n_end);



    assert(n_start * BDRV_SECTOR_SIZE == offset_into_cluster(s, offset));

    offset = start_of_cluster(s, offset);



again:

    start = offset + (n_start << BDRV_SECTOR_BITS);

    remaining = (n_end - n_start) << BDRV_SECTOR_BITS;

    cluster_offset = 0;

    *host_offset = 0;



    while (true) {

        



































        cur_bytes = remaining;

        ret = handle_dependencies(bs, start, &cur_bytes);

        if (ret == -EAGAIN) {

            goto again;

        } else if (ret < 0) {

            return ret;

        } else {

            





        }



        





        ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m);

        if (ret < 0) {

            return ret;

        } else if (ret) {

            if (!*host_offset) {

                *host_offset = start_of_cluster(s, cluster_offset);

            }



            start           += cur_bytes;

            remaining       -= cur_bytes;

            cluster_offset  += cur_bytes;



            cur_bytes = remaining;

        } else if (cur_bytes == 0) {

            break;

        }



        

        if (remaining == 0) {

            break;

        }



        







        ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m);

        if (ret < 0) {

            return ret;

        } else if (ret) {

            if (!*host_offset) {

                *host_offset = start_of_cluster(s, cluster_offset);

            }



            start           += cur_bytes;

            remaining       -= cur_bytes;

            cluster_offset  += cur_bytes;



            break;

        } else {

            assert(cur_bytes == 0);

            break;

        }

    }



    *num = (n_end - n_start) - (remaining >> BDRV_SECTOR_BITS);

    assert(*num > 0);

    assert(*host_offset != 0);



    return 0;

}

        cur_bytes = remaining;         ret = handle_dependencies(bs, start, &cur_bytes);             if (!*host_offset) {                 *host_offset = start_of_cluster(s, cluster_offset);             start           += cur_bytes;             remaining       -= cur_bytes;             cluster_offset  += cur_bytes;             cur_bytes = remaining;         if (remaining == 0) {             break;             if (!*host_offset) {                 *host_offset = start_of_cluster(s, cluster_offset);             start           += cur_bytes;             remaining       -= cur_bytes;             cluster_offset  += cur_bytes;             break;
int FUNC_0(BlockDriverState *VAR_0, uint64_t VAR_1,

    int VAR_2, int VAR_3, int *VAR_4, uint64_t *VAR_5, QCowL2Meta **VAR_6)

{

    BDRVQcowState *s = VAR_0->opaque;

    uint64_t start, remaining;

    uint64_t cluster_offset;

    uint64_t cur_bytes;

    int VAR_7;



    trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), VAR_1,

                                      VAR_2, VAR_3);



    assert(VAR_2 * BDRV_SECTOR_SIZE == offset_into_cluster(s, VAR_1));

    VAR_1 = start_of_cluster(s, VAR_1);



again:

    start = VAR_1 + (VAR_2 << BDRV_SECTOR_BITS);

    remaining = (VAR_3 - VAR_2) << BDRV_SECTOR_BITS;

    cluster_offset = 0;

    *VAR_5 = 0;



    while (true) {

        



































        cur_bytes = remaining;

        VAR_7 = handle_dependencies(VAR_0, start, &cur_bytes);

        if (VAR_7 == -EAGAIN) {

            goto again;

        } else if (VAR_7 < 0) {

            return VAR_7;

        } else {

            





        }



        





        VAR_7 = handle_copied(VAR_0, start, &cluster_offset, &cur_bytes, VAR_6);

        if (VAR_7 < 0) {

            return VAR_7;

        } else if (VAR_7) {

            if (!*VAR_5) {

                *VAR_5 = start_of_cluster(s, cluster_offset);

            }



            start           += cur_bytes;

            remaining       -= cur_bytes;

            cluster_offset  += cur_bytes;



            cur_bytes = remaining;

        } else if (cur_bytes == 0) {

            break;

        }



        

        if (remaining == 0) {

            break;

        }



        







        VAR_7 = handle_alloc(VAR_0, start, &cluster_offset, &cur_bytes, VAR_6);

        if (VAR_7 < 0) {

            return VAR_7;

        } else if (VAR_7) {

            if (!*VAR_5) {

                *VAR_5 = start_of_cluster(s, cluster_offset);

            }



            start           += cur_bytes;

            remaining       -= cur_bytes;

            cluster_offset  += cur_bytes;



            break;

        } else {

            assert(cur_bytes == 0);

            break;

        }

    }



    *VAR_4 = (VAR_3 - VAR_2) - (remaining >> BDRV_SECTOR_BITS);

    assert(*VAR_4 > 0);

    assert(*VAR_5 != 0);



    return 0;

}

int FUNC_0(BlockDriverState *VAR_0, uint64_t VAR_1,
int VAR_2, int VAR_3, int *VAR_4, uint64_t *VAR_5, QCowL2Meta **VAR_6)
{ BDRVQcowState *s = VAR_0->opaque; uint64_t start, remaining; uint64_t cluster_offset; uint64_t cur_bytes; int VAR_7; trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), VAR_1,
VAR_2, VAR_3); assert(VAR_2 * BDRV_SECTOR_SIZE == offset_into_cluster(s, VAR_1)); VAR_1 = start_of_cluster(s, VAR_1); again:
start = VAR_1 + (VAR_2 << BDRV_SECTOR_BITS); remaining = (VAR_3 - VAR_2) << BDRV_SECTOR_BITS; cluster_offset = 0; *VAR_5 = 0; while (true) { cur_bytes = remaining; VAR_7 = handle_dependencies(VAR_0, start, &cur_bytes); if (VAR_7 == -EAGAIN) { goto again; } else if (VAR_7 < 0) { return VAR_7; } else { } VAR_7 = handle_copied(VAR_0, start, &cluster_offset, &cur_bytes, VAR_6); if (VAR_7 < 0) { return VAR_7; } else if (VAR_7) { if (!*VAR_5) { *VAR_5 = start_of_cluster(s, cluster_offset); } start           += cur_bytes; remaining       -= cur_bytes; cluster_offset  += cur_bytes; cur_bytes = remaining; } else if (cur_bytes == 0) { break; } if (remaining == 0) { break; } VAR_7 = handle_alloc(VAR_0, start, &cluster_offset, &cur_bytes, VAR_6); if (VAR_7 < 0) { return VAR_7; } else if (VAR_7) { if (!*VAR_5) { *VAR_5 = start_of_cluster(s, cluster_offset); } start           += cur_bytes; remaining       -= cur_bytes; cluster_offset  += cur_bytes; break; } else { assert(cur_bytes == 0); break; } } *VAR_4 = (VAR_3 - VAR_2) - (remaining >> BDRV_SECTOR_BITS); assert(*VAR_4 > 0); assert(*VAR_5 != 0); return 0; }