int qcow2_snapshot_delete(BlockDriverState *bs,

                          const char *snapshot_id,

                          const char *name,

                          Error **errp)

{

    BDRVQcowState *s = bs->opaque;

    QCowSnapshot sn;

    int snapshot_index, ret;



    /* 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 the snapshot");

        return -ENOENT;

    }

    sn = s->snapshots[snapshot_index];



    /* Remove it from the snapshot list */

    memmove(s->snapshots + snapshot_index,

            s->snapshots + snapshot_index + 1,

            (s->nb_snapshots - snapshot_index - 1) * sizeof(sn));

    s->nb_snapshots--;

    ret = qcow2_write_snapshots(bs);

    if (ret < 0) {

        error_setg(errp, "Failed to remove snapshot from snapshot list");

        return ret;

    }



    /*

     * The snapshot is now unused, clean up. If we fail after this point, we

     * won't recover but just leak clusters.

     */

    g_free(sn.id_str);

    g_free(sn.name);



    /*

     * Now decrease the refcounts of clusters referenced by the snapshot and

     * free the L1 table.

     */

    ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset,

                                         sn.l1_size, -1);

    if (ret < 0) {

        error_setg(errp, "Failed to free the cluster and L1 table");

        return ret;

    }

    qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t),

                        QCOW2_DISCARD_SNAPSHOT);



    /* must update the copied flag on the current cluster offsets */

    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);

    if (ret < 0) {

        error_setg(errp, "Failed to update snapshot status in disk");

        return ret;

    }



#ifdef DEBUG_ALLOC

    {

        BdrvCheckResult result = {0};

        qcow2_check_refcounts(bs, &result, 0);

    }

#endif

    return 0;

}

int qcow2_snapshot_delete(BlockDriverState *bs,

                          const char *snapshot_id,

                          const char *name,

                          Error **errp)

{

    BDRVQcowState *s = bs->opaque;

    QCowSnapshot sn;

    int snapshot_index, ret;



    

    snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);

    if (snapshot_index < 0) {

        error_setg(errp, "Can't find the snapshot");

        return -ENOENT;

    }

    sn = s->snapshots[snapshot_index];



    

    memmove(s->snapshots + snapshot_index,

            s->snapshots + snapshot_index + 1,

            (s->nb_snapshots - snapshot_index - 1) * sizeof(sn));

    s->nb_snapshots--;

    ret = qcow2_write_snapshots(bs);

    if (ret < 0) {

        error_setg(errp, "Failed to remove snapshot from snapshot list");

        return ret;

    }



    







    g_free(sn.id_str);

    g_free(sn.name);



    







    ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset,

                                         sn.l1_size, -1);

    if (ret < 0) {

        error_setg(errp, "Failed to free the cluster and L1 table");

        return ret;

    }

    qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t),

                        QCOW2_DISCARD_SNAPSHOT);



    

    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);

    if (ret < 0) {

        error_setg(errp, "Failed to update snapshot status in disk");

        return ret;

    }



#ifdef DEBUG_ALLOC

    {

        BdrvCheckResult result = {0};

        qcow2_check_refcounts(bs, &result, 0);

    }

#endif

    return 0;

}

        error_setg(errp, "Failed to remove snapshot from snapshot list");         error_setg(errp, "Failed to free the cluster and L1 table");         error_setg(errp, "Failed to update snapshot status in disk");
int FUNC_0(BlockDriverState *VAR_0,

                          const char *VAR_1,

                          const char *VAR_2,

                          Error **VAR_3)

{

    BDRVQcowState *s = VAR_0->opaque;

    QCowSnapshot sn;

    int VAR_4, VAR_5;



    

    VAR_4 = find_snapshot_by_id_and_name(VAR_0, VAR_1, VAR_2);

    if (VAR_4 < 0) {

        error_setg(VAR_3, "Can't find the snapshot");

        return -ENOENT;

    }

    sn = s->snapshots[VAR_4];



    

    memmove(s->snapshots + VAR_4,

            s->snapshots + VAR_4 + 1,

            (s->nb_snapshots - VAR_4 - 1) * sizeof(sn));

    s->nb_snapshots--;

    VAR_5 = qcow2_write_snapshots(VAR_0);

    if (VAR_5 < 0) {

        error_setg(VAR_3, "Failed to remove snapshot from snapshot list");

        return VAR_5;

    }



    







    g_free(sn.id_str);

    g_free(sn.VAR_2);



    







    VAR_5 = qcow2_update_snapshot_refcount(VAR_0, sn.l1_table_offset,

                                         sn.l1_size, -1);

    if (VAR_5 < 0) {

        error_setg(VAR_3, "Failed to free the cluster and L1 table");

        return VAR_5;

    }

    qcow2_free_clusters(VAR_0, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t),

                        QCOW2_DISCARD_SNAPSHOT);



    

    VAR_5 = qcow2_update_snapshot_refcount(VAR_0, s->l1_table_offset, s->l1_size, 0);

    if (VAR_5 < 0) {

        error_setg(VAR_3, "Failed to update snapshot status in disk");

        return VAR_5;

    }



#ifdef DEBUG_ALLOC

    {

        BdrvCheckResult result = {0};

        qcow2_check_refcounts(VAR_0, &result, 0);

    }

#endif

    return 0;

}

int FUNC_0(BlockDriverState *VAR_0,
const char *VAR_1,
const char *VAR_2,
Error **VAR_3)
{ BDRVQcowState *s = VAR_0->opaque; QCowSnapshot sn; int VAR_4, VAR_5; VAR_4 = find_snapshot_by_id_and_name(VAR_0, VAR_1, VAR_2); if (VAR_4 < 0) { error_setg(VAR_3, "Can't find the snapshot"); return -ENOENT; } sn = s->snapshots[VAR_4]; memmove(s->snapshots + VAR_4,
s->snapshots + VAR_4 + 1,
(s->nb_snapshots - VAR_4 - 1) * sizeof(sn)); s->nb_snapshots--; VAR_5 = qcow2_write_snapshots(VAR_0); if (VAR_5 < 0) { error_setg(VAR_3, "Failed to remove snapshot from snapshot list"); return VAR_5; } g_free(sn.id_str); g_free(sn.VAR_2); VAR_5 = qcow2_update_snapshot_refcount(VAR_0, sn.l1_table_offset,
sn.l1_size, -1); if (VAR_5 < 0) { error_setg(VAR_3, "Failed to free the cluster and L1 table"); return VAR_5; } qcow2_free_clusters(VAR_0, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t),
QCOW2_DISCARD_SNAPSHOT); VAR_5 = qcow2_update_snapshot_refcount(VAR_0, s->l1_table_offset, s->l1_size, 0); if (VAR_5 < 0) { error_setg(VAR_3, "Failed to update snapshot status in disk"); return VAR_5; } #ifdef DEBUG_ALLOC
{ BdrvCheckResult result = {0}; qcow2_check_refcounts(VAR_0, &result, 0); } #endif
return 0; }