int qcow2_snapshot_load_tmp(BlockDriverState *bs,

                            const char *snapshot_id,

                            const char *name,

                            Error **errp)

{

    int i, snapshot_index;

    BDRVQcowState *s = bs->opaque;

    QCowSnapshot *sn;

    uint64_t *new_l1_table;

    int new_l1_bytes;

    int ret;



    assert(bs->read_only);



    /* Search the snapshot */

    snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);

    if (snapshot_index < 0) {

        error_setg(errp,

                   "Can't find snapshot");

        return -ENOENT;

    }

    sn = &s->snapshots[snapshot_index];



    /* Allocate and read in the snapshot's L1 table */

    if (sn->l1_size > QCOW_MAX_L1_SIZE) {

        error_setg(errp, "Snapshot L1 table too large");

        return -EFBIG;

    }

    new_l1_bytes = sn->l1_size * sizeof(uint64_t);

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



    ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_table, new_l1_bytes);

    if (ret < 0) {

        error_setg(errp, "Failed to read l1 table for snapshot");

        g_free(new_l1_table);

        return ret;

    }



    /* Switch the L1 table */

    g_free(s->l1_table);



    s->l1_size = sn->l1_size;

    s->l1_table_offset = sn->l1_table_offset;

    s->l1_table = new_l1_table;



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

        be64_to_cpus(&s->l1_table[i]);

    }



    return 0;

}
