int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)

{

    BDRVQcowState *s = bs->opaque;

    int new_l1_size, new_l1_size2, ret, i;

    uint64_t *new_l1_table;

    int64_t new_l1_table_offset;

    uint8_t data[12];



    if (min_size <= s->l1_size)

        return 0;



    if (exact_size) {

        new_l1_size = min_size;

    } else {

        /* Bump size up to reduce the number of times we have to grow */

        new_l1_size = s->l1_size;

        if (new_l1_size == 0) {

            new_l1_size = 1;

        }

        while (min_size > new_l1_size) {

            new_l1_size = (new_l1_size * 3 + 1) / 2;

        }

    }



#ifdef DEBUG_ALLOC2

    fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, new_l1_size);

#endif



    new_l1_size2 = sizeof(uint64_t) * new_l1_size;

    new_l1_table = g_malloc0(align_offset(new_l1_size2, 512));

    memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));



    /* write new table (align to cluster) */

    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE);

    new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);

    if (new_l1_table_offset < 0) {

        g_free(new_l1_table);

        return new_l1_table_offset;

    }



    ret = qcow2_cache_flush(bs, s->refcount_block_cache);

    if (ret < 0) {

        goto fail;

    }



    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);

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

        new_l1_table[i] = cpu_to_be64(new_l1_table[i]);

    ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);

    if (ret < 0)

        goto fail;

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

        new_l1_table[i] = be64_to_cpu(new_l1_table[i]);



    /* set new table */

    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);

    cpu_to_be32w((uint32_t*)data, new_l1_size);

    cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset);

    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));

    if (ret < 0) {

        goto fail;

    }

    g_free(s->l1_table);

    qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));

    s->l1_table_offset = new_l1_table_offset;

    s->l1_table = new_l1_table;

    s->l1_size = new_l1_size;

    return 0;

 fail:

    g_free(new_l1_table);

    qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);

    return ret;

}

int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)

{

    BDRVQcowState *s = bs->opaque;

    int new_l1_size, new_l1_size2, ret, i;

    uint64_t *new_l1_table;

    int64_t new_l1_table_offset;

    uint8_t data[12];



    if (min_size <= s->l1_size)

        return 0;



    if (exact_size) {

        new_l1_size = min_size;

    } else {

        

        new_l1_size = s->l1_size;

        if (new_l1_size == 0) {

            new_l1_size = 1;

        }

        while (min_size > new_l1_size) {

            new_l1_size = (new_l1_size * 3 + 1) / 2;

        }

    }



#ifdef DEBUG_ALLOC2

    fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, new_l1_size);

#endif



    new_l1_size2 = sizeof(uint64_t) * new_l1_size;

    new_l1_table = g_malloc0(align_offset(new_l1_size2, 512));

    memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));



    

    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE);

    new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);

    if (new_l1_table_offset < 0) {

        g_free(new_l1_table);

        return new_l1_table_offset;

    }



    ret = qcow2_cache_flush(bs, s->refcount_block_cache);

    if (ret < 0) {

        goto fail;

    }



    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);

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

        new_l1_table[i] = cpu_to_be64(new_l1_table[i]);

    ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);

    if (ret < 0)

        goto fail;

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

        new_l1_table[i] = be64_to_cpu(new_l1_table[i]);



    

    BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);

    cpu_to_be32w((uint32_t*)data, new_l1_size);

    cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset);

    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));

    if (ret < 0) {

        goto fail;

    }

    g_free(s->l1_table);

    qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));

    s->l1_table_offset = new_l1_table_offset;

    s->l1_table = new_l1_table;

    s->l1_size = new_l1_size;

    return 0;

 fail:

    g_free(new_l1_table);

    qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);

    return ret;

}

int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)     int new_l1_size, new_l1_size2, ret, i;     int64_t new_l1_table_offset;     fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
int FUNC_0(BlockDriverState *VAR_0, int VAR_1, bool VAR_2)

{

    BDRVQcowState *s = VAR_0->opaque;

    int VAR_3, VAR_4, VAR_5, VAR_6;

    uint64_t *new_l1_table;

    int64_t new_l1_table_offset;

    uint8_t data[12];



    if (VAR_1 <= s->l1_size)

        return 0;



    if (VAR_2) {

        VAR_3 = VAR_1;

    } else {

        

        VAR_3 = s->l1_size;

        if (VAR_3 == 0) {

            VAR_3 = 1;

        }

        while (VAR_1 > VAR_3) {

            VAR_3 = (VAR_3 * 3 + 1) / 2;

        }

    }



#ifdef DEBUG_ALLOC2

    fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, VAR_3);

#endif



    VAR_4 = sizeof(uint64_t) * VAR_3;

    new_l1_table = g_malloc0(align_offset(VAR_4, 512));

    memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));



    

    BLKDBG_EVENT(VAR_0->file, BLKDBG_L1_GROW_ALLOC_TABLE);

    new_l1_table_offset = qcow2_alloc_clusters(VAR_0, VAR_4);

    if (new_l1_table_offset < 0) {

        g_free(new_l1_table);

        return new_l1_table_offset;

    }



    VAR_5 = qcow2_cache_flush(VAR_0, s->refcount_block_cache);

    if (VAR_5 < 0) {

        goto fail;

    }



    BLKDBG_EVENT(VAR_0->file, BLKDBG_L1_GROW_WRITE_TABLE);

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

        new_l1_table[VAR_6] = cpu_to_be64(new_l1_table[VAR_6]);

    VAR_5 = bdrv_pwrite_sync(VAR_0->file, new_l1_table_offset, new_l1_table, VAR_4);

    if (VAR_5 < 0)

        goto fail;

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

        new_l1_table[VAR_6] = be64_to_cpu(new_l1_table[VAR_6]);



    

    BLKDBG_EVENT(VAR_0->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);

    cpu_to_be32w((uint32_t*)data, VAR_3);

    cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset);

    VAR_5 = bdrv_pwrite_sync(VAR_0->file, offsetof(QCowHeader, l1_size), data,sizeof(data));

    if (VAR_5 < 0) {

        goto fail;

    }

    g_free(s->l1_table);

    qcow2_free_clusters(VAR_0, s->l1_table_offset, s->l1_size * sizeof(uint64_t));

    s->l1_table_offset = new_l1_table_offset;

    s->l1_table = new_l1_table;

    s->l1_size = VAR_3;

    return 0;

 fail:

    g_free(new_l1_table);

    qcow2_free_clusters(VAR_0, new_l1_table_offset, VAR_4);

    return VAR_5;

}

int FUNC_0(BlockDriverState *VAR_0, int VAR_1, bool VAR_2)
{ BDRVQcowState *s = VAR_0->opaque; int VAR_3, VAR_4, VAR_5, VAR_6; uint64_t *new_l1_table; int64_t new_l1_table_offset; uint8_t data[12]; if (VAR_1 <= s->l1_size)
return 0; if (VAR_2) { VAR_3 = VAR_1; } else { VAR_3 = s->l1_size; if (VAR_3 == 0) { VAR_3 = 1; } while (VAR_1 > VAR_3) { VAR_3 = (VAR_3 * 3 + 1) / 2; } } #ifdef DEBUG_ALLOC2
fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, VAR_3); #endif
VAR_4 = sizeof(uint64_t) * VAR_3; new_l1_table = g_malloc0(align_offset(VAR_4, 512)); memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t)); BLKDBG_EVENT(VAR_0->file, BLKDBG_L1_GROW_ALLOC_TABLE); new_l1_table_offset = qcow2_alloc_clusters(VAR_0, VAR_4); if (new_l1_table_offset < 0) { g_free(new_l1_table); return new_l1_table_offset; } VAR_5 = qcow2_cache_flush(VAR_0, s->refcount_block_cache); if (VAR_5 < 0) { goto fail; } BLKDBG_EVENT(VAR_0->file, BLKDBG_L1_GROW_WRITE_TABLE); for(VAR_6 = 0; VAR_6 < s->l1_size; VAR_6++) new_l1_table[VAR_6] = cpu_to_be64(new_l1_table[VAR_6]); VAR_5 = bdrv_pwrite_sync(VAR_0->file, new_l1_table_offset, new_l1_table, VAR_4); if (VAR_5 < 0)
goto fail; for(VAR_6 = 0; VAR_6 < s->l1_size; VAR_6++) new_l1_table[VAR_6] = be64_to_cpu(new_l1_table[VAR_6]); BLKDBG_EVENT(VAR_0->file, BLKDBG_L1_GROW_ACTIVATE_TABLE); cpu_to_be32w((uint32_t*)data, VAR_3); cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset); VAR_5 = bdrv_pwrite_sync(VAR_0->file, offsetof(QCowHeader, l1_size), data,sizeof(data)); if (VAR_5 < 0) { goto fail; } g_free(s->l1_table); qcow2_free_clusters(VAR_0, s->l1_table_offset, s->l1_size * sizeof(uint64_t)); s->l1_table_offset = new_l1_table_offset; s->l1_table = new_l1_table; s->l1_size = VAR_3; return 0; fail:
g_free(new_l1_table); qcow2_free_clusters(VAR_0, new_l1_table_offset, VAR_4); return VAR_5; }