static int64_t realloc_refcount_block(BlockDriverState *bs, int reftable_index,

                                      uint64_t offset)

{

    BDRVQcowState *s = bs->opaque;

    int64_t new_offset = 0;

    void *refcount_block = NULL;

    int ret;



    /* allocate new refcount block */

    new_offset = qcow2_alloc_clusters(bs, s->cluster_size);

    if (new_offset < 0) {

        fprintf(stderr, "Could not allocate new cluster: %s\n",

                strerror(-new_offset));

        ret = new_offset;

        goto fail;

    }



    /* fetch current refcount block content */

    ret = qcow2_cache_get(bs, s->refcount_block_cache, offset, &refcount_block);

    if (ret < 0) {

        fprintf(stderr, "Could not fetch refcount block: %s\n", strerror(-ret));

        goto fail;

    }



    /* new block has not yet been entered into refcount table, therefore it is

     * no refcount block yet (regarding this check) */

    ret = qcow2_pre_write_overlap_check(bs, 0, new_offset, s->cluster_size);

    if (ret < 0) {

        fprintf(stderr, "Could not write refcount block; metadata overlap "

                "check failed: %s\n", strerror(-ret));

        /* the image will be marked corrupt, so don't even attempt on freeing

         * the cluster */

        new_offset = 0;

        goto fail;

    }



    /* write to new block */

    ret = bdrv_write(bs->file, new_offset / BDRV_SECTOR_SIZE, refcount_block,

            s->cluster_sectors);

    if (ret < 0) {

        fprintf(stderr, "Could not write refcount block: %s\n", strerror(-ret));

        goto fail;

    }



    /* update refcount table */

    assert(!offset_into_cluster(s, new_offset));

    s->refcount_table[reftable_index] = new_offset;

    ret = write_reftable_entry(bs, reftable_index);

    if (ret < 0) {

        fprintf(stderr, "Could not update refcount table: %s\n",

                strerror(-ret));

        goto fail;

    }



fail:

    if (new_offset && (ret < 0)) {

        qcow2_free_clusters(bs, new_offset, s->cluster_size,

                QCOW2_DISCARD_ALWAYS);

    }

    if (refcount_block) {

        if (ret < 0) {

            qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);

        } else {

            ret = qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);

        }

    }

    if (ret < 0) {

        return ret;

    }

    return new_offset;

}

static int64_t realloc_refcount_block(BlockDriverState *bs, int reftable_index,

                                      uint64_t offset)

{

    BDRVQcowState *s = bs->opaque;

    int64_t new_offset = 0;

    void *refcount_block = NULL;

    int ret;



    

    new_offset = qcow2_alloc_clusters(bs, s->cluster_size);

    if (new_offset < 0) {

        fprintf(stderr, "Could not allocate new cluster: %s\n",

                strerror(-new_offset));

        ret = new_offset;

        goto fail;

    }



    

    ret = qcow2_cache_get(bs, s->refcount_block_cache, offset, &refcount_block);

    if (ret < 0) {

        fprintf(stderr, "Could not fetch refcount block: %s\n", strerror(-ret));

        goto fail;

    }



    



    ret = qcow2_pre_write_overlap_check(bs, 0, new_offset, s->cluster_size);

    if (ret < 0) {

        fprintf(stderr, "Could not write refcount block; metadata overlap "

                "check failed: %s\n", strerror(-ret));

        



        new_offset = 0;

        goto fail;

    }



    

    ret = bdrv_write(bs->file, new_offset / BDRV_SECTOR_SIZE, refcount_block,

            s->cluster_sectors);

    if (ret < 0) {

        fprintf(stderr, "Could not write refcount block: %s\n", strerror(-ret));

        goto fail;

    }



    

    assert(!offset_into_cluster(s, new_offset));

    s->refcount_table[reftable_index] = new_offset;

    ret = write_reftable_entry(bs, reftable_index);

    if (ret < 0) {

        fprintf(stderr, "Could not update refcount table: %s\n",

                strerror(-ret));

        goto fail;

    }



fail:

    if (new_offset && (ret < 0)) {

        qcow2_free_clusters(bs, new_offset, s->cluster_size,

                QCOW2_DISCARD_ALWAYS);

    }

    if (refcount_block) {

        if (ret < 0) {

            qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);

        } else {

            ret = qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);

        }

    }

    if (ret < 0) {

        return ret;

    }

    return new_offset;

}

        goto fail;         goto fail;         new_offset = 0;         goto fail;         goto fail;         goto fail; fail:     if (new_offset && (ret < 0)) {         qcow2_free_clusters(bs, new_offset, s->cluster_size,                 QCOW2_DISCARD_ALWAYS);         if (ret < 0) {             qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);         } else {             ret = qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
static int64_t FUNC_0(BlockDriverState *bs, int reftable_index,

                                      uint64_t offset)

{

    BDRVQcowState *s = bs->opaque;

    int64_t new_offset = 0;

    void *VAR_0 = NULL;

    int VAR_1;



    

    new_offset = qcow2_alloc_clusters(bs, s->cluster_size);

    if (new_offset < 0) {

        fprintf(stderr, "Could not allocate new cluster: %s\n",

                strerror(-new_offset));

        VAR_1 = new_offset;

        goto fail;

    }



    

    VAR_1 = qcow2_cache_get(bs, s->refcount_block_cache, offset, &VAR_0);

    if (VAR_1 < 0) {

        fprintf(stderr, "Could not fetch refcount block: %s\n", strerror(-VAR_1));

        goto fail;

    }



    



    VAR_1 = qcow2_pre_write_overlap_check(bs, 0, new_offset, s->cluster_size);

    if (VAR_1 < 0) {

        fprintf(stderr, "Could not write refcount block; metadata overlap "

                "check failed: %s\n", strerror(-VAR_1));

        



        new_offset = 0;

        goto fail;

    }



    

    VAR_1 = bdrv_write(bs->file, new_offset / BDRV_SECTOR_SIZE, VAR_0,

            s->cluster_sectors);

    if (VAR_1 < 0) {

        fprintf(stderr, "Could not write refcount block: %s\n", strerror(-VAR_1));

        goto fail;

    }



    

    assert(!offset_into_cluster(s, new_offset));

    s->refcount_table[reftable_index] = new_offset;

    VAR_1 = write_reftable_entry(bs, reftable_index);

    if (VAR_1 < 0) {

        fprintf(stderr, "Could not update refcount table: %s\n",

                strerror(-VAR_1));

        goto fail;

    }



fail:

    if (new_offset && (VAR_1 < 0)) {

        qcow2_free_clusters(bs, new_offset, s->cluster_size,

                QCOW2_DISCARD_ALWAYS);

    }

    if (VAR_0) {

        if (VAR_1 < 0) {

            qcow2_cache_put(bs, s->refcount_block_cache, &VAR_0);

        } else {

            VAR_1 = qcow2_cache_put(bs, s->refcount_block_cache, &VAR_0);

        }

    }

    if (VAR_1 < 0) {

        return VAR_1;

    }

    return new_offset;

}

static int64_t FUNC_0(BlockDriverState *bs, int reftable_index,
uint64_t offset)
{ BDRVQcowState *s = bs->opaque; int64_t new_offset = 0; void *VAR_0 = NULL; int VAR_1; new_offset = qcow2_alloc_clusters(bs, s->cluster_size); if (new_offset < 0) { fprintf(stderr, "Could not allocate new cluster: %s\n",
strerror(-new_offset)); VAR_1 = new_offset; goto fail; } VAR_1 = qcow2_cache_get(bs, s->refcount_block_cache, offset, &VAR_0); if (VAR_1 < 0) { fprintf(stderr, "Could not fetch refcount block: %s\n", strerror(-VAR_1)); goto fail; } VAR_1 = qcow2_pre_write_overlap_check(bs, 0, new_offset, s->cluster_size); if (VAR_1 < 0) { fprintf(stderr, "Could not write refcount block; metadata overlap " "check failed: %s\n", strerror(-VAR_1)); new_offset = 0; goto fail; } VAR_1 = bdrv_write(bs->file, new_offset / BDRV_SECTOR_SIZE, VAR_0,
s->cluster_sectors); if (VAR_1 < 0) { fprintf(stderr, "Could not write refcount block: %s\n", strerror(-VAR_1)); goto fail; } assert(!offset_into_cluster(s, new_offset)); s->refcount_table[reftable_index] = new_offset; VAR_1 = write_reftable_entry(bs, reftable_index); if (VAR_1 < 0) { fprintf(stderr, "Could not update refcount table: %s\n",
strerror(-VAR_1)); goto fail; } fail:
if (new_offset && (VAR_1 < 0)) { qcow2_free_clusters(bs, new_offset, s->cluster_size,
QCOW2_DISCARD_ALWAYS); } if (VAR_0) { if (VAR_1 < 0) { qcow2_cache_put(bs, s->refcount_block_cache, &VAR_0); } else { VAR_1 = qcow2_cache_put(bs, s->refcount_block_cache, &VAR_0); } } if (VAR_1 < 0) { return VAR_1; } return new_offset; }