1c142442bSKevin Wolf /*
2c142442bSKevin Wolf * Block driver for the QCOW version 2 format
3c142442bSKevin Wolf *
4c142442bSKevin Wolf * Copyright (c) 2004-2006 Fabrice Bellard
5c142442bSKevin Wolf *
6c142442bSKevin Wolf * Permission is hereby granted, free of charge, to any person obtaining a copy
7c142442bSKevin Wolf * of this software and associated documentation files (the "Software"), to deal
8c142442bSKevin Wolf * in the Software without restriction, including without limitation the rights
9c142442bSKevin Wolf * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10c142442bSKevin Wolf * copies of the Software, and to permit persons to whom the Software is
11c142442bSKevin Wolf * furnished to do so, subject to the following conditions:
12c142442bSKevin Wolf *
13c142442bSKevin Wolf * The above copyright notice and this permission notice shall be included in
14c142442bSKevin Wolf * all copies or substantial portions of the Software.
15c142442bSKevin Wolf *
16c142442bSKevin Wolf * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17c142442bSKevin Wolf * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18c142442bSKevin Wolf * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19c142442bSKevin Wolf * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20c142442bSKevin Wolf * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21c142442bSKevin Wolf * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22c142442bSKevin Wolf * THE SOFTWARE.
23c142442bSKevin Wolf */
24c142442bSKevin Wolf
2580c71a24SPeter Maydell #include "qemu/osdep.h"
267fa140abSEric Blake #include "sysemu/block-backend.h"
27da34e65cSMarkus Armbruster #include "qapi/error.h"
280d8c41daSMichael S. Tsirkin #include "qcow2.h"
2958369e22SPaolo Bonzini #include "qemu/bswap.h"
30d49b6836SMarkus Armbruster #include "qemu/error-report.h"
31f348b6d1SVeronia Bahaa #include "qemu/cutils.h"
325df022cfSPeter Maydell #include "qemu/memalign.h"
33c142442bSKevin Wolf
qcow2_free_single_snapshot(BlockDriverState * bs,int i)34099febf3SMax Reitz static void qcow2_free_single_snapshot(BlockDriverState *bs, int i)
35099febf3SMax Reitz {
36099febf3SMax Reitz BDRVQcow2State *s = bs->opaque;
37099febf3SMax Reitz
38099febf3SMax Reitz assert(i >= 0 && i < s->nb_snapshots);
39099febf3SMax Reitz g_free(s->snapshots[i].name);
40099febf3SMax Reitz g_free(s->snapshots[i].id_str);
41099febf3SMax Reitz g_free(s->snapshots[i].unknown_extra_data);
42099febf3SMax Reitz memset(&s->snapshots[i], 0, sizeof(s->snapshots[i]));
43099febf3SMax Reitz }
44099febf3SMax Reitz
qcow2_free_snapshots(BlockDriverState * bs)45ed6ccf0fSKevin Wolf void qcow2_free_snapshots(BlockDriverState *bs)
46c142442bSKevin Wolf {
47ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
48c142442bSKevin Wolf int i;
49c142442bSKevin Wolf
50c142442bSKevin Wolf for(i = 0; i < s->nb_snapshots; i++) {
51099febf3SMax Reitz qcow2_free_single_snapshot(bs, i);
52c142442bSKevin Wolf }
537267c094SAnthony Liguori g_free(s->snapshots);
54c142442bSKevin Wolf s->snapshots = NULL;
55c142442bSKevin Wolf s->nb_snapshots = 0;
56c142442bSKevin Wolf }
57c142442bSKevin Wolf
58f91f1f15SMax Reitz /*
59f91f1f15SMax Reitz * If @repair is true, try to repair a broken snapshot table instead
60f91f1f15SMax Reitz * of just returning an error:
61f91f1f15SMax Reitz *
62099febf3SMax Reitz * - If the snapshot table was too long, set *nb_clusters_reduced to
63099febf3SMax Reitz * the number of snapshots removed off the end.
64099febf3SMax Reitz * The caller will update the on-disk nb_snapshots accordingly;
65099febf3SMax Reitz * this leaks clusters, but is safe.
66099febf3SMax Reitz * (The on-disk information must be updated before
67099febf3SMax Reitz * qcow2_check_refcounts(), because that function relies on
68099febf3SMax Reitz * s->nb_snapshots to reflect the on-disk value.)
69099febf3SMax Reitz *
70f91f1f15SMax Reitz * - If there were snapshots with too much extra metadata, increment
71f91f1f15SMax Reitz * *extra_data_dropped for each.
72f91f1f15SMax Reitz * This requires the caller to eventually rewrite the whole snapshot
73f91f1f15SMax Reitz * table, which requires cluster allocation. Therefore, this should
74f91f1f15SMax Reitz * be done only after qcow2_check_refcounts() made sure the refcount
75f91f1f15SMax Reitz * structures are valid.
76f91f1f15SMax Reitz * (In the meantime, the image is still valid because
77f91f1f15SMax Reitz * qcow2_check_refcounts() does not do anything with snapshots'
78f91f1f15SMax Reitz * extra data.)
79f91f1f15SMax Reitz */
80*a39bae4eSPaolo Bonzini static coroutine_fn GRAPH_RDLOCK
qcow2_do_read_snapshots(BlockDriverState * bs,bool repair,int * nb_clusters_reduced,int * extra_data_dropped,Error ** errp)81*a39bae4eSPaolo Bonzini int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair,
82099febf3SMax Reitz int *nb_clusters_reduced,
83f91f1f15SMax Reitz int *extra_data_dropped,
84f91f1f15SMax Reitz Error **errp)
85c142442bSKevin Wolf {
86ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
87c142442bSKevin Wolf QCowSnapshotHeader h;
88c2c9a466SKevin Wolf QCowSnapshotExtraData extra;
89c142442bSKevin Wolf QCowSnapshot *sn;
90c142442bSKevin Wolf int i, id_str_size, name_size;
91099febf3SMax Reitz int64_t offset, pre_sn_offset;
9262414335SMax Reitz uint64_t table_length = 0;
9342deb29fSKevin Wolf int ret;
94c142442bSKevin Wolf
95c142442bSKevin Wolf if (!s->nb_snapshots) {
96c142442bSKevin Wolf s->snapshots = NULL;
97c142442bSKevin Wolf s->snapshots_size = 0;
98c142442bSKevin Wolf return 0;
99c142442bSKevin Wolf }
100c142442bSKevin Wolf
101c142442bSKevin Wolf offset = s->snapshots_offset;
1025839e53bSMarkus Armbruster s->snapshots = g_new0(QCowSnapshot, s->nb_snapshots);
10342deb29fSKevin Wolf
104c142442bSKevin Wolf for(i = 0; i < s->nb_snapshots; i++) {
105f91f1f15SMax Reitz bool truncate_unknown_extra_data = false;
106f91f1f15SMax Reitz
107099febf3SMax Reitz pre_sn_offset = offset;
10862414335SMax Reitz table_length = ROUND_UP(table_length, 8);
10962414335SMax Reitz
11042deb29fSKevin Wolf /* Read statically sized part of the snapshot header */
1119e029689SAlberto Garcia offset = ROUND_UP(offset, 8);
112*a39bae4eSPaolo Bonzini ret = bdrv_co_pread(bs->file, offset, sizeof(h), &h, 0);
11342deb29fSKevin Wolf if (ret < 0) {
114ecf6c7c0SMax Reitz error_setg_errno(errp, -ret, "Failed to read snapshot table");
115c142442bSKevin Wolf goto fail;
11642deb29fSKevin Wolf }
11742deb29fSKevin Wolf
118c142442bSKevin Wolf offset += sizeof(h);
119c142442bSKevin Wolf sn = s->snapshots + i;
120c142442bSKevin Wolf sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);
121c142442bSKevin Wolf sn->l1_size = be32_to_cpu(h.l1_size);
122c142442bSKevin Wolf sn->vm_state_size = be32_to_cpu(h.vm_state_size);
123c142442bSKevin Wolf sn->date_sec = be32_to_cpu(h.date_sec);
124c142442bSKevin Wolf sn->date_nsec = be32_to_cpu(h.date_nsec);
125c142442bSKevin Wolf sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec);
126fcf9a6b7SMax Reitz sn->extra_data_size = be32_to_cpu(h.extra_data_size);
127c142442bSKevin Wolf
128c142442bSKevin Wolf id_str_size = be16_to_cpu(h.id_str_size);
129c142442bSKevin Wolf name_size = be16_to_cpu(h.name_size);
130c142442bSKevin Wolf
131fcf9a6b7SMax Reitz if (sn->extra_data_size > QCOW_MAX_SNAPSHOT_EXTRA_DATA) {
132f91f1f15SMax Reitz if (!repair) {
133fcf9a6b7SMax Reitz ret = -EFBIG;
134fcf9a6b7SMax Reitz error_setg(errp, "Too much extra metadata in snapshot table "
135fcf9a6b7SMax Reitz "entry %i", i);
136f91f1f15SMax Reitz error_append_hint(errp, "You can force-remove this extra "
137f91f1f15SMax Reitz "metadata with qemu-img check -r all\n");
138fcf9a6b7SMax Reitz goto fail;
139fcf9a6b7SMax Reitz }
140fcf9a6b7SMax Reitz
141f91f1f15SMax Reitz fprintf(stderr, "Discarding too much extra metadata in snapshot "
142f91f1f15SMax Reitz "table entry %i (%" PRIu32 " > %u)\n",
143f91f1f15SMax Reitz i, sn->extra_data_size, QCOW_MAX_SNAPSHOT_EXTRA_DATA);
144f91f1f15SMax Reitz
145f91f1f15SMax Reitz (*extra_data_dropped)++;
146f91f1f15SMax Reitz truncate_unknown_extra_data = true;
147f91f1f15SMax Reitz }
148f91f1f15SMax Reitz
149fcf9a6b7SMax Reitz /* Read known extra data */
150*a39bae4eSPaolo Bonzini ret = bdrv_co_pread(bs->file, offset,
15132cc71deSAlberto Faria MIN(sizeof(extra), sn->extra_data_size), &extra, 0);
152c2c9a466SKevin Wolf if (ret < 0) {
153ecf6c7c0SMax Reitz error_setg_errno(errp, -ret, "Failed to read snapshot table");
154c2c9a466SKevin Wolf goto fail;
155c2c9a466SKevin Wolf }
156fcf9a6b7SMax Reitz offset += MIN(sizeof(extra), sn->extra_data_size);
157c142442bSKevin Wolf
158fcf9a6b7SMax Reitz if (sn->extra_data_size >= endof(QCowSnapshotExtraData,
159d8fa8442SMax Reitz vm_state_size_large)) {
160c2c9a466SKevin Wolf sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large);
161c2c9a466SKevin Wolf }
162c2c9a466SKevin Wolf
163fcf9a6b7SMax Reitz if (sn->extra_data_size >= endof(QCowSnapshotExtraData, disk_size)) {
16490b27759SKevin Wolf sn->disk_size = be64_to_cpu(extra.disk_size);
16590b27759SKevin Wolf } else {
16690b27759SKevin Wolf sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
16790b27759SKevin Wolf }
16890b27759SKevin Wolf
169bbacffc5SPavel Dovgalyuk if (sn->extra_data_size >= endof(QCowSnapshotExtraData, icount)) {
170bbacffc5SPavel Dovgalyuk sn->icount = be64_to_cpu(extra.icount);
171bbacffc5SPavel Dovgalyuk } else {
172bbacffc5SPavel Dovgalyuk sn->icount = -1ULL;
173bbacffc5SPavel Dovgalyuk }
174bbacffc5SPavel Dovgalyuk
175fcf9a6b7SMax Reitz if (sn->extra_data_size > sizeof(extra)) {
176f91f1f15SMax Reitz uint64_t extra_data_end;
177f91f1f15SMax Reitz size_t unknown_extra_data_size;
178fcf9a6b7SMax Reitz
179f91f1f15SMax Reitz extra_data_end = offset + sn->extra_data_size - sizeof(extra);
180f91f1f15SMax Reitz
181f91f1f15SMax Reitz if (truncate_unknown_extra_data) {
182f91f1f15SMax Reitz sn->extra_data_size = QCOW_MAX_SNAPSHOT_EXTRA_DATA;
183f91f1f15SMax Reitz }
184f91f1f15SMax Reitz
185f91f1f15SMax Reitz /* Store unknown extra data */
186f91f1f15SMax Reitz unknown_extra_data_size = sn->extra_data_size - sizeof(extra);
187fcf9a6b7SMax Reitz sn->unknown_extra_data = g_malloc(unknown_extra_data_size);
188*a39bae4eSPaolo Bonzini ret = bdrv_co_pread(bs->file, offset, unknown_extra_data_size,
18932cc71deSAlberto Faria sn->unknown_extra_data, 0);
190fcf9a6b7SMax Reitz if (ret < 0) {
191f91f1f15SMax Reitz error_setg_errno(errp, -ret,
192f91f1f15SMax Reitz "Failed to read snapshot table");
193fcf9a6b7SMax Reitz goto fail;
194fcf9a6b7SMax Reitz }
195f91f1f15SMax Reitz offset = extra_data_end;
196fcf9a6b7SMax Reitz }
197fcf9a6b7SMax Reitz
19842deb29fSKevin Wolf /* Read snapshot ID */
1997267c094SAnthony Liguori sn->id_str = g_malloc(id_str_size + 1);
200*a39bae4eSPaolo Bonzini ret = bdrv_co_pread(bs->file, offset, id_str_size, sn->id_str, 0);
20142deb29fSKevin Wolf if (ret < 0) {
202ecf6c7c0SMax Reitz error_setg_errno(errp, -ret, "Failed to read snapshot table");
203c142442bSKevin Wolf goto fail;
20442deb29fSKevin Wolf }
205c142442bSKevin Wolf offset += id_str_size;
206c142442bSKevin Wolf sn->id_str[id_str_size] = '\0';
207c142442bSKevin Wolf
20842deb29fSKevin Wolf /* Read snapshot name */
2097267c094SAnthony Liguori sn->name = g_malloc(name_size + 1);
210*a39bae4eSPaolo Bonzini ret = bdrv_co_pread(bs->file, offset, name_size, sn->name, 0);
21142deb29fSKevin Wolf if (ret < 0) {
212ecf6c7c0SMax Reitz error_setg_errno(errp, -ret, "Failed to read snapshot table");
213c142442bSKevin Wolf goto fail;
21442deb29fSKevin Wolf }
215c142442bSKevin Wolf offset += name_size;
216c142442bSKevin Wolf sn->name[name_size] = '\0';
2175dae6e30SKevin Wolf
21862414335SMax Reitz /* Note that the extra data may have been truncated */
21962414335SMax Reitz table_length += sizeof(h) + sn->extra_data_size + id_str_size +
22062414335SMax Reitz name_size;
22162414335SMax Reitz if (!repair) {
22262414335SMax Reitz assert(table_length == offset - s->snapshots_offset);
22362414335SMax Reitz }
22462414335SMax Reitz
22562414335SMax Reitz if (table_length > QCOW_MAX_SNAPSHOTS_SIZE ||
22662414335SMax Reitz offset - s->snapshots_offset > INT_MAX)
22762414335SMax Reitz {
228099febf3SMax Reitz if (!repair) {
2295dae6e30SKevin Wolf ret = -EFBIG;
230ecf6c7c0SMax Reitz error_setg(errp, "Snapshot table is too big");
231099febf3SMax Reitz error_append_hint(errp, "You can force-remove all %u "
232099febf3SMax Reitz "overhanging snapshots with qemu-img check "
233099febf3SMax Reitz "-r all\n", s->nb_snapshots - i);
2345dae6e30SKevin Wolf goto fail;
2355dae6e30SKevin Wolf }
236099febf3SMax Reitz
237099febf3SMax Reitz fprintf(stderr, "Discarding %u overhanging snapshots (snapshot "
238099febf3SMax Reitz "table is too big)\n", s->nb_snapshots - i);
239099febf3SMax Reitz
240099febf3SMax Reitz *nb_clusters_reduced += (s->nb_snapshots - i);
241099febf3SMax Reitz
242099febf3SMax Reitz /* Discard current snapshot also */
243099febf3SMax Reitz qcow2_free_single_snapshot(bs, i);
244099febf3SMax Reitz
245099febf3SMax Reitz /*
246099febf3SMax Reitz * This leaks all the rest of the snapshot table and the
247099febf3SMax Reitz * snapshots' clusters, but we run in check -r all mode,
248099febf3SMax Reitz * so qcow2_check_refcounts() will take care of it.
249099febf3SMax Reitz */
250099febf3SMax Reitz s->nb_snapshots = i;
251099febf3SMax Reitz offset = pre_sn_offset;
252099febf3SMax Reitz break;
253099febf3SMax Reitz }
254c142442bSKevin Wolf }
25542deb29fSKevin Wolf
2565dae6e30SKevin Wolf assert(offset - s->snapshots_offset <= INT_MAX);
257c142442bSKevin Wolf s->snapshots_size = offset - s->snapshots_offset;
258c142442bSKevin Wolf return 0;
25942deb29fSKevin Wolf
260c142442bSKevin Wolf fail:
261ed6ccf0fSKevin Wolf qcow2_free_snapshots(bs);
26242deb29fSKevin Wolf return ret;
263c142442bSKevin Wolf }
264c142442bSKevin Wolf
qcow2_read_snapshots(BlockDriverState * bs,Error ** errp)265*a39bae4eSPaolo Bonzini int coroutine_fn qcow2_read_snapshots(BlockDriverState *bs, Error **errp)
266f91f1f15SMax Reitz {
267099febf3SMax Reitz return qcow2_do_read_snapshots(bs, false, NULL, NULL, errp);
268f91f1f15SMax Reitz }
269f91f1f15SMax Reitz
270c142442bSKevin Wolf /* add at the end of the file a new list of snapshots */
qcow2_write_snapshots(BlockDriverState * bs)271e0314b56SMax Reitz int qcow2_write_snapshots(BlockDriverState *bs)
272c142442bSKevin Wolf {
273ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
274c142442bSKevin Wolf QCowSnapshot *sn;
275c142442bSKevin Wolf QCowSnapshotHeader h;
276c2c9a466SKevin Wolf QCowSnapshotExtraData extra;
277c142442bSKevin Wolf int i, name_size, id_str_size, snapshots_size;
278d69969c4SKevin Wolf struct {
279d69969c4SKevin Wolf uint32_t nb_snapshots;
280d69969c4SKevin Wolf uint64_t snapshots_offset;
281d69969c4SKevin Wolf } QEMU_PACKED header_data;
2825dae6e30SKevin Wolf int64_t offset, snapshots_offset = 0;
28307fd8779SKevin Wolf int ret;
284c142442bSKevin Wolf
285c142442bSKevin Wolf /* compute the size of the snapshots */
286c142442bSKevin Wolf offset = 0;
287c142442bSKevin Wolf for(i = 0; i < s->nb_snapshots; i++) {
288c142442bSKevin Wolf sn = s->snapshots + i;
2899e029689SAlberto Garcia offset = ROUND_UP(offset, 8);
290c142442bSKevin Wolf offset += sizeof(h);
291fcf9a6b7SMax Reitz offset += MAX(sizeof(extra), sn->extra_data_size);
292c142442bSKevin Wolf offset += strlen(sn->id_str);
293c142442bSKevin Wolf offset += strlen(sn->name);
2945dae6e30SKevin Wolf
2955dae6e30SKevin Wolf if (offset > QCOW_MAX_SNAPSHOTS_SIZE) {
2965dae6e30SKevin Wolf ret = -EFBIG;
2975dae6e30SKevin Wolf goto fail;
298c142442bSKevin Wolf }
2995dae6e30SKevin Wolf }
3005dae6e30SKevin Wolf
3015dae6e30SKevin Wolf assert(offset <= INT_MAX);
302c142442bSKevin Wolf snapshots_size = offset;
303c142442bSKevin Wolf
30407fd8779SKevin Wolf /* Allocate space for the new snapshot list */
305ed6ccf0fSKevin Wolf snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
306c142442bSKevin Wolf offset = snapshots_offset;
3075d757b56SKevin Wolf if (offset < 0) {
30837d41f0aSMax Reitz ret = offset;
30937d41f0aSMax Reitz goto fail;
3105d757b56SKevin Wolf }
311f6977f15SStefan Hajnoczi ret = bdrv_flush(bs);
312f6977f15SStefan Hajnoczi if (ret < 0) {
31337d41f0aSMax Reitz goto fail;
314f6977f15SStefan Hajnoczi }
315c142442bSKevin Wolf
316cf93980eSMax Reitz /* The snapshot list position has not yet been updated, so these clusters
317cf93980eSMax Reitz * must indeed be completely free */
318966b000fSKevin Wolf ret = qcow2_pre_write_overlap_check(bs, 0, offset, snapshots_size, false);
319cf93980eSMax Reitz if (ret < 0) {
32037d41f0aSMax Reitz goto fail;
321cf93980eSMax Reitz }
322cf93980eSMax Reitz
323cf93980eSMax Reitz
32407fd8779SKevin Wolf /* Write all snapshots to the new list */
325c142442bSKevin Wolf for(i = 0; i < s->nb_snapshots; i++) {
326c142442bSKevin Wolf sn = s->snapshots + i;
327c142442bSKevin Wolf memset(&h, 0, sizeof(h));
328c142442bSKevin Wolf h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);
329c142442bSKevin Wolf h.l1_size = cpu_to_be32(sn->l1_size);
330c2c9a466SKevin Wolf /* If it doesn't fit in 32 bit, older implementations should treat it
331c2c9a466SKevin Wolf * as a disk-only snapshot rather than truncate the VM state */
332c2c9a466SKevin Wolf if (sn->vm_state_size <= 0xffffffff) {
333c142442bSKevin Wolf h.vm_state_size = cpu_to_be32(sn->vm_state_size);
334c2c9a466SKevin Wolf }
335c142442bSKevin Wolf h.date_sec = cpu_to_be32(sn->date_sec);
336c142442bSKevin Wolf h.date_nsec = cpu_to_be32(sn->date_nsec);
337c142442bSKevin Wolf h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);
338fcf9a6b7SMax Reitz h.extra_data_size = cpu_to_be32(MAX(sizeof(extra),
339fcf9a6b7SMax Reitz sn->extra_data_size));
340c2c9a466SKevin Wolf
341c2c9a466SKevin Wolf memset(&extra, 0, sizeof(extra));
342c2c9a466SKevin Wolf extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size);
34390b27759SKevin Wolf extra.disk_size = cpu_to_be64(sn->disk_size);
344bbacffc5SPavel Dovgalyuk extra.icount = cpu_to_be64(sn->icount);
345c142442bSKevin Wolf
346c142442bSKevin Wolf id_str_size = strlen(sn->id_str);
347c142442bSKevin Wolf name_size = strlen(sn->name);
34888fb1535SMax Reitz assert(id_str_size <= UINT16_MAX && name_size <= UINT16_MAX);
349c142442bSKevin Wolf h.id_str_size = cpu_to_be16(id_str_size);
350c142442bSKevin Wolf h.name_size = cpu_to_be16(name_size);
3519e029689SAlberto Garcia offset = ROUND_UP(offset, 8);
35207fd8779SKevin Wolf
35332cc71deSAlberto Faria ret = bdrv_pwrite(bs->file, offset, sizeof(h), &h, 0);
35407fd8779SKevin Wolf if (ret < 0) {
355c142442bSKevin Wolf goto fail;
35607fd8779SKevin Wolf }
357c142442bSKevin Wolf offset += sizeof(h);
35807fd8779SKevin Wolf
35932cc71deSAlberto Faria ret = bdrv_pwrite(bs->file, offset, sizeof(extra), &extra, 0);
360c2c9a466SKevin Wolf if (ret < 0) {
361c2c9a466SKevin Wolf goto fail;
362c2c9a466SKevin Wolf }
363c2c9a466SKevin Wolf offset += sizeof(extra);
364c2c9a466SKevin Wolf
365fcf9a6b7SMax Reitz if (sn->extra_data_size > sizeof(extra)) {
366fcf9a6b7SMax Reitz size_t unknown_extra_data_size =
367fcf9a6b7SMax Reitz sn->extra_data_size - sizeof(extra);
368fcf9a6b7SMax Reitz
369fcf9a6b7SMax Reitz /* qcow2_read_snapshots() ensures no unbounded allocation */
370fcf9a6b7SMax Reitz assert(unknown_extra_data_size <= BDRV_REQUEST_MAX_BYTES);
371fcf9a6b7SMax Reitz assert(sn->unknown_extra_data);
372fcf9a6b7SMax Reitz
37332cc71deSAlberto Faria ret = bdrv_pwrite(bs->file, offset, unknown_extra_data_size,
37432cc71deSAlberto Faria sn->unknown_extra_data, 0);
375fcf9a6b7SMax Reitz if (ret < 0) {
376fcf9a6b7SMax Reitz goto fail;
377fcf9a6b7SMax Reitz }
378fcf9a6b7SMax Reitz offset += unknown_extra_data_size;
379fcf9a6b7SMax Reitz }
380fcf9a6b7SMax Reitz
38132cc71deSAlberto Faria ret = bdrv_pwrite(bs->file, offset, id_str_size, sn->id_str, 0);
38207fd8779SKevin Wolf if (ret < 0) {
383c142442bSKevin Wolf goto fail;
38407fd8779SKevin Wolf }
385c142442bSKevin Wolf offset += id_str_size;
38607fd8779SKevin Wolf
38732cc71deSAlberto Faria ret = bdrv_pwrite(bs->file, offset, name_size, sn->name, 0);
38807fd8779SKevin Wolf if (ret < 0) {
389c142442bSKevin Wolf goto fail;
39007fd8779SKevin Wolf }
391c142442bSKevin Wolf offset += name_size;
392c142442bSKevin Wolf }
393c142442bSKevin Wolf
39407fd8779SKevin Wolf /*
39507fd8779SKevin Wolf * Update the header to point to the new snapshot table. This requires the
39607fd8779SKevin Wolf * new table and its refcounts to be stable on disk.
39707fd8779SKevin Wolf */
39807fd8779SKevin Wolf ret = bdrv_flush(bs);
39907fd8779SKevin Wolf if (ret < 0) {
40007fd8779SKevin Wolf goto fail;
40107fd8779SKevin Wolf }
40207fd8779SKevin Wolf
403d69969c4SKevin Wolf QEMU_BUILD_BUG_ON(offsetof(QCowHeader, snapshots_offset) !=
404d8fa8442SMax Reitz endof(QCowHeader, nb_snapshots));
40507fd8779SKevin Wolf
406d69969c4SKevin Wolf header_data.nb_snapshots = cpu_to_be32(s->nb_snapshots);
407d69969c4SKevin Wolf header_data.snapshots_offset = cpu_to_be64(snapshots_offset);
408d69969c4SKevin Wolf
409d9ca2ea2SKevin Wolf ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
41032cc71deSAlberto Faria sizeof(header_data), &header_data, 0);
41107fd8779SKevin Wolf if (ret < 0) {
412c142442bSKevin Wolf goto fail;
41307fd8779SKevin Wolf }
414c142442bSKevin Wolf
415c142442bSKevin Wolf /* free the old snapshot table */
4166cfcb9b8SKevin Wolf qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size,
4176cfcb9b8SKevin Wolf QCOW2_DISCARD_SNAPSHOT);
418c142442bSKevin Wolf s->snapshots_offset = snapshots_offset;
419c142442bSKevin Wolf s->snapshots_size = snapshots_size;
420c142442bSKevin Wolf return 0;
42107fd8779SKevin Wolf
422c142442bSKevin Wolf fail:
4239186ad96SMax Reitz if (snapshots_offset > 0) {
4249186ad96SMax Reitz qcow2_free_clusters(bs, snapshots_offset, snapshots_size,
4259186ad96SMax Reitz QCOW2_DISCARD_ALWAYS);
4269186ad96SMax Reitz }
42707fd8779SKevin Wolf return ret;
428c142442bSKevin Wolf }
429c142442bSKevin Wolf
qcow2_check_read_snapshot_table(BlockDriverState * bs,BdrvCheckResult * result,BdrvCheckMode fix)4308bc584feSMax Reitz int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs,
4318bc584feSMax Reitz BdrvCheckResult *result,
4328bc584feSMax Reitz BdrvCheckMode fix)
4338bc584feSMax Reitz {
4348bc584feSMax Reitz BDRVQcow2State *s = bs->opaque;
4358bc584feSMax Reitz Error *local_err = NULL;
436099febf3SMax Reitz int nb_clusters_reduced = 0;
437f91f1f15SMax Reitz int extra_data_dropped = 0;
4388bc584feSMax Reitz int ret;
4398bc584feSMax Reitz struct {
4408bc584feSMax Reitz uint32_t nb_snapshots;
4418bc584feSMax Reitz uint64_t snapshots_offset;
4428bc584feSMax Reitz } QEMU_PACKED snapshot_table_pointer;
4438bc584feSMax Reitz
4448bc584feSMax Reitz /* qcow2_do_open() discards this information in check mode */
44538505e2aSAlberto Faria ret = bdrv_co_pread(bs->file, offsetof(QCowHeader, nb_snapshots),
44632cc71deSAlberto Faria sizeof(snapshot_table_pointer), &snapshot_table_pointer,
44753fb7844SAlberto Faria 0);
4488bc584feSMax Reitz if (ret < 0) {
4498bc584feSMax Reitz result->check_errors++;
4508bc584feSMax Reitz fprintf(stderr, "ERROR failed to read the snapshot table pointer from "
4518bc584feSMax Reitz "the image header: %s\n", strerror(-ret));
4528bc584feSMax Reitz return ret;
4538bc584feSMax Reitz }
4548bc584feSMax Reitz
4558bc584feSMax Reitz s->snapshots_offset = be64_to_cpu(snapshot_table_pointer.snapshots_offset);
4568bc584feSMax Reitz s->nb_snapshots = be32_to_cpu(snapshot_table_pointer.nb_snapshots);
4578bc584feSMax Reitz
458d2b1d1ecSMax Reitz if (s->nb_snapshots > QCOW_MAX_SNAPSHOTS && (fix & BDRV_FIX_ERRORS)) {
459d2b1d1ecSMax Reitz fprintf(stderr, "Discarding %u overhanging snapshots\n",
460d2b1d1ecSMax Reitz s->nb_snapshots - QCOW_MAX_SNAPSHOTS);
461d2b1d1ecSMax Reitz
462d2b1d1ecSMax Reitz nb_clusters_reduced += s->nb_snapshots - QCOW_MAX_SNAPSHOTS;
463d2b1d1ecSMax Reitz s->nb_snapshots = QCOW_MAX_SNAPSHOTS;
464d2b1d1ecSMax Reitz }
465d2b1d1ecSMax Reitz
4668bc584feSMax Reitz ret = qcow2_validate_table(bs, s->snapshots_offset, s->nb_snapshots,
4678bc584feSMax Reitz sizeof(QCowSnapshotHeader),
4688bc584feSMax Reitz sizeof(QCowSnapshotHeader) * QCOW_MAX_SNAPSHOTS,
4698bc584feSMax Reitz "snapshot table", &local_err);
4708bc584feSMax Reitz if (ret < 0) {
4718bc584feSMax Reitz result->check_errors++;
4728bc584feSMax Reitz error_reportf_err(local_err, "ERROR ");
4738bc584feSMax Reitz
474d2b1d1ecSMax Reitz if (s->nb_snapshots > QCOW_MAX_SNAPSHOTS) {
475d2b1d1ecSMax Reitz fprintf(stderr, "You can force-remove all %u overhanging snapshots "
476d2b1d1ecSMax Reitz "with qemu-img check -r all\n",
477d2b1d1ecSMax Reitz s->nb_snapshots - QCOW_MAX_SNAPSHOTS);
478d2b1d1ecSMax Reitz }
479d2b1d1ecSMax Reitz
4808bc584feSMax Reitz /* We did not read the snapshot table, so invalidate this information */
4818bc584feSMax Reitz s->snapshots_offset = 0;
4828bc584feSMax Reitz s->nb_snapshots = 0;
4838bc584feSMax Reitz
4848bc584feSMax Reitz return ret;
4858bc584feSMax Reitz }
4868bc584feSMax Reitz
4878bc584feSMax Reitz qemu_co_mutex_unlock(&s->lock);
488f91f1f15SMax Reitz ret = qcow2_do_read_snapshots(bs, fix & BDRV_FIX_ERRORS,
489099febf3SMax Reitz &nb_clusters_reduced, &extra_data_dropped,
490099febf3SMax Reitz &local_err);
4918bc584feSMax Reitz qemu_co_mutex_lock(&s->lock);
4928bc584feSMax Reitz if (ret < 0) {
4938bc584feSMax Reitz result->check_errors++;
4948bc584feSMax Reitz error_reportf_err(local_err,
4958bc584feSMax Reitz "ERROR failed to read the snapshot table: ");
4968bc584feSMax Reitz
4978bc584feSMax Reitz /* We did not read the snapshot table, so invalidate this information */
4988bc584feSMax Reitz s->snapshots_offset = 0;
4998bc584feSMax Reitz s->nb_snapshots = 0;
5008bc584feSMax Reitz
5018bc584feSMax Reitz return ret;
5028bc584feSMax Reitz }
503099febf3SMax Reitz result->corruptions += nb_clusters_reduced + extra_data_dropped;
504099febf3SMax Reitz
505099febf3SMax Reitz if (nb_clusters_reduced) {
506099febf3SMax Reitz /*
507099febf3SMax Reitz * Update image header now, because:
508099febf3SMax Reitz * (1) qcow2_check_refcounts() relies on s->nb_snapshots to be
509099febf3SMax Reitz * the same as what the image header says,
510099febf3SMax Reitz * (2) this leaks clusters, but qcow2_check_refcounts() will
511099febf3SMax Reitz * fix that.
512099febf3SMax Reitz */
513099febf3SMax Reitz assert(fix & BDRV_FIX_ERRORS);
514099febf3SMax Reitz
515099febf3SMax Reitz snapshot_table_pointer.nb_snapshots = cpu_to_be32(s->nb_snapshots);
516a8f0e83cSAlberto Faria ret = bdrv_co_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
51732cc71deSAlberto Faria sizeof(snapshot_table_pointer.nb_snapshots),
51832cc71deSAlberto Faria &snapshot_table_pointer.nb_snapshots, 0);
519099febf3SMax Reitz if (ret < 0) {
520099febf3SMax Reitz result->check_errors++;
521099febf3SMax Reitz fprintf(stderr, "ERROR failed to update the snapshot count in the "
522099febf3SMax Reitz "image header: %s\n", strerror(-ret));
523099febf3SMax Reitz return ret;
524099febf3SMax Reitz }
525099febf3SMax Reitz
526099febf3SMax Reitz result->corruptions_fixed += nb_clusters_reduced;
527099febf3SMax Reitz result->corruptions -= nb_clusters_reduced;
528099febf3SMax Reitz }
5298bc584feSMax Reitz
530e40e6e88SMax Reitz /*
531e40e6e88SMax Reitz * All of v3 images' snapshot table entries need to have at least
532e40e6e88SMax Reitz * 16 bytes of extra data.
533e40e6e88SMax Reitz */
534e40e6e88SMax Reitz if (s->qcow_version >= 3) {
535e40e6e88SMax Reitz int i;
536e40e6e88SMax Reitz for (i = 0; i < s->nb_snapshots; i++) {
537e40e6e88SMax Reitz if (s->snapshots[i].extra_data_size <
538e40e6e88SMax Reitz sizeof_field(QCowSnapshotExtraData, vm_state_size_large) +
539e40e6e88SMax Reitz sizeof_field(QCowSnapshotExtraData, disk_size))
540e40e6e88SMax Reitz {
541e40e6e88SMax Reitz result->corruptions++;
542e40e6e88SMax Reitz fprintf(stderr, "%s snapshot table entry %i is incomplete\n",
543e40e6e88SMax Reitz fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
544e40e6e88SMax Reitz }
545e40e6e88SMax Reitz }
546e40e6e88SMax Reitz }
547e40e6e88SMax Reitz
5488bc584feSMax Reitz return 0;
5498bc584feSMax Reitz }
5508bc584feSMax Reitz
qcow2_check_fix_snapshot_table(BlockDriverState * bs,BdrvCheckResult * result,BdrvCheckMode fix)551fe446b5dSMax Reitz int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs,
552fe446b5dSMax Reitz BdrvCheckResult *result,
553fe446b5dSMax Reitz BdrvCheckMode fix)
554fe446b5dSMax Reitz {
555fe446b5dSMax Reitz BDRVQcow2State *s = bs->opaque;
556fe446b5dSMax Reitz int ret;
557fe446b5dSMax Reitz
558fe446b5dSMax Reitz if (result->corruptions && (fix & BDRV_FIX_ERRORS)) {
559fe446b5dSMax Reitz qemu_co_mutex_unlock(&s->lock);
560fe446b5dSMax Reitz ret = qcow2_write_snapshots(bs);
561fe446b5dSMax Reitz qemu_co_mutex_lock(&s->lock);
562fe446b5dSMax Reitz if (ret < 0) {
563fe446b5dSMax Reitz result->check_errors++;
564fe446b5dSMax Reitz fprintf(stderr, "ERROR failed to update snapshot table: %s\n",
565fe446b5dSMax Reitz strerror(-ret));
566fe446b5dSMax Reitz return ret;
567fe446b5dSMax Reitz }
568fe446b5dSMax Reitz
569fe446b5dSMax Reitz result->corruptions_fixed += result->corruptions;
570fe446b5dSMax Reitz result->corruptions = 0;
571fe446b5dSMax Reitz }
572fe446b5dSMax Reitz
573fe446b5dSMax Reitz return 0;
574fe446b5dSMax Reitz }
575fe446b5dSMax Reitz
find_new_snapshot_id(BlockDriverState * bs,char * id_str,int id_str_size)576c142442bSKevin Wolf static void find_new_snapshot_id(BlockDriverState *bs,
577c142442bSKevin Wolf char *id_str, int id_str_size)
578c142442bSKevin Wolf {
579ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
580c142442bSKevin Wolf QCowSnapshot *sn;
58100c49b21SMax Reitz int i;
58200c49b21SMax Reitz unsigned long id, id_max = 0;
583c142442bSKevin Wolf
584c142442bSKevin Wolf for(i = 0; i < s->nb_snapshots; i++) {
585c142442bSKevin Wolf sn = s->snapshots + i;
586c142442bSKevin Wolf id = strtoul(sn->id_str, NULL, 10);
587c142442bSKevin Wolf if (id > id_max)
588c142442bSKevin Wolf id_max = id;
589c142442bSKevin Wolf }
59000c49b21SMax Reitz snprintf(id_str, id_str_size, "%lu", id_max + 1);
591c142442bSKevin Wolf }
592c142442bSKevin Wolf
find_snapshot_by_id_and_name(BlockDriverState * bs,const char * id,const char * name)593a89d89d3SWenchao Xia static int find_snapshot_by_id_and_name(BlockDriverState *bs,
594a89d89d3SWenchao Xia const char *id,
595a89d89d3SWenchao Xia const char *name)
596c142442bSKevin Wolf {
597ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
598c142442bSKevin Wolf int i;
599c142442bSKevin Wolf
600a89d89d3SWenchao Xia if (id && name) {
601c142442bSKevin Wolf for (i = 0; i < s->nb_snapshots; i++) {
602a89d89d3SWenchao Xia if (!strcmp(s->snapshots[i].id_str, id) &&
603a89d89d3SWenchao Xia !strcmp(s->snapshots[i].name, name)) {
604c142442bSKevin Wolf return i;
605c142442bSKevin Wolf }
606a89d89d3SWenchao Xia }
607a89d89d3SWenchao Xia } else if (id) {
608a89d89d3SWenchao Xia for (i = 0; i < s->nb_snapshots; i++) {
609a89d89d3SWenchao Xia if (!strcmp(s->snapshots[i].id_str, id)) {
610a89d89d3SWenchao Xia return i;
611a89d89d3SWenchao Xia }
612a89d89d3SWenchao Xia }
613a89d89d3SWenchao Xia } else if (name) {
614a89d89d3SWenchao Xia for (i = 0; i < s->nb_snapshots; i++) {
615a89d89d3SWenchao Xia if (!strcmp(s->snapshots[i].name, name)) {
616a89d89d3SWenchao Xia return i;
617a89d89d3SWenchao Xia }
618a89d89d3SWenchao Xia }
619a89d89d3SWenchao Xia }
620a89d89d3SWenchao Xia
621c142442bSKevin Wolf return -1;
622c142442bSKevin Wolf }
623c142442bSKevin Wolf
find_snapshot_by_id_or_name(BlockDriverState * bs,const char * id_or_name)624a89d89d3SWenchao Xia static int find_snapshot_by_id_or_name(BlockDriverState *bs,
625a89d89d3SWenchao Xia const char *id_or_name)
626c142442bSKevin Wolf {
627a89d89d3SWenchao Xia int ret;
628c142442bSKevin Wolf
629a89d89d3SWenchao Xia ret = find_snapshot_by_id_and_name(bs, id_or_name, NULL);
630a89d89d3SWenchao Xia if (ret >= 0) {
631c142442bSKevin Wolf return ret;
632c142442bSKevin Wolf }
633a89d89d3SWenchao Xia return find_snapshot_by_id_and_name(bs, NULL, id_or_name);
634c142442bSKevin Wolf }
635c142442bSKevin Wolf
636c142442bSKevin Wolf /* if no id is provided, a new one is constructed */
qcow2_snapshot_create(BlockDriverState * bs,QEMUSnapshotInfo * sn_info)637ed6ccf0fSKevin Wolf int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
638c142442bSKevin Wolf {
639ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
640d1ea98d5SKevin Wolf QCowSnapshot *new_snapshot_list = NULL;
641d1ea98d5SKevin Wolf QCowSnapshot *old_snapshot_list = NULL;
642d1ea98d5SKevin Wolf QCowSnapshot sn1, *sn = &sn1;
643c142442bSKevin Wolf int i, ret;
644c142442bSKevin Wolf uint64_t *l1_table = NULL;
6455d757b56SKevin Wolf int64_t l1_table_offset;
646c142442bSKevin Wolf
647ce48f2f4SKevin Wolf if (s->nb_snapshots >= QCOW_MAX_SNAPSHOTS) {
648ce48f2f4SKevin Wolf return -EFBIG;
649ce48f2f4SKevin Wolf }
650ce48f2f4SKevin Wolf
651aa8b34c1SKevin Wolf if (has_data_file(bs)) {
652aa8b34c1SKevin Wolf return -ENOTSUP;
653aa8b34c1SKevin Wolf }
654aa8b34c1SKevin Wolf
655c142442bSKevin Wolf memset(sn, 0, sizeof(*sn));
656c142442bSKevin Wolf
657407bc150SYi Wang /* Generate an ID */
658c142442bSKevin Wolf find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str));
659c142442bSKevin Wolf
66003343166SKevin Wolf /* Populate sn with passed data */
6617267c094SAnthony Liguori sn->id_str = g_strdup(sn_info->id_str);
6627267c094SAnthony Liguori sn->name = g_strdup(sn_info->name);
66303343166SKevin Wolf
66490b27759SKevin Wolf sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
665c142442bSKevin Wolf sn->vm_state_size = sn_info->vm_state_size;
666c142442bSKevin Wolf sn->date_sec = sn_info->date_sec;
667c142442bSKevin Wolf sn->date_nsec = sn_info->date_nsec;
668c142442bSKevin Wolf sn->vm_clock_nsec = sn_info->vm_clock_nsec;
669b39847a5SPavel Dovgalyuk sn->icount = sn_info->icount;
670fcf9a6b7SMax Reitz sn->extra_data_size = sizeof(QCowSnapshotExtraData);
671c142442bSKevin Wolf
67203343166SKevin Wolf /* Allocate the L1 table of the snapshot and copy the current one there. */
67302b1ecfaSAlberto Garcia l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * L1E_SIZE);
6745d757b56SKevin Wolf if (l1_table_offset < 0) {
675d1ea98d5SKevin Wolf ret = l1_table_offset;
6765d757b56SKevin Wolf goto fail;
6775d757b56SKevin Wolf }
6785d757b56SKevin Wolf
6795d757b56SKevin Wolf sn->l1_table_offset = l1_table_offset;
680c142442bSKevin Wolf sn->l1_size = s->l1_size;
681c142442bSKevin Wolf
6825839e53bSMarkus Armbruster l1_table = g_try_new(uint64_t, s->l1_size);
683de82815dSKevin Wolf if (s->l1_size && l1_table == NULL) {
684de82815dSKevin Wolf ret = -ENOMEM;
685de82815dSKevin Wolf goto fail;
686de82815dSKevin Wolf }
687de82815dSKevin Wolf
688c142442bSKevin Wolf for(i = 0; i < s->l1_size; i++) {
689c142442bSKevin Wolf l1_table[i] = cpu_to_be64(s->l1_table[i]);
690c142442bSKevin Wolf }
691d1ea98d5SKevin Wolf
692231bb267SMax Reitz ret = qcow2_pre_write_overlap_check(bs, 0, sn->l1_table_offset,
69302b1ecfaSAlberto Garcia s->l1_size * L1E_SIZE, false);
694cf93980eSMax Reitz if (ret < 0) {
695cf93980eSMax Reitz goto fail;
696cf93980eSMax Reitz }
697cf93980eSMax Reitz
69832cc71deSAlberto Faria ret = bdrv_pwrite(bs->file, sn->l1_table_offset, s->l1_size * L1E_SIZE,
69932cc71deSAlberto Faria l1_table, 0);
700d1ea98d5SKevin Wolf if (ret < 0) {
701c142442bSKevin Wolf goto fail;
702d1ea98d5SKevin Wolf }
703d1ea98d5SKevin Wolf
7047267c094SAnthony Liguori g_free(l1_table);
705c142442bSKevin Wolf l1_table = NULL;
706c142442bSKevin Wolf
707d1ea98d5SKevin Wolf /*
708d1ea98d5SKevin Wolf * Increase the refcounts of all clusters and make sure everything is
709d1ea98d5SKevin Wolf * stable on disk before updating the snapshot table to contain a pointer
710d1ea98d5SKevin Wolf * to the new L1 table.
711d1ea98d5SKevin Wolf */
712d1ea98d5SKevin Wolf ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1);
713d1ea98d5SKevin Wolf if (ret < 0) {
714d1ea98d5SKevin Wolf goto fail;
715c142442bSKevin Wolf }
716d1ea98d5SKevin Wolf
717d1ea98d5SKevin Wolf /* Append the new snapshot to the snapshot list */
7185839e53bSMarkus Armbruster new_snapshot_list = g_new(QCowSnapshot, s->nb_snapshots + 1);
719d1ea98d5SKevin Wolf if (s->snapshots) {
720d1ea98d5SKevin Wolf memcpy(new_snapshot_list, s->snapshots,
721d1ea98d5SKevin Wolf s->nb_snapshots * sizeof(QCowSnapshot));
722d1ea98d5SKevin Wolf old_snapshot_list = s->snapshots;
723d1ea98d5SKevin Wolf }
724d1ea98d5SKevin Wolf s->snapshots = new_snapshot_list;
725c142442bSKevin Wolf s->snapshots[s->nb_snapshots++] = *sn;
726c142442bSKevin Wolf
727d1ea98d5SKevin Wolf ret = qcow2_write_snapshots(bs);
728d1ea98d5SKevin Wolf if (ret < 0) {
729d1ea98d5SKevin Wolf g_free(s->snapshots);
730d1ea98d5SKevin Wolf s->snapshots = old_snapshot_list;
73184757f7eSMax Reitz s->nb_snapshots--;
732c142442bSKevin Wolf goto fail;
733d1ea98d5SKevin Wolf }
734d1ea98d5SKevin Wolf
735d1ea98d5SKevin Wolf g_free(old_snapshot_list);
736d1ea98d5SKevin Wolf
7371ebf561cSKevin Wolf /* The VM state isn't needed any more in the active L1 table; in fact, it
7381ebf561cSKevin Wolf * hurts by causing expensive COW for the next snapshot. */
739d2cb36afSEric Blake qcow2_cluster_discard(bs, qcow2_vm_state_offset(s),
7409e029689SAlberto Garcia ROUND_UP(sn->vm_state_size, s->cluster_size),
741808c4b6fSMax Reitz QCOW2_DISCARD_NEVER, false);
7421ebf561cSKevin Wolf
743c142442bSKevin Wolf #ifdef DEBUG_ALLOC
7446cbc3031SPhilipp Hahn {
7456cbc3031SPhilipp Hahn BdrvCheckResult result = {0};
746b35278f7SStefan Hajnoczi qcow2_check_refcounts(bs, &result, 0);
7476cbc3031SPhilipp Hahn }
748c142442bSKevin Wolf #endif
749c142442bSKevin Wolf return 0;
75003343166SKevin Wolf
751c142442bSKevin Wolf fail:
75203343166SKevin Wolf g_free(sn->id_str);
7537267c094SAnthony Liguori g_free(sn->name);
7547267c094SAnthony Liguori g_free(l1_table);
755d1ea98d5SKevin Wolf
756d1ea98d5SKevin Wolf return ret;
757c142442bSKevin Wolf }
758c142442bSKevin Wolf
759c142442bSKevin Wolf /* copy the snapshot 'snapshot_name' into the current disk image */
qcow2_snapshot_goto(BlockDriverState * bs,const char * snapshot_id)760ed6ccf0fSKevin Wolf int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
761c142442bSKevin Wolf {
762ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
763c142442bSKevin Wolf QCowSnapshot *sn;
764a8475d75SAlberto Garcia Error *local_err = NULL;
76535d7ace7SKevin Wolf int i, snapshot_index;
76635d7ace7SKevin Wolf int cur_l1_bytes, sn_l1_bytes;
767589f284bSKevin Wolf int ret;
76843a0cac4SKevin Wolf uint64_t *sn_l1_table = NULL;
769c142442bSKevin Wolf
770aa8b34c1SKevin Wolf if (has_data_file(bs)) {
771aa8b34c1SKevin Wolf return -ENOTSUP;
772aa8b34c1SKevin Wolf }
773aa8b34c1SKevin Wolf
774589f284bSKevin Wolf /* Search the snapshot */
775c142442bSKevin Wolf snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
776589f284bSKevin Wolf if (snapshot_index < 0) {
777c142442bSKevin Wolf return -ENOENT;
778589f284bSKevin Wolf }
779c142442bSKevin Wolf sn = &s->snapshots[snapshot_index];
780c142442bSKevin Wolf
781a8475d75SAlberto Garcia ret = qcow2_validate_table(bs, sn->l1_table_offset, sn->l1_size,
78202b1ecfaSAlberto Garcia L1E_SIZE, QCOW_MAX_L1_SIZE,
783a8475d75SAlberto Garcia "Snapshot L1 table", &local_err);
784a8475d75SAlberto Garcia if (ret < 0) {
785a8475d75SAlberto Garcia error_report_err(local_err);
786a8475d75SAlberto Garcia goto fail;
787a8475d75SAlberto Garcia }
788a8475d75SAlberto Garcia
78990b27759SKevin Wolf if (sn->disk_size != bs->total_sectors * BDRV_SECTOR_SIZE) {
7907fa140abSEric Blake BlockBackend *blk = blk_new_with_bs(bs, BLK_PERM_RESIZE, BLK_PERM_ALL,
7917fa140abSEric Blake &local_err);
7927fa140abSEric Blake if (!blk) {
7937fa140abSEric Blake error_report_err(local_err);
79490b27759SKevin Wolf ret = -ENOTSUP;
79590b27759SKevin Wolf goto fail;
79690b27759SKevin Wolf }
79790b27759SKevin Wolf
7987fa140abSEric Blake ret = blk_truncate(blk, sn->disk_size, true, PREALLOC_MODE_OFF, 0,
7997fa140abSEric Blake &local_err);
8007fa140abSEric Blake blk_unref(blk);
8017fa140abSEric Blake if (ret < 0) {
8027fa140abSEric Blake error_report_err(local_err);
8037fa140abSEric Blake goto fail;
8047fa140abSEric Blake }
8057fa140abSEric Blake }
8067fa140abSEric Blake
807589f284bSKevin Wolf /*
808589f284bSKevin Wolf * Make sure that the current L1 table is big enough to contain the whole
809589f284bSKevin Wolf * L1 table of the snapshot. If the snapshot L1 table is smaller, the
810589f284bSKevin Wolf * current one must be padded with zeros.
811589f284bSKevin Wolf */
812589f284bSKevin Wolf ret = qcow2_grow_l1_table(bs, sn->l1_size, true);
813589f284bSKevin Wolf if (ret < 0) {
814c142442bSKevin Wolf goto fail;
815589f284bSKevin Wolf }
816c142442bSKevin Wolf
81702b1ecfaSAlberto Garcia cur_l1_bytes = s->l1_size * L1E_SIZE;
81802b1ecfaSAlberto Garcia sn_l1_bytes = sn->l1_size * L1E_SIZE;
81935d7ace7SKevin Wolf
820589f284bSKevin Wolf /*
821589f284bSKevin Wolf * Copy the snapshot L1 table to the current L1 table.
822589f284bSKevin Wolf *
823589f284bSKevin Wolf * Before overwriting the old current L1 table on disk, make sure to
824589f284bSKevin Wolf * increase all refcounts for the clusters referenced by the new one.
82543a0cac4SKevin Wolf * Decrease the refcount referenced by the old one only when the L1
82643a0cac4SKevin Wolf * table is overwritten.
827589f284bSKevin Wolf */
828de82815dSKevin Wolf sn_l1_table = g_try_malloc0(cur_l1_bytes);
829de82815dSKevin Wolf if (cur_l1_bytes && sn_l1_table == NULL) {
830de82815dSKevin Wolf ret = -ENOMEM;
831de82815dSKevin Wolf goto fail;
832de82815dSKevin Wolf }
83343a0cac4SKevin Wolf
83432cc71deSAlberto Faria ret = bdrv_pread(bs->file, sn->l1_table_offset, sn_l1_bytes, sn_l1_table,
83553fb7844SAlberto Faria 0);
836589f284bSKevin Wolf if (ret < 0) {
837c142442bSKevin Wolf goto fail;
838589f284bSKevin Wolf }
839589f284bSKevin Wolf
84043a0cac4SKevin Wolf ret = qcow2_update_snapshot_refcount(bs, sn->l1_table_offset,
84143a0cac4SKevin Wolf sn->l1_size, 1);
84243a0cac4SKevin Wolf if (ret < 0) {
84343a0cac4SKevin Wolf goto fail;
84443a0cac4SKevin Wolf }
84543a0cac4SKevin Wolf
846231bb267SMax Reitz ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1,
847966b000fSKevin Wolf s->l1_table_offset, cur_l1_bytes,
848966b000fSKevin Wolf false);
849cf93980eSMax Reitz if (ret < 0) {
850cf93980eSMax Reitz goto fail;
851cf93980eSMax Reitz }
852cf93980eSMax Reitz
85332cc71deSAlberto Faria ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset, cur_l1_bytes,
85432cc71deSAlberto Faria sn_l1_table, 0);
855589f284bSKevin Wolf if (ret < 0) {
856c142442bSKevin Wolf goto fail;
857589f284bSKevin Wolf }
858589f284bSKevin Wolf
85943a0cac4SKevin Wolf /*
86043a0cac4SKevin Wolf * Decrease refcount of clusters of current L1 table.
86143a0cac4SKevin Wolf *
86243a0cac4SKevin Wolf * At this point, the in-memory s->l1_table points to the old L1 table,
86343a0cac4SKevin Wolf * whereas on disk we already have the new one.
86443a0cac4SKevin Wolf *
86543a0cac4SKevin Wolf * qcow2_update_snapshot_refcount special cases the current L1 table to use
86643a0cac4SKevin Wolf * the in-memory data instead of really using the offset to load a new one,
86743a0cac4SKevin Wolf * which is why this works.
86843a0cac4SKevin Wolf */
86943a0cac4SKevin Wolf ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset,
87043a0cac4SKevin Wolf s->l1_size, -1);
87143a0cac4SKevin Wolf
87243a0cac4SKevin Wolf /*
87343a0cac4SKevin Wolf * Now update the in-memory L1 table to be in sync with the on-disk one. We
87443a0cac4SKevin Wolf * need to do this even if updating refcounts failed.
87543a0cac4SKevin Wolf */
876c142442bSKevin Wolf for(i = 0;i < s->l1_size; i++) {
87743a0cac4SKevin Wolf s->l1_table[i] = be64_to_cpu(sn_l1_table[i]);
878c142442bSKevin Wolf }
879c142442bSKevin Wolf
88043a0cac4SKevin Wolf if (ret < 0) {
88143a0cac4SKevin Wolf goto fail;
88243a0cac4SKevin Wolf }
88343a0cac4SKevin Wolf
88443a0cac4SKevin Wolf g_free(sn_l1_table);
88543a0cac4SKevin Wolf sn_l1_table = NULL;
88643a0cac4SKevin Wolf
88743a0cac4SKevin Wolf /*
88843a0cac4SKevin Wolf * Update QCOW_OFLAG_COPIED in the active L1 table (it may have changed
88943a0cac4SKevin Wolf * when we decreased the refcount of the old snapshot.
89043a0cac4SKevin Wolf */
89143a0cac4SKevin Wolf ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
892589f284bSKevin Wolf if (ret < 0) {
893c142442bSKevin Wolf goto fail;
894589f284bSKevin Wolf }
895c142442bSKevin Wolf
896c142442bSKevin Wolf #ifdef DEBUG_ALLOC
8976cbc3031SPhilipp Hahn {
8986cbc3031SPhilipp Hahn BdrvCheckResult result = {0};
899b35278f7SStefan Hajnoczi qcow2_check_refcounts(bs, &result, 0);
9006cbc3031SPhilipp Hahn }
901c142442bSKevin Wolf #endif
902c142442bSKevin Wolf return 0;
903589f284bSKevin Wolf
904c142442bSKevin Wolf fail:
90543a0cac4SKevin Wolf g_free(sn_l1_table);
906589f284bSKevin Wolf return ret;
907c142442bSKevin Wolf }
908c142442bSKevin Wolf
qcow2_snapshot_delete(BlockDriverState * bs,const char * snapshot_id,const char * name,Error ** errp)909a89d89d3SWenchao Xia int qcow2_snapshot_delete(BlockDriverState *bs,
910a89d89d3SWenchao Xia const char *snapshot_id,
911a89d89d3SWenchao Xia const char *name,
912a89d89d3SWenchao Xia Error **errp)
913c142442bSKevin Wolf {
914ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
9159a476780SKevin Wolf QCowSnapshot sn;
916c142442bSKevin Wolf int snapshot_index, ret;
917c142442bSKevin Wolf
918aa8b34c1SKevin Wolf if (has_data_file(bs)) {
919aa8b34c1SKevin Wolf return -ENOTSUP;
920aa8b34c1SKevin Wolf }
921aa8b34c1SKevin Wolf
9229a476780SKevin Wolf /* Search the snapshot */
923a89d89d3SWenchao Xia snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);
9249a476780SKevin Wolf if (snapshot_index < 0) {
925a89d89d3SWenchao Xia error_setg(errp, "Can't find the snapshot");
926c142442bSKevin Wolf return -ENOENT;
9279a476780SKevin Wolf }
9289a476780SKevin Wolf sn = s->snapshots[snapshot_index];
929c142442bSKevin Wolf
930db5794f1SAlberto Garcia ret = qcow2_validate_table(bs, sn.l1_table_offset, sn.l1_size,
93102b1ecfaSAlberto Garcia L1E_SIZE, QCOW_MAX_L1_SIZE,
932db5794f1SAlberto Garcia "Snapshot L1 table", errp);
933db5794f1SAlberto Garcia if (ret < 0) {
934db5794f1SAlberto Garcia return ret;
935db5794f1SAlberto Garcia }
936db5794f1SAlberto Garcia
9379a476780SKevin Wolf /* Remove it from the snapshot list */
9389a476780SKevin Wolf memmove(s->snapshots + snapshot_index,
9399a476780SKevin Wolf s->snapshots + snapshot_index + 1,
9409a476780SKevin Wolf (s->nb_snapshots - snapshot_index - 1) * sizeof(sn));
941c142442bSKevin Wolf s->nb_snapshots--;
9427c80ab3fSJes Sorensen ret = qcow2_write_snapshots(bs);
943c142442bSKevin Wolf if (ret < 0) {
94439a611a3SJeff Cody error_setg_errno(errp, -ret,
94539a611a3SJeff Cody "Failed to remove snapshot from snapshot list");
946c142442bSKevin Wolf return ret;
947c142442bSKevin Wolf }
9489a476780SKevin Wolf
9499a476780SKevin Wolf /*
9509a476780SKevin Wolf * The snapshot is now unused, clean up. If we fail after this point, we
9519a476780SKevin Wolf * won't recover but just leak clusters.
9529a476780SKevin Wolf */
953fcf9a6b7SMax Reitz g_free(sn.unknown_extra_data);
9549a476780SKevin Wolf g_free(sn.id_str);
9559a476780SKevin Wolf g_free(sn.name);
9569a476780SKevin Wolf
9579a476780SKevin Wolf /*
9589a476780SKevin Wolf * Now decrease the refcounts of clusters referenced by the snapshot and
9599a476780SKevin Wolf * free the L1 table.
9609a476780SKevin Wolf */
9619a476780SKevin Wolf ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset,
9629a476780SKevin Wolf sn.l1_size, -1);
9639a476780SKevin Wolf if (ret < 0) {
96439a611a3SJeff Cody error_setg_errno(errp, -ret, "Failed to free the cluster and L1 table");
9659a476780SKevin Wolf return ret;
9669a476780SKevin Wolf }
96702b1ecfaSAlberto Garcia qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * L1E_SIZE,
9686cfcb9b8SKevin Wolf QCOW2_DISCARD_SNAPSHOT);
9699a476780SKevin Wolf
9709a476780SKevin Wolf /* must update the copied flag on the current cluster offsets */
9719a476780SKevin Wolf ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
9729a476780SKevin Wolf if (ret < 0) {
97339a611a3SJeff Cody error_setg_errno(errp, -ret,
97439a611a3SJeff Cody "Failed to update snapshot status in disk");
9759a476780SKevin Wolf return ret;
9769a476780SKevin Wolf }
9779a476780SKevin Wolf
978c142442bSKevin Wolf #ifdef DEBUG_ALLOC
9796cbc3031SPhilipp Hahn {
9806cbc3031SPhilipp Hahn BdrvCheckResult result = {0};
981b35278f7SStefan Hajnoczi qcow2_check_refcounts(bs, &result, 0);
9826cbc3031SPhilipp Hahn }
983c142442bSKevin Wolf #endif
984c142442bSKevin Wolf return 0;
985c142442bSKevin Wolf }
986c142442bSKevin Wolf
qcow2_snapshot_list(BlockDriverState * bs,QEMUSnapshotInfo ** psn_tab)987ed6ccf0fSKevin Wolf int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
988c142442bSKevin Wolf {
989ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
990c142442bSKevin Wolf QEMUSnapshotInfo *sn_tab, *sn_info;
991c142442bSKevin Wolf QCowSnapshot *sn;
992c142442bSKevin Wolf int i;
993c142442bSKevin Wolf
994aa8b34c1SKevin Wolf if (has_data_file(bs)) {
995aa8b34c1SKevin Wolf return -ENOTSUP;
996aa8b34c1SKevin Wolf }
997c142442bSKevin Wolf if (!s->nb_snapshots) {
998c142442bSKevin Wolf *psn_tab = NULL;
999c142442bSKevin Wolf return s->nb_snapshots;
1000c142442bSKevin Wolf }
1001c142442bSKevin Wolf
10025839e53bSMarkus Armbruster sn_tab = g_new0(QEMUSnapshotInfo, s->nb_snapshots);
1003c142442bSKevin Wolf for(i = 0; i < s->nb_snapshots; i++) {
1004c142442bSKevin Wolf sn_info = sn_tab + i;
1005c142442bSKevin Wolf sn = s->snapshots + i;
1006c142442bSKevin Wolf pstrcpy(sn_info->id_str, sizeof(sn_info->id_str),
1007c142442bSKevin Wolf sn->id_str);
1008c142442bSKevin Wolf pstrcpy(sn_info->name, sizeof(sn_info->name),
1009c142442bSKevin Wolf sn->name);
1010c142442bSKevin Wolf sn_info->vm_state_size = sn->vm_state_size;
1011c142442bSKevin Wolf sn_info->date_sec = sn->date_sec;
1012c142442bSKevin Wolf sn_info->date_nsec = sn->date_nsec;
1013c142442bSKevin Wolf sn_info->vm_clock_nsec = sn->vm_clock_nsec;
1014b39847a5SPavel Dovgalyuk sn_info->icount = sn->icount;
1015c142442bSKevin Wolf }
1016c142442bSKevin Wolf *psn_tab = sn_tab;
1017c142442bSKevin Wolf return s->nb_snapshots;
1018c142442bSKevin Wolf }
1019c142442bSKevin Wolf
qcow2_snapshot_load_tmp(BlockDriverState * bs,const char * snapshot_id,const char * name,Error ** errp)10207b4c4781SWenchao Xia int qcow2_snapshot_load_tmp(BlockDriverState *bs,
10217b4c4781SWenchao Xia const char *snapshot_id,
10227b4c4781SWenchao Xia const char *name,
10237b4c4781SWenchao Xia Error **errp)
102451ef6727Sedison {
1025e3f652b3SKevin Wolf int i, snapshot_index;
1026ff99129aSKevin Wolf BDRVQcow2State *s = bs->opaque;
102751ef6727Sedison QCowSnapshot *sn;
1028e3f652b3SKevin Wolf uint64_t *new_l1_table;
1029e3f652b3SKevin Wolf int new_l1_bytes;
1030e3f652b3SKevin Wolf int ret;
103151ef6727Sedison
1032307261b2SVladimir Sementsov-Ogievskiy assert(bdrv_is_read_only(bs));
1033e3f652b3SKevin Wolf
1034e3f652b3SKevin Wolf /* Search the snapshot */
10357b4c4781SWenchao Xia snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);
103651ef6727Sedison if (snapshot_index < 0) {
10377b4c4781SWenchao Xia error_setg(errp,
10387b4c4781SWenchao Xia "Can't find snapshot");
103951ef6727Sedison return -ENOENT;
104051ef6727Sedison }
104151ef6727Sedison sn = &s->snapshots[snapshot_index];
1042e3f652b3SKevin Wolf
1043e3f652b3SKevin Wolf /* Allocate and read in the snapshot's L1 table */
1044314e8d39SAlberto Garcia ret = qcow2_validate_table(bs, sn->l1_table_offset, sn->l1_size,
104502b1ecfaSAlberto Garcia L1E_SIZE, QCOW_MAX_L1_SIZE,
1046314e8d39SAlberto Garcia "Snapshot L1 table", errp);
1047314e8d39SAlberto Garcia if (ret < 0) {
1048314e8d39SAlberto Garcia return ret;
10496a83f8b5SKevin Wolf }
105002b1ecfaSAlberto Garcia new_l1_bytes = sn->l1_size * L1E_SIZE;
1051ef97d608SAlberto Garcia new_l1_table = qemu_try_blockalign(bs->file->bs, new_l1_bytes);
1052de82815dSKevin Wolf if (new_l1_table == NULL) {
1053de82815dSKevin Wolf return -ENOMEM;
1054de82815dSKevin Wolf }
1055e3f652b3SKevin Wolf
105632cc71deSAlberto Faria ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_bytes,
105732cc71deSAlberto Faria new_l1_table, 0);
1058e3f652b3SKevin Wolf if (ret < 0) {
10597b4c4781SWenchao Xia error_setg(errp, "Failed to read l1 table for snapshot");
1060de82815dSKevin Wolf qemu_vfree(new_l1_table);
1061e3f652b3SKevin Wolf return ret;
1062e3f652b3SKevin Wolf }
1063e3f652b3SKevin Wolf
1064e3f652b3SKevin Wolf /* Switch the L1 table */
1065de82815dSKevin Wolf qemu_vfree(s->l1_table);
106651ef6727Sedison
1067e3f652b3SKevin Wolf s->l1_size = sn->l1_size;
106851ef6727Sedison s->l1_table_offset = sn->l1_table_offset;
1069e3f652b3SKevin Wolf s->l1_table = new_l1_table;
107051ef6727Sedison
107151ef6727Sedison for(i = 0;i < s->l1_size; i++) {
107251ef6727Sedison be64_to_cpus(&s->l1_table[i]);
107351ef6727Sedison }
1074e3f652b3SKevin Wolf
107551ef6727Sedison return 0;
107651ef6727Sedison }
1077