static void update_refcount_discard(BlockDriverState *bs,

                                    uint64_t offset, uint64_t length)

{

    BDRVQcowState *s = bs->opaque;

    Qcow2DiscardRegion *d, *p, *next;



    QTAILQ_FOREACH(d, &s->discards, next) {

        uint64_t new_start = MIN(offset, d->offset);

        uint64_t new_end = MAX(offset + length, d->offset + d->bytes);



        if (new_end - new_start <= length + d->bytes) {

            /* There can't be any overlap, areas ending up here have no

             * references any more and therefore shouldn't get freed another

             * time. */

            assert(d->bytes + length == new_end - new_start);

            d->offset = new_start;

            d->bytes = new_end - new_start;

            goto found;

        }

    }



    d = g_malloc(sizeof(*d));

    *d = (Qcow2DiscardRegion) {

        .bs     = bs,

        .offset = offset,

        .bytes  = length,

    };

    QTAILQ_INSERT_TAIL(&s->discards, d, next);



found:

    /* Merge discard requests if they are adjacent now */

    QTAILQ_FOREACH_SAFE(p, &s->discards, next, next) {

        if (p == d

            || p->offset > d->offset + d->bytes

            || d->offset > p->offset + p->bytes)

        {

            continue;

        }



        /* Still no overlap possible */

        assert(p->offset == d->offset + d->bytes

            || d->offset == p->offset + p->bytes);



        QTAILQ_REMOVE(&s->discards, p, next);

        d->offset = MIN(d->offset, p->offset);

        d->bytes += p->bytes;


    }

}
static void update_refcount_discard(BlockDriverState *bs,

                                    uint64_t offset, uint64_t length)

{

    BDRVQcowState *s = bs->opaque;

    Qcow2DiscardRegion *d, *p, *next;



    QTAILQ_FOREACH(d, &s->discards, next) {

        uint64_t new_start = MIN(offset, d->offset);

        uint64_t new_end = MAX(offset + length, d->offset + d->bytes);



        if (new_end - new_start <= length + d->bytes) {

            





            assert(d->bytes + length == new_end - new_start);

            d->offset = new_start;

            d->bytes = new_end - new_start;

            goto found;

        }

    }



    d = g_malloc(sizeof(*d));

    *d = (Qcow2DiscardRegion) {

        .bs     = bs,

        .offset = offset,

        .bytes  = length,

    };

    QTAILQ_INSERT_TAIL(&s->discards, d, next);



found:

    

    QTAILQ_FOREACH_SAFE(p, &s->discards, next, next) {

        if (p == d

            || p->offset > d->offset + d->bytes

            || d->offset > p->offset + p->bytes)

        {

            continue;

        }



        

        assert(p->offset == d->offset + d->bytes

            || d->offset == p->offset + p->bytes);



        QTAILQ_REMOVE(&s->discards, p, next);

        d->offset = MIN(d->offset, p->offset);

        d->bytes += p->bytes;


    }

}
static void FUNC_0(BlockDriverState *VAR_0,

                                    uint64_t VAR_1, uint64_t VAR_2)

{

    BDRVQcowState *s = VAR_0->opaque;

    Qcow2DiscardRegion *d, *p, *next;



    QTAILQ_FOREACH(d, &s->discards, next) {

        uint64_t new_start = MIN(VAR_1, d->VAR_1);

        uint64_t new_end = MAX(VAR_1 + VAR_2, d->VAR_1 + d->bytes);



        if (new_end - new_start <= VAR_2 + d->bytes) {

            





            assert(d->bytes + VAR_2 == new_end - new_start);

            d->VAR_1 = new_start;

            d->bytes = new_end - new_start;

            goto found;

        }

    }



    d = g_malloc(sizeof(*d));

    *d = (Qcow2DiscardRegion) {

        .VAR_0     = VAR_0,

        .VAR_1 = VAR_1,

        .bytes  = VAR_2,

    };

    QTAILQ_INSERT_TAIL(&s->discards, d, next);



found:

    

    QTAILQ_FOREACH_SAFE(p, &s->discards, next, next) {

        if (p == d

            || p->VAR_1 > d->VAR_1 + d->bytes

            || d->VAR_1 > p->VAR_1 + p->bytes)

        {

            continue;

        }



        

        assert(p->VAR_1 == d->VAR_1 + d->bytes

            || d->VAR_1 == p->VAR_1 + p->bytes);



        QTAILQ_REMOVE(&s->discards, p, next);

        d->VAR_1 = MIN(d->VAR_1, p->VAR_1);

        d->bytes += p->bytes;


    }

}
static void FUNC_0(BlockDriverState *VAR_0,
uint64_t VAR_1, uint64_t VAR_2)
{ BDRVQcowState *s = VAR_0->opaque; Qcow2DiscardRegion *d, *p, *next; QTAILQ_FOREACH(d, &s->discards, next) { uint64_t new_start = MIN(VAR_1, d->VAR_1); uint64_t new_end = MAX(VAR_1 + VAR_2, d->VAR_1 + d->bytes); if (new_end - new_start <= VAR_2 + d->bytes) { assert(d->bytes + VAR_2 == new_end - new_start); d->VAR_1 = new_start; d->bytes = new_end - new_start; goto found; } } d = g_malloc(sizeof(*d)); *d = (Qcow2DiscardRegion) { .VAR_0     = VAR_0,
.VAR_1 = VAR_1,
.bytes  = VAR_2,
}; QTAILQ_INSERT_TAIL(&s->discards, d, next); found:
QTAILQ_FOREACH_SAFE(p, &s->discards, next, next) { if (p == d
|| p->VAR_1 > d->VAR_1 + d->bytes
|| d->VAR_1 > p->VAR_1 + p->bytes)
{ continue; } assert(p->VAR_1 == d->VAR_1 + d->bytes
|| d->VAR_1 == p->VAR_1 + p->bytes); QTAILQ_REMOVE(&s->discards, p, next); d->VAR_1 = MIN(d->VAR_1, p->VAR_1); d->bytes += p->bytes; } }