static int get_cluster_table(BlockDriverState *bs, uint64_t offset,

                             uint64_t **new_l2_table,

                             int *new_l2_index)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int l1_index, l2_index;

    uint64_t l2_offset;

    uint64_t *l2_table = NULL;

    int ret;



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



    l1_index = offset >> (s->l2_bits + s->cluster_bits);

    if (l1_index >= s->l1_size) {

        ret = qcow2_grow_l1_table(bs, l1_index + 1, false);

        if (ret < 0) {

            return ret;

        }

    }



    l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;



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



    if (s->l1_table[l1_index] & QCOW_OFLAG_COPIED) {

        /* load the l2 table in memory */

        ret = l2_load(bs, l2_offset, &l2_table);

        if (ret < 0) {

            return ret;

        }

    } else {

        /* First allocate a new L2 table (and do COW if needed) */

        ret = l2_allocate(bs, l1_index, &l2_table);

        if (ret < 0) {

            return ret;

        }



        /* Then decrease the refcount of the old table */

        if (l2_offset) {

            qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));

        }

    }



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



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



    *new_l2_table = l2_table;

    *new_l2_index = l2_index;



    return 0;

}

static int get_cluster_table(BlockDriverState *bs, uint64_t offset,

                             uint64_t **new_l2_table,

                             int *new_l2_index)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int l1_index, l2_index;

    uint64_t l2_offset;

    uint64_t *l2_table = NULL;

    int ret;



    



    l1_index = offset >> (s->l2_bits + s->cluster_bits);

    if (l1_index >= s->l1_size) {

        ret = qcow2_grow_l1_table(bs, l1_index + 1, false);

        if (ret < 0) {

            return ret;

        }

    }



    l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;



    



    if (s->l1_table[l1_index] & QCOW_OFLAG_COPIED) {

        

        ret = l2_load(bs, l2_offset, &l2_table);

        if (ret < 0) {

            return ret;

        }

    } else {

        

        ret = l2_allocate(bs, l1_index, &l2_table);

        if (ret < 0) {

            return ret;

        }



        

        if (l2_offset) {

            qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));

        }

    }



    



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



    *new_l2_table = l2_table;

    *new_l2_index = l2_index;



    return 0;

}

    unsigned int l1_index, l2_index;     unsigned int l1_index, l2_index;     uint64_t l2_offset;
static int FUNC_0(BlockDriverState *VAR_0, uint64_t VAR_1,

                             uint64_t **VAR_2,

                             int *VAR_3)

{

    BDRVQcowState *s = VAR_0->opaque;

    unsigned int VAR_4, VAR_5;

    uint64_t l2_offset;

    uint64_t *l2_table = NULL;

    int VAR_6;



    



    VAR_4 = VAR_1 >> (s->l2_bits + s->cluster_bits);

    if (VAR_4 >= s->l1_size) {

        VAR_6 = qcow2_grow_l1_table(VAR_0, VAR_4 + 1, false);

        if (VAR_6 < 0) {

            return VAR_6;

        }

    }



    l2_offset = s->l1_table[VAR_4] & L1E_OFFSET_MASK;



    



    if (s->l1_table[VAR_4] & QCOW_OFLAG_COPIED) {

        

        VAR_6 = l2_load(VAR_0, l2_offset, &l2_table);

        if (VAR_6 < 0) {

            return VAR_6;

        }

    } else {

        

        VAR_6 = l2_allocate(VAR_0, VAR_4, &l2_table);

        if (VAR_6 < 0) {

            return VAR_6;

        }



        

        if (l2_offset) {

            qcow2_free_clusters(VAR_0, l2_offset, s->l2_size * sizeof(uint64_t));

        }

    }



    



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



    *VAR_2 = l2_table;

    *VAR_3 = VAR_5;



    return 0;

}

static int FUNC_0(BlockDriverState *VAR_0, uint64_t VAR_1,
uint64_t **VAR_2,
int *VAR_3)
{ BDRVQcowState *s = VAR_0->opaque; unsigned int VAR_4, VAR_5; uint64_t l2_offset; uint64_t *l2_table = NULL; int VAR_6; VAR_4 = VAR_1 >> (s->l2_bits + s->cluster_bits); if (VAR_4 >= s->l1_size) { VAR_6 = qcow2_grow_l1_table(VAR_0, VAR_4 + 1, false); if (VAR_6 < 0) { return VAR_6; } } l2_offset = s->l1_table[VAR_4] & L1E_OFFSET_MASK; if (s->l1_table[VAR_4] & QCOW_OFLAG_COPIED) { VAR_6 = l2_load(VAR_0, l2_offset, &l2_table); if (VAR_6 < 0) { return VAR_6; } } else { VAR_6 = l2_allocate(VAR_0, VAR_4, &l2_table); if (VAR_6 < 0) { return VAR_6; } if (l2_offset) { qcow2_free_clusters(VAR_0, l2_offset, s->l2_size * sizeof(uint64_t)); } } VAR_5 = (VAR_1 >> s->cluster_bits) & (s->l2_size - 1); *VAR_2 = l2_table; *VAR_3 = VAR_5; return 0; }