1f7d0fe02SKevin Wolf /*
2f7d0fe02SKevin Wolf * Block driver for the QCOW version 2 format
3f7d0fe02SKevin Wolf *
4f7d0fe02SKevin Wolf * Copyright (c) 2004-2006 Fabrice Bellard
5f7d0fe02SKevin Wolf *
6f7d0fe02SKevin Wolf * Permission is hereby granted, free of charge, to any person obtaining a copy
7f7d0fe02SKevin Wolf * of this software and associated documentation files (the "Software"), to deal
8f7d0fe02SKevin Wolf * in the Software without restriction, including without limitation the rights
9f7d0fe02SKevin Wolf * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10f7d0fe02SKevin Wolf * copies of the Software, and to permit persons to whom the Software is
11f7d0fe02SKevin Wolf * furnished to do so, subject to the following conditions:
12f7d0fe02SKevin Wolf *
13f7d0fe02SKevin Wolf * The above copyright notice and this permission notice shall be included in
14f7d0fe02SKevin Wolf * all copies or substantial portions of the Software.
15f7d0fe02SKevin Wolf *
16f7d0fe02SKevin Wolf * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17f7d0fe02SKevin Wolf * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18f7d0fe02SKevin Wolf * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19f7d0fe02SKevin Wolf * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20f7d0fe02SKevin Wolf * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21f7d0fe02SKevin Wolf * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22f7d0fe02SKevin Wolf * THE SOFTWARE.
23f7d0fe02SKevin Wolf */
24f7d0fe02SKevin Wolf
25f7d0fe02SKevin Wolf #ifndef BLOCK_QCOW2_H
26f7d0fe02SKevin Wolf #define BLOCK_QCOW2_H
27f7d0fe02SKevin Wolf
28b25b387fSDaniel P. Berrange #include "crypto/block.h"
2910817bf0SDaniel P. Berrange #include "qemu/coroutine.h"
30b6a95c6dSLeonid Bloch #include "qemu/units.h"
319353db47SVladimir Sementsov-Ogievskiy #include "block/block_int.h"
32f7d0fe02SKevin Wolf
3314899cdfSFilip Navara //#define DEBUG_ALLOC
3414899cdfSFilip Navara //#define DEBUG_ALLOC2
3514899cdfSFilip Navara //#define DEBUG_EXT
3614899cdfSFilip Navara
37f7d0fe02SKevin Wolf #define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
38f7d0fe02SKevin Wolf
39f7d0fe02SKevin Wolf #define QCOW_CRYPT_NONE 0
40f7d0fe02SKevin Wolf #define QCOW_CRYPT_AES 1
414652b8f3SDaniel P. Berrange #define QCOW_CRYPT_LUKS 2
42f7d0fe02SKevin Wolf
43f7d0fe02SKevin Wolf #define QCOW_MAX_CRYPT_CLUSTERS 32
44ce48f2f4SKevin Wolf #define QCOW_MAX_SNAPSHOTS 65536
45f7d0fe02SKevin Wolf
4677d6a215SEric Blake /* Field widths in qcow2 mean normal cluster offsets cannot reach
4777d6a215SEric Blake * 64PB; depending on cluster size, compressed clusters can have a
4877d6a215SEric Blake * smaller limit (64PB for up to 16k clusters, then ramps down to
4977d6a215SEric Blake * 512TB for 2M clusters). */
5077d6a215SEric Blake #define QCOW_MAX_CLUSTER_OFFSET ((1ULL << 56) - 1)
5177d6a215SEric Blake
522b5d5953SKevin Wolf /* 8 MB refcount table is enough for 2 PB images at 64k cluster size
532b5d5953SKevin Wolf * (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
5414632122SMarkus Armbruster #define QCOW_MAX_REFTABLE_SIZE (8 * MiB)
552b5d5953SKevin Wolf
566a83f8b5SKevin Wolf /* 32 MB L1 table is enough for 2 PB images at 64k cluster size
576a83f8b5SKevin Wolf * (128 GB for 512 byte clusters, 2 EB for 2 MB clusters) */
5814632122SMarkus Armbruster #define QCOW_MAX_L1_SIZE (32 * MiB)
596a83f8b5SKevin Wolf
605dae6e30SKevin Wolf /* Allow for an average of 1k per snapshot table entry, should be plenty of
615dae6e30SKevin Wolf * space for snapshot names and IDs */
625dae6e30SKevin Wolf #define QCOW_MAX_SNAPSHOTS_SIZE (1024 * QCOW_MAX_SNAPSHOTS)
635dae6e30SKevin Wolf
64fcf9a6b7SMax Reitz /* Maximum amount of extra data per snapshot table entry to accept */
65fcf9a6b7SMax Reitz #define QCOW_MAX_SNAPSHOT_EXTRA_DATA 1024
66fcf9a6b7SMax Reitz
6788ddffaeSVladimir Sementsov-Ogievskiy /* Bitmap header extension constraints */
6888ddffaeSVladimir Sementsov-Ogievskiy #define QCOW2_MAX_BITMAPS 65535
6988ddffaeSVladimir Sementsov-Ogievskiy #define QCOW2_MAX_BITMAP_DIRECTORY_SIZE (1024 * QCOW2_MAX_BITMAPS)
7088ddffaeSVladimir Sementsov-Ogievskiy
71d710cf57SVladimir Sementsov-Ogievskiy /* Maximum of parallel sub-request per guest request */
72d710cf57SVladimir Sementsov-Ogievskiy #define QCOW2_MAX_WORKERS 8
73d710cf57SVladimir Sementsov-Ogievskiy
74f7d0fe02SKevin Wolf /* indicate that the refcount of the referenced cluster is exactly one. */
75127c84e1SPeter Maydell #define QCOW_OFLAG_COPIED (1ULL << 63)
76f7d0fe02SKevin Wolf /* indicate that the cluster is compressed (they never have the copied flag) */
77127c84e1SPeter Maydell #define QCOW_OFLAG_COMPRESSED (1ULL << 62)
786377af48SKevin Wolf /* The cluster reads as all zeros */
79127c84e1SPeter Maydell #define QCOW_OFLAG_ZERO (1ULL << 0)
80f7d0fe02SKevin Wolf
81d0346b55SAlberto Garcia #define QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER 32
82d0346b55SAlberto Garcia
8334905d8eSAlberto Garcia /* The subcluster X [0..31] is allocated */
8434905d8eSAlberto Garcia #define QCOW_OFLAG_SUB_ALLOC(X) (1ULL << (X))
8534905d8eSAlberto Garcia /* The subcluster X [0..31] reads as zeroes */
8634905d8eSAlberto Garcia #define QCOW_OFLAG_SUB_ZERO(X) (QCOW_OFLAG_SUB_ALLOC(X) << 32)
8734905d8eSAlberto Garcia /* Subclusters [X, Y) (0 <= X <= Y <= 32) are allocated */
8834905d8eSAlberto Garcia #define QCOW_OFLAG_SUB_ALLOC_RANGE(X, Y) \
8934905d8eSAlberto Garcia (QCOW_OFLAG_SUB_ALLOC(Y) - QCOW_OFLAG_SUB_ALLOC(X))
9034905d8eSAlberto Garcia /* Subclusters [X, Y) (0 <= X <= Y <= 32) read as zeroes */
9134905d8eSAlberto Garcia #define QCOW_OFLAG_SUB_ZERO_RANGE(X, Y) \
9234905d8eSAlberto Garcia (QCOW_OFLAG_SUB_ALLOC_RANGE(X, Y) << 32)
9334905d8eSAlberto Garcia /* L2 entry bitmap with all allocation bits set */
9434905d8eSAlberto Garcia #define QCOW_L2_BITMAP_ALL_ALLOC (QCOW_OFLAG_SUB_ALLOC_RANGE(0, 32))
9534905d8eSAlberto Garcia /* L2 entry bitmap with all "read as zeroes" bits set */
9634905d8eSAlberto Garcia #define QCOW_L2_BITMAP_ALL_ZEROES (QCOW_OFLAG_SUB_ZERO_RANGE(0, 32))
9734905d8eSAlberto Garcia
98c8fd8554SAlberto Garcia /* Size of normal and extended L2 entries */
99c8fd8554SAlberto Garcia #define L2E_SIZE_NORMAL (sizeof(uint64_t))
100c8fd8554SAlberto Garcia #define L2E_SIZE_EXTENDED (sizeof(uint64_t) * 2)
101c8fd8554SAlberto Garcia
10202b1ecfaSAlberto Garcia /* Size of L1 table entries */
10302b1ecfaSAlberto Garcia #define L1E_SIZE (sizeof(uint64_t))
10402b1ecfaSAlberto Garcia
10502b1ecfaSAlberto Garcia /* Size of reftable entries */
10602b1ecfaSAlberto Garcia #define REFTABLE_ENTRY_SIZE (sizeof(uint64_t))
10702b1ecfaSAlberto Garcia
108f7d0fe02SKevin Wolf #define MIN_CLUSTER_BITS 9
10980ee15a6SKevin Wolf #define MAX_CLUSTER_BITS 21
110f7d0fe02SKevin Wolf
111b6c24694SAlberto Garcia /* Defined in the qcow2 spec (compressed cluster descriptor) */
112b6c24694SAlberto Garcia #define QCOW2_COMPRESSED_SECTOR_SIZE 512U
113b6c24694SAlberto Garcia
11457e21669SMax Reitz /* Must be at least 2 to cover COW */
1151221fe6fSAlberto Garcia #define MIN_L2_CACHE_SIZE 2 /* cache entries */
116f7d0fe02SKevin Wolf
11729c1a730SKevin Wolf /* Must be at least 4 to cover all cases of refcount table growth */
118440ba08aSMax Reitz #define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */
119440ba08aSMax Reitz
12080668d0fSLeonid Bloch #ifdef CONFIG_LINUX
12114632122SMarkus Armbruster #define DEFAULT_L2_CACHE_MAX_SIZE (32 * MiB)
122e957b50bSLeonid Bloch #define DEFAULT_CACHE_CLEAN_INTERVAL 600 /* seconds */
12380668d0fSLeonid Bloch #else
12414632122SMarkus Armbruster #define DEFAULT_L2_CACHE_MAX_SIZE (8 * MiB)
125e957b50bSLeonid Bloch /* Cache clean interval is currently available only on Linux, so must be 0 */
126e957b50bSLeonid Bloch #define DEFAULT_CACHE_CLEAN_INTERVAL 0
12780668d0fSLeonid Bloch #endif
128440ba08aSMax Reitz
12914632122SMarkus Armbruster #define DEFAULT_CLUSTER_SIZE 65536
13099cce9faSKevin Wolf
1310e8c08beSKevin Wolf #define QCOW2_OPT_DATA_FILE "data-file"
13264aa99d3SKevin Wolf #define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts"
13364aa99d3SKevin Wolf #define QCOW2_OPT_DISCARD_REQUEST "pass-discard-request"
13464aa99d3SKevin Wolf #define QCOW2_OPT_DISCARD_SNAPSHOT "pass-discard-snapshot"
13564aa99d3SKevin Wolf #define QCOW2_OPT_DISCARD_OTHER "pass-discard-other"
13642a2890aSJean-Louis Dupond #define QCOW2_OPT_DISCARD_NO_UNREF "discard-no-unref"
13705de7e86SMax Reitz #define QCOW2_OPT_OVERLAP "overlap-check"
138ee42b5ceSMax Reitz #define QCOW2_OPT_OVERLAP_TEMPLATE "overlap-check.template"
13905de7e86SMax Reitz #define QCOW2_OPT_OVERLAP_MAIN_HEADER "overlap-check.main-header"
14005de7e86SMax Reitz #define QCOW2_OPT_OVERLAP_ACTIVE_L1 "overlap-check.active-l1"
14105de7e86SMax Reitz #define QCOW2_OPT_OVERLAP_ACTIVE_L2 "overlap-check.active-l2"
14205de7e86SMax Reitz #define QCOW2_OPT_OVERLAP_REFCOUNT_TABLE "overlap-check.refcount-table"
14305de7e86SMax Reitz #define QCOW2_OPT_OVERLAP_REFCOUNT_BLOCK "overlap-check.refcount-block"
14405de7e86SMax Reitz #define QCOW2_OPT_OVERLAP_SNAPSHOT_TABLE "overlap-check.snapshot-table"
14505de7e86SMax Reitz #define QCOW2_OPT_OVERLAP_INACTIVE_L1 "overlap-check.inactive-l1"
14605de7e86SMax Reitz #define QCOW2_OPT_OVERLAP_INACTIVE_L2 "overlap-check.inactive-l2"
1470e4e4318SVladimir Sementsov-Ogievskiy #define QCOW2_OPT_OVERLAP_BITMAP_DIRECTORY "overlap-check.bitmap-directory"
1486c1c8d5dSMax Reitz #define QCOW2_OPT_CACHE_SIZE "cache-size"
1496c1c8d5dSMax Reitz #define QCOW2_OPT_L2_CACHE_SIZE "l2-cache-size"
1501221fe6fSAlberto Garcia #define QCOW2_OPT_L2_CACHE_ENTRY_SIZE "l2-cache-entry-size"
1516c1c8d5dSMax Reitz #define QCOW2_OPT_REFCOUNT_CACHE_SIZE "refcount-cache-size"
152279621c0SAlberto Garcia #define QCOW2_OPT_CACHE_CLEAN_INTERVAL "cache-clean-interval"
153acdfb480SKevin Wolf
154f7d0fe02SKevin Wolf typedef struct QCowHeader {
155f7d0fe02SKevin Wolf uint32_t magic;
156f7d0fe02SKevin Wolf uint32_t version;
157f7d0fe02SKevin Wolf uint64_t backing_file_offset;
158f7d0fe02SKevin Wolf uint32_t backing_file_size;
159f7d0fe02SKevin Wolf uint32_t cluster_bits;
160f7d0fe02SKevin Wolf uint64_t size; /* in bytes */
161f7d0fe02SKevin Wolf uint32_t crypt_method;
162f7d0fe02SKevin Wolf uint32_t l1_size; /* XXX: save number of clusters instead ? */
163f7d0fe02SKevin Wolf uint64_t l1_table_offset;
164f7d0fe02SKevin Wolf uint64_t refcount_table_offset;
165f7d0fe02SKevin Wolf uint32_t refcount_table_clusters;
166f7d0fe02SKevin Wolf uint32_t nb_snapshots;
167f7d0fe02SKevin Wolf uint64_t snapshots_offset;
1686744cbabSKevin Wolf
1696744cbabSKevin Wolf /* The following fields are only valid for version >= 3 */
1706744cbabSKevin Wolf uint64_t incompatible_features;
1716744cbabSKevin Wolf uint64_t compatible_features;
1726744cbabSKevin Wolf uint64_t autoclear_features;
1736744cbabSKevin Wolf
1746744cbabSKevin Wolf uint32_t refcount_order;
1756744cbabSKevin Wolf uint32_t header_length;
176572ad978SDenis Plotnikov
177572ad978SDenis Plotnikov /* Additional fields */
178572ad978SDenis Plotnikov uint8_t compression_type;
179572ad978SDenis Plotnikov
180572ad978SDenis Plotnikov /* header must be a multiple of 8 */
181572ad978SDenis Plotnikov uint8_t padding[7];
182c4217f64SJeff Cody } QEMU_PACKED QCowHeader;
183f7d0fe02SKevin Wolf
184572ad978SDenis Plotnikov QEMU_BUILD_BUG_ON(!QEMU_IS_ALIGNED(sizeof(QCowHeader), 8));
185572ad978SDenis Plotnikov
186ce48f2f4SKevin Wolf typedef struct QEMU_PACKED QCowSnapshotHeader {
187ce48f2f4SKevin Wolf /* header is 8 byte aligned */
188ce48f2f4SKevin Wolf uint64_t l1_table_offset;
189ce48f2f4SKevin Wolf
190ce48f2f4SKevin Wolf uint32_t l1_size;
191ce48f2f4SKevin Wolf uint16_t id_str_size;
192ce48f2f4SKevin Wolf uint16_t name_size;
193ce48f2f4SKevin Wolf
194ce48f2f4SKevin Wolf uint32_t date_sec;
195ce48f2f4SKevin Wolf uint32_t date_nsec;
196ce48f2f4SKevin Wolf
197ce48f2f4SKevin Wolf uint64_t vm_clock_nsec;
198ce48f2f4SKevin Wolf
199ce48f2f4SKevin Wolf uint32_t vm_state_size;
200ce48f2f4SKevin Wolf uint32_t extra_data_size; /* for extension */
201ce48f2f4SKevin Wolf /* extra data follows */
202ce48f2f4SKevin Wolf /* id_str follows */
203ce48f2f4SKevin Wolf /* name follows */
204ce48f2f4SKevin Wolf } QCowSnapshotHeader;
205ce48f2f4SKevin Wolf
206ce48f2f4SKevin Wolf typedef struct QEMU_PACKED QCowSnapshotExtraData {
207ce48f2f4SKevin Wolf uint64_t vm_state_size_large;
208ce48f2f4SKevin Wolf uint64_t disk_size;
209bbacffc5SPavel Dovgalyuk uint64_t icount;
210ce48f2f4SKevin Wolf } QCowSnapshotExtraData;
211ce48f2f4SKevin Wolf
212ce48f2f4SKevin Wolf
213f7d0fe02SKevin Wolf typedef struct QCowSnapshot {
214f7d0fe02SKevin Wolf uint64_t l1_table_offset;
215f7d0fe02SKevin Wolf uint32_t l1_size;
216f7d0fe02SKevin Wolf char *id_str;
217f7d0fe02SKevin Wolf char *name;
21890b27759SKevin Wolf uint64_t disk_size;
219c2c9a466SKevin Wolf uint64_t vm_state_size;
220f7d0fe02SKevin Wolf uint32_t date_sec;
221f7d0fe02SKevin Wolf uint32_t date_nsec;
222f7d0fe02SKevin Wolf uint64_t vm_clock_nsec;
223bbacffc5SPavel Dovgalyuk /* icount value for the moment when snapshot was taken */
224bbacffc5SPavel Dovgalyuk uint64_t icount;
225fcf9a6b7SMax Reitz /* Size of all extra data, including QCowSnapshotExtraData if available */
226fcf9a6b7SMax Reitz uint32_t extra_data_size;
227fcf9a6b7SMax Reitz /* Data beyond QCowSnapshotExtraData, if any */
228fcf9a6b7SMax Reitz void *unknown_extra_data;
229f7d0fe02SKevin Wolf } QCowSnapshot;
230f7d0fe02SKevin Wolf
23149381094SKevin Wolf struct Qcow2Cache;
23249381094SKevin Wolf typedef struct Qcow2Cache Qcow2Cache;
23349381094SKevin Wolf
2344652b8f3SDaniel P. Berrange typedef struct Qcow2CryptoHeaderExtension {
2354652b8f3SDaniel P. Berrange uint64_t offset;
2364652b8f3SDaniel P. Berrange uint64_t length;
2374652b8f3SDaniel P. Berrange } QEMU_PACKED Qcow2CryptoHeaderExtension;
2384652b8f3SDaniel P. Berrange
23975bab85cSKevin Wolf typedef struct Qcow2UnknownHeaderExtension {
24075bab85cSKevin Wolf uint32_t magic;
24175bab85cSKevin Wolf uint32_t len;
24275bab85cSKevin Wolf QLIST_ENTRY(Qcow2UnknownHeaderExtension) next;
24375bab85cSKevin Wolf uint8_t data[];
24475bab85cSKevin Wolf } Qcow2UnknownHeaderExtension;
24575bab85cSKevin Wolf
246cfcc4c62SKevin Wolf enum {
247cfcc4c62SKevin Wolf QCOW2_FEAT_TYPE_INCOMPATIBLE = 0,
248cfcc4c62SKevin Wolf QCOW2_FEAT_TYPE_COMPATIBLE = 1,
249cfcc4c62SKevin Wolf QCOW2_FEAT_TYPE_AUTOCLEAR = 2,
250cfcc4c62SKevin Wolf };
251cfcc4c62SKevin Wolf
252c61d0004SStefan Hajnoczi /* Incompatible feature bits */
253c61d0004SStefan Hajnoczi enum {
254c61d0004SStefan Hajnoczi QCOW2_INCOMPAT_DIRTY_BITNR = 0,
25569c98726SMax Reitz QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
25693c24936SKevin Wolf QCOW2_INCOMPAT_DATA_FILE_BITNR = 2,
257572ad978SDenis Plotnikov QCOW2_INCOMPAT_COMPRESSION_BITNR = 3,
2587be20252SAlberto Garcia QCOW2_INCOMPAT_EXTL2_BITNR = 4,
259c61d0004SStefan Hajnoczi QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
26069c98726SMax Reitz QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
26193c24936SKevin Wolf QCOW2_INCOMPAT_DATA_FILE = 1 << QCOW2_INCOMPAT_DATA_FILE_BITNR,
262572ad978SDenis Plotnikov QCOW2_INCOMPAT_COMPRESSION = 1 << QCOW2_INCOMPAT_COMPRESSION_BITNR,
2637be20252SAlberto Garcia QCOW2_INCOMPAT_EXTL2 = 1 << QCOW2_INCOMPAT_EXTL2_BITNR,
264c61d0004SStefan Hajnoczi
26569c98726SMax Reitz QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
2660e8c08beSKevin Wolf | QCOW2_INCOMPAT_CORRUPT
267572ad978SDenis Plotnikov | QCOW2_INCOMPAT_DATA_FILE
2687be20252SAlberto Garcia | QCOW2_INCOMPAT_COMPRESSION
2697be20252SAlberto Garcia | QCOW2_INCOMPAT_EXTL2,
270c61d0004SStefan Hajnoczi };
271c61d0004SStefan Hajnoczi
272bfe8043eSStefan Hajnoczi /* Compatible feature bits */
273bfe8043eSStefan Hajnoczi enum {
274bfe8043eSStefan Hajnoczi QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR = 0,
275bfe8043eSStefan Hajnoczi QCOW2_COMPAT_LAZY_REFCOUNTS = 1 << QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
276bfe8043eSStefan Hajnoczi
277bfe8043eSStefan Hajnoczi QCOW2_COMPAT_FEAT_MASK = QCOW2_COMPAT_LAZY_REFCOUNTS,
278bfe8043eSStefan Hajnoczi };
279bfe8043eSStefan Hajnoczi
28088ddffaeSVladimir Sementsov-Ogievskiy /* Autoclear feature bits */
28188ddffaeSVladimir Sementsov-Ogievskiy enum {
28288ddffaeSVladimir Sementsov-Ogievskiy QCOW2_AUTOCLEAR_BITMAPS_BITNR = 0,
28393c24936SKevin Wolf QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR = 1,
28488ddffaeSVladimir Sementsov-Ogievskiy QCOW2_AUTOCLEAR_BITMAPS = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR,
28593c24936SKevin Wolf QCOW2_AUTOCLEAR_DATA_FILE_RAW = 1 << QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR,
28688ddffaeSVladimir Sementsov-Ogievskiy
2876c3944dcSKevin Wolf QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS
2886c3944dcSKevin Wolf | QCOW2_AUTOCLEAR_DATA_FILE_RAW,
28988ddffaeSVladimir Sementsov-Ogievskiy };
29088ddffaeSVladimir Sementsov-Ogievskiy
2916cfcb9b8SKevin Wolf enum qcow2_discard_type {
2926cfcb9b8SKevin Wolf QCOW2_DISCARD_NEVER = 0,
2936cfcb9b8SKevin Wolf QCOW2_DISCARD_ALWAYS,
2946cfcb9b8SKevin Wolf QCOW2_DISCARD_REQUEST,
2956cfcb9b8SKevin Wolf QCOW2_DISCARD_SNAPSHOT,
2966cfcb9b8SKevin Wolf QCOW2_DISCARD_OTHER,
2976cfcb9b8SKevin Wolf QCOW2_DISCARD_MAX
2986cfcb9b8SKevin Wolf };
2996cfcb9b8SKevin Wolf
300cfcc4c62SKevin Wolf typedef struct Qcow2Feature {
301cfcc4c62SKevin Wolf uint8_t type;
302cfcc4c62SKevin Wolf uint8_t bit;
303cfcc4c62SKevin Wolf char name[46];
304cfcc4c62SKevin Wolf } QEMU_PACKED Qcow2Feature;
305cfcc4c62SKevin Wolf
3060b919faeSKevin Wolf typedef struct Qcow2DiscardRegion {
3070b919faeSKevin Wolf BlockDriverState *bs;
3080b919faeSKevin Wolf uint64_t offset;
3090b919faeSKevin Wolf uint64_t bytes;
3100b919faeSKevin Wolf QTAILQ_ENTRY(Qcow2DiscardRegion) next;
3110b919faeSKevin Wolf } Qcow2DiscardRegion;
3120b919faeSKevin Wolf
3137453c96bSMax Reitz typedef uint64_t Qcow2GetRefcountFunc(const void *refcount_array,
3147453c96bSMax Reitz uint64_t index);
3157453c96bSMax Reitz typedef void Qcow2SetRefcountFunc(void *refcount_array,
3167453c96bSMax Reitz uint64_t index, uint64_t value);
3177453c96bSMax Reitz
31888ddffaeSVladimir Sementsov-Ogievskiy typedef struct Qcow2BitmapHeaderExt {
31988ddffaeSVladimir Sementsov-Ogievskiy uint32_t nb_bitmaps;
32088ddffaeSVladimir Sementsov-Ogievskiy uint32_t reserved32;
32188ddffaeSVladimir Sementsov-Ogievskiy uint64_t bitmap_directory_size;
32288ddffaeSVladimir Sementsov-Ogievskiy uint64_t bitmap_directory_offset;
32388ddffaeSVladimir Sementsov-Ogievskiy } QEMU_PACKED Qcow2BitmapHeaderExt;
32488ddffaeSVladimir Sementsov-Ogievskiy
3258ac0f15fSVladimir Sementsov-Ogievskiy #define QCOW2_MAX_THREADS 4
3268ac0f15fSVladimir Sementsov-Ogievskiy
327ff99129aSKevin Wolf typedef struct BDRVQcow2State {
328f7d0fe02SKevin Wolf int cluster_bits;
329f7d0fe02SKevin Wolf int cluster_size;
3303c2e511aSAlberto Garcia int l2_slice_size;
331d0346b55SAlberto Garcia int subcluster_bits;
332d0346b55SAlberto Garcia int subcluster_size;
333d0346b55SAlberto Garcia int subclusters_per_cluster;
334f7d0fe02SKevin Wolf int l2_bits;
335f7d0fe02SKevin Wolf int l2_size;
336f7d0fe02SKevin Wolf int l1_size;
337f7d0fe02SKevin Wolf int l1_vm_state_index;
3381d13d654SMax Reitz int refcount_block_bits;
3391d13d654SMax Reitz int refcount_block_size;
340f7d0fe02SKevin Wolf int csize_shift;
341f7d0fe02SKevin Wolf int csize_mask;
342f7d0fe02SKevin Wolf uint64_t cluster_offset_mask;
343f7d0fe02SKevin Wolf uint64_t l1_table_offset;
344f7d0fe02SKevin Wolf uint64_t *l1_table;
34529c1a730SKevin Wolf
34629c1a730SKevin Wolf Qcow2Cache *l2_table_cache;
34729c1a730SKevin Wolf Qcow2Cache *refcount_block_cache;
348279621c0SAlberto Garcia QEMUTimer *cache_clean_timer;
349279621c0SAlberto Garcia unsigned cache_clean_interval;
35029c1a730SKevin Wolf
351b58deb34SPaolo Bonzini QLIST_HEAD(, QCowL2Meta) cluster_allocs;
352f7d0fe02SKevin Wolf
353f7d0fe02SKevin Wolf uint64_t *refcount_table;
354f7d0fe02SKevin Wolf uint64_t refcount_table_offset;
355f7d0fe02SKevin Wolf uint32_t refcount_table_size;
3567061a078SAlberto Garcia uint32_t max_refcount_table_index; /* Last used entry in refcount_table */
357bb572aefSKevin Wolf uint64_t free_cluster_index;
358bb572aefSKevin Wolf uint64_t free_byte_offset;
359f7d0fe02SKevin Wolf
36068d100e9SKevin Wolf CoMutex lock;
36168d100e9SKevin Wolf
3624652b8f3SDaniel P. Berrange Qcow2CryptoHeaderExtension crypto_header; /* QCow2 header extension */
363b25b387fSDaniel P. Berrange QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */
364b25b387fSDaniel P. Berrange QCryptoBlock *crypto; /* Disk encryption format driver */
3654652b8f3SDaniel P. Berrange bool crypt_physical_offset; /* Whether to use virtual or physical offset
3664652b8f3SDaniel P. Berrange for encryption initialization vector tweak */
367f7d0fe02SKevin Wolf uint32_t crypt_method_header;
368f7d0fe02SKevin Wolf uint64_t snapshots_offset;
369f7d0fe02SKevin Wolf int snapshots_size;
370ce48f2f4SKevin Wolf unsigned int nb_snapshots;
371f7d0fe02SKevin Wolf QCowSnapshot *snapshots;
37206d9260fSAnthony Liguori
37388ddffaeSVladimir Sementsov-Ogievskiy uint32_t nb_bitmaps;
37488ddffaeSVladimir Sementsov-Ogievskiy uint64_t bitmap_directory_size;
37588ddffaeSVladimir Sementsov-Ogievskiy uint64_t bitmap_directory_offset;
37688ddffaeSVladimir Sementsov-Ogievskiy
37706d9260fSAnthony Liguori int flags;
3786744cbabSKevin Wolf int qcow_version;
37974c4510aSKevin Wolf bool use_lazy_refcounts;
380b6481f37SMax Reitz int refcount_order;
381346a53dfSMax Reitz int refcount_bits;
382346a53dfSMax Reitz uint64_t refcount_max;
3836744cbabSKevin Wolf
3847453c96bSMax Reitz Qcow2GetRefcountFunc *get_refcount;
3857453c96bSMax Reitz Qcow2SetRefcountFunc *set_refcount;
3867453c96bSMax Reitz
38767af674eSKevin Wolf bool discard_passthrough[QCOW2_DISCARD_MAX];
38867af674eSKevin Wolf
38942a2890aSJean-Louis Dupond bool discard_no_unref;
39042a2890aSJean-Louis Dupond
3913e355390SMax Reitz int overlap_check; /* bitmask of Qcow2MetadataOverlap values */
39285186ebdSMax Reitz bool signaled_corruption;
3933e355390SMax Reitz
3946744cbabSKevin Wolf uint64_t incompatible_features;
3956744cbabSKevin Wolf uint64_t compatible_features;
3966744cbabSKevin Wolf uint64_t autoclear_features;
3976744cbabSKevin Wolf
3986744cbabSKevin Wolf size_t unknown_header_fields_size;
3996744cbabSKevin Wolf void *unknown_header_fields;
40075bab85cSKevin Wolf QLIST_HEAD(, Qcow2UnknownHeaderExtension) unknown_header_ext;
4010b919faeSKevin Wolf QTAILQ_HEAD (, Qcow2DiscardRegion) discards;
4020b919faeSKevin Wolf bool cache_discards;
403e4603fe1SKevin Wolf
404e4603fe1SKevin Wolf /* Backing file path and format as stored in the image (this is not the
405e4603fe1SKevin Wolf * effective path/format, which may be the result of a runtime option
406e4603fe1SKevin Wolf * override) */
407e4603fe1SKevin Wolf char *image_backing_file;
408e4603fe1SKevin Wolf char *image_backing_format;
4099b890bdcSKevin Wolf char *image_data_file;
410ceb029cdSVladimir Sementsov-Ogievskiy
4116f13a316SVladimir Sementsov-Ogievskiy CoQueue thread_task_queue;
4126f13a316SVladimir Sementsov-Ogievskiy int nb_threads;
41393c24936SKevin Wolf
41493c24936SKevin Wolf BdrvChild *data_file;
41569f47505SVladimir Sementsov-Ogievskiy
41669f47505SVladimir Sementsov-Ogievskiy bool metadata_preallocation_checked;
41769f47505SVladimir Sementsov-Ogievskiy bool metadata_preallocation;
418572ad978SDenis Plotnikov /*
419572ad978SDenis Plotnikov * Compression type used for the image. Default: 0 - ZLIB
420572ad978SDenis Plotnikov * The image compression type is set on image creation.
421572ad978SDenis Plotnikov * For now, the only way to change the compression type
422572ad978SDenis Plotnikov * is to convert the image with the desired compression type set.
423572ad978SDenis Plotnikov */
424572ad978SDenis Plotnikov Qcow2CompressionType compression_type;
425ff99129aSKevin Wolf } BDRVQcow2State;
426f7d0fe02SKevin Wolf
427593fb83cSKevin Wolf typedef struct Qcow2COWRegion {
428593fb83cSKevin Wolf /**
429593fb83cSKevin Wolf * Offset of the COW region in bytes from the start of the first cluster
430593fb83cSKevin Wolf * touched by the request.
431593fb83cSKevin Wolf */
432e034f5bcSAlberto Garcia unsigned offset;
433593fb83cSKevin Wolf
43485567393SKevin Wolf /** Number of bytes to copy */
435e034f5bcSAlberto Garcia unsigned nb_bytes;
436593fb83cSKevin Wolf } Qcow2COWRegion;
437593fb83cSKevin Wolf
438f50f88b9SKevin Wolf /**
439f50f88b9SKevin Wolf * Describes an in-flight (part of a) write request that writes to clusters
4403441ad4bSAlberto Garcia * that need to have their L2 table entries updated (because they are
4413441ad4bSAlberto Garcia * newly allocated or need changes in their L2 bitmaps)
442f50f88b9SKevin Wolf */
44345aba42fSKevin Wolf typedef struct QCowL2Meta
44445aba42fSKevin Wolf {
4453441ad4bSAlberto Garcia /** Guest offset of the first updated cluster */
44645aba42fSKevin Wolf uint64_t offset;
4471d3afd64SKevin Wolf
4483441ad4bSAlberto Garcia /** Host offset of the first updated cluster */
449250196f1SKevin Wolf uint64_t alloc_offset;
4501d3afd64SKevin Wolf
4513441ad4bSAlberto Garcia /** Number of updated clusters */
45245aba42fSKevin Wolf int nb_clusters;
4531d3afd64SKevin Wolf
454564a6b69SMax Reitz /** Do not free the old clusters */
455564a6b69SMax Reitz bool keep_old_clusters;
456564a6b69SMax Reitz
4571d3afd64SKevin Wolf /**
4581d3afd64SKevin Wolf * Requests that overlap with this allocation and wait to be restarted
4591d3afd64SKevin Wolf * when the allocating request has completed.
4601d3afd64SKevin Wolf */
46168d100e9SKevin Wolf CoQueue dependent_requests;
462f214978aSKevin Wolf
463593fb83cSKevin Wolf /**
4643441ad4bSAlberto Garcia * The COW Region immediately before the area the guest actually
4653441ad4bSAlberto Garcia * writes to. This (part of the) write request starts at
4663441ad4bSAlberto Garcia * cow_start.offset + cow_start.nb_bytes.
467593fb83cSKevin Wolf */
468593fb83cSKevin Wolf Qcow2COWRegion cow_start;
469593fb83cSKevin Wolf
470593fb83cSKevin Wolf /**
4713441ad4bSAlberto Garcia * The COW Region immediately after the area the guest actually
4723441ad4bSAlberto Garcia * writes to. This (part of the) write request ends at cow_end.offset
4733441ad4bSAlberto Garcia * (which must always be set even when cow_end.nb_bytes is 0).
474593fb83cSKevin Wolf */
475593fb83cSKevin Wolf Qcow2COWRegion cow_end;
476593fb83cSKevin Wolf
477c8bb23cbSAnton Nefedov /*
478c8bb23cbSAnton Nefedov * Indicates that COW regions are already handled and do not require
479c8bb23cbSAnton Nefedov * any more processing.
480c8bb23cbSAnton Nefedov */
481c8bb23cbSAnton Nefedov bool skip_cow;
482c8bb23cbSAnton Nefedov
483ee22a9d8SAlberto Garcia /**
48440dee943SAlberto Garcia * Indicates that this is not a normal write request but a preallocation.
48540dee943SAlberto Garcia * If the image has extended L2 entries this means that no new individual
48640dee943SAlberto Garcia * subclusters will be marked as allocated in the L2 bitmap (but any
48740dee943SAlberto Garcia * existing contents of that bitmap will be kept).
48840dee943SAlberto Garcia */
48940dee943SAlberto Garcia bool prealloc;
49040dee943SAlberto Garcia
49140dee943SAlberto Garcia /**
492ee22a9d8SAlberto Garcia * The I/O vector with the data from the actual guest write request.
493ee22a9d8SAlberto Garcia * If non-NULL, this is meant to be merged together with the data
494ee22a9d8SAlberto Garcia * from @cow_start and @cow_end into one single write operation.
495ee22a9d8SAlberto Garcia */
496ee22a9d8SAlberto Garcia QEMUIOVector *data_qiov;
4975396234bSVladimir Sementsov-Ogievskiy size_t data_qiov_offset;
498ee22a9d8SAlberto Garcia
49988c6588cSKevin Wolf /** Pointer to next L2Meta of the same write request */
50088c6588cSKevin Wolf struct QCowL2Meta *next;
50188c6588cSKevin Wolf
50272cf2d4fSBlue Swirl QLIST_ENTRY(QCowL2Meta) next_in_flight;
50345aba42fSKevin Wolf } QCowL2Meta;
50445aba42fSKevin Wolf
50534905d8eSAlberto Garcia /*
50634905d8eSAlberto Garcia * In images with standard L2 entries all clusters are treated as if
50734905d8eSAlberto Garcia * they had one subcluster so QCow2ClusterType and QCow2SubclusterType
50834905d8eSAlberto Garcia * can be mapped to each other and have the exact same meaning
50934905d8eSAlberto Garcia * (QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC cannot happen in these images).
51034905d8eSAlberto Garcia *
51134905d8eSAlberto Garcia * In images with extended L2 entries QCow2ClusterType refers to the
51234905d8eSAlberto Garcia * complete cluster and QCow2SubclusterType to each of the individual
51334905d8eSAlberto Garcia * subclusters, so there are several possible combinations:
51434905d8eSAlberto Garcia *
51534905d8eSAlberto Garcia * |--------------+---------------------------|
51634905d8eSAlberto Garcia * | Cluster type | Possible subcluster types |
51734905d8eSAlberto Garcia * |--------------+---------------------------|
51834905d8eSAlberto Garcia * | UNALLOCATED | UNALLOCATED_PLAIN |
51934905d8eSAlberto Garcia * | | ZERO_PLAIN |
52034905d8eSAlberto Garcia * |--------------+---------------------------|
52134905d8eSAlberto Garcia * | NORMAL | UNALLOCATED_ALLOC |
52234905d8eSAlberto Garcia * | | ZERO_ALLOC |
52334905d8eSAlberto Garcia * | | NORMAL |
52434905d8eSAlberto Garcia * |--------------+---------------------------|
52534905d8eSAlberto Garcia * | COMPRESSED | COMPRESSED |
52634905d8eSAlberto Garcia * |--------------+---------------------------|
52734905d8eSAlberto Garcia *
52834905d8eSAlberto Garcia * QCOW2_SUBCLUSTER_INVALID means that the L2 entry is incorrect and
52934905d8eSAlberto Garcia * the image should be marked corrupt.
53034905d8eSAlberto Garcia */
53134905d8eSAlberto Garcia
5323ef95218SEric Blake typedef enum QCow2ClusterType {
53368d000a3SKevin Wolf QCOW2_CLUSTER_UNALLOCATED,
534fdfab37dSEric Blake QCOW2_CLUSTER_ZERO_PLAIN,
535fdfab37dSEric Blake QCOW2_CLUSTER_ZERO_ALLOC,
53668d000a3SKevin Wolf QCOW2_CLUSTER_NORMAL,
53768d000a3SKevin Wolf QCOW2_CLUSTER_COMPRESSED,
5383ef95218SEric Blake } QCow2ClusterType;
53968d000a3SKevin Wolf
54034905d8eSAlberto Garcia typedef enum QCow2SubclusterType {
54134905d8eSAlberto Garcia QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN,
54234905d8eSAlberto Garcia QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC,
54334905d8eSAlberto Garcia QCOW2_SUBCLUSTER_ZERO_PLAIN,
54434905d8eSAlberto Garcia QCOW2_SUBCLUSTER_ZERO_ALLOC,
54534905d8eSAlberto Garcia QCOW2_SUBCLUSTER_NORMAL,
54634905d8eSAlberto Garcia QCOW2_SUBCLUSTER_COMPRESSED,
54734905d8eSAlberto Garcia QCOW2_SUBCLUSTER_INVALID,
54834905d8eSAlberto Garcia } QCow2SubclusterType;
54934905d8eSAlberto Garcia
550a40f1c2aSMax Reitz typedef enum QCow2MetadataOverlap {
551a40f1c2aSMax Reitz QCOW2_OL_MAIN_HEADER_BITNR = 0,
552a40f1c2aSMax Reitz QCOW2_OL_ACTIVE_L1_BITNR = 1,
553a40f1c2aSMax Reitz QCOW2_OL_ACTIVE_L2_BITNR = 2,
554a40f1c2aSMax Reitz QCOW2_OL_REFCOUNT_TABLE_BITNR = 3,
555a40f1c2aSMax Reitz QCOW2_OL_REFCOUNT_BLOCK_BITNR = 4,
556a40f1c2aSMax Reitz QCOW2_OL_SNAPSHOT_TABLE_BITNR = 5,
557a40f1c2aSMax Reitz QCOW2_OL_INACTIVE_L1_BITNR = 6,
558a40f1c2aSMax Reitz QCOW2_OL_INACTIVE_L2_BITNR = 7,
5590e4e4318SVladimir Sementsov-Ogievskiy QCOW2_OL_BITMAP_DIRECTORY_BITNR = 8,
560a40f1c2aSMax Reitz
5610e4e4318SVladimir Sementsov-Ogievskiy QCOW2_OL_MAX_BITNR = 9,
562a40f1c2aSMax Reitz
563a40f1c2aSMax Reitz QCOW2_OL_NONE = 0,
564a40f1c2aSMax Reitz QCOW2_OL_MAIN_HEADER = (1 << QCOW2_OL_MAIN_HEADER_BITNR),
565a40f1c2aSMax Reitz QCOW2_OL_ACTIVE_L1 = (1 << QCOW2_OL_ACTIVE_L1_BITNR),
566a40f1c2aSMax Reitz QCOW2_OL_ACTIVE_L2 = (1 << QCOW2_OL_ACTIVE_L2_BITNR),
567a40f1c2aSMax Reitz QCOW2_OL_REFCOUNT_TABLE = (1 << QCOW2_OL_REFCOUNT_TABLE_BITNR),
568a40f1c2aSMax Reitz QCOW2_OL_REFCOUNT_BLOCK = (1 << QCOW2_OL_REFCOUNT_BLOCK_BITNR),
569a40f1c2aSMax Reitz QCOW2_OL_SNAPSHOT_TABLE = (1 << QCOW2_OL_SNAPSHOT_TABLE_BITNR),
570a40f1c2aSMax Reitz QCOW2_OL_INACTIVE_L1 = (1 << QCOW2_OL_INACTIVE_L1_BITNR),
571a40f1c2aSMax Reitz /* NOTE: Checking overlaps with inactive L2 tables will result in bdrv
572a40f1c2aSMax Reitz * reads. */
573a40f1c2aSMax Reitz QCOW2_OL_INACTIVE_L2 = (1 << QCOW2_OL_INACTIVE_L2_BITNR),
5740e4e4318SVladimir Sementsov-Ogievskiy QCOW2_OL_BITMAP_DIRECTORY = (1 << QCOW2_OL_BITMAP_DIRECTORY_BITNR),
575a40f1c2aSMax Reitz } QCow2MetadataOverlap;
576a40f1c2aSMax Reitz
5774a273c39SMax Reitz /* Perform all overlap checks which can be done in constant time */
5784a273c39SMax Reitz #define QCOW2_OL_CONSTANT \
5794a273c39SMax Reitz (QCOW2_OL_MAIN_HEADER | QCOW2_OL_ACTIVE_L1 | QCOW2_OL_REFCOUNT_TABLE | \
5800e4e4318SVladimir Sementsov-Ogievskiy QCOW2_OL_SNAPSHOT_TABLE | QCOW2_OL_BITMAP_DIRECTORY)
5814a273c39SMax Reitz
582a40f1c2aSMax Reitz /* Perform all overlap checks which don't require disk access */
583a40f1c2aSMax Reitz #define QCOW2_OL_CACHED \
5844a273c39SMax Reitz (QCOW2_OL_CONSTANT | QCOW2_OL_ACTIVE_L2 | QCOW2_OL_REFCOUNT_BLOCK | \
5854a273c39SMax Reitz QCOW2_OL_INACTIVE_L1)
5864a273c39SMax Reitz
5874a273c39SMax Reitz /* Perform all overlap checks */
5884a273c39SMax Reitz #define QCOW2_OL_ALL \
5894a273c39SMax Reitz (QCOW2_OL_CACHED | QCOW2_OL_INACTIVE_L2)
590a40f1c2aSMax Reitz
59146bae927SHu Tao #define L1E_OFFSET_MASK 0x00fffffffffffe00ULL
59298bc07d6SVladimir Sementsov-Ogievskiy #define L1E_RESERVED_MASK 0x7f000000000001ffULL
59346bae927SHu Tao #define L2E_OFFSET_MASK 0x00fffffffffffe00ULL
594289ef5f2SVladimir Sementsov-Ogievskiy #define L2E_STD_RESERVED_MASK 0x3f000000000001feULL
59568d000a3SKevin Wolf
59646bae927SHu Tao #define REFT_OFFSET_MASK 0xfffffffffffffe00ULL
5978fba3951SVladimir Sementsov-Ogievskiy #define REFT_RESERVED_MASK 0x1ffULL
59876dc9e0cSKevin Wolf
599c6d619ccSKevin Wolf #define INV_OFFSET (-1ULL)
600c6d619ccSKevin Wolf
has_subclusters(BDRVQcow2State * s)601a3c7d916SAlberto Garcia static inline bool has_subclusters(BDRVQcow2State *s)
602a3c7d916SAlberto Garcia {
6037be20252SAlberto Garcia return s->incompatible_features & QCOW2_INCOMPAT_EXTL2;
604a3c7d916SAlberto Garcia }
605a3c7d916SAlberto Garcia
l2_entry_size(BDRVQcow2State * s)606c8fd8554SAlberto Garcia static inline size_t l2_entry_size(BDRVQcow2State *s)
607c8fd8554SAlberto Garcia {
608c8fd8554SAlberto Garcia return has_subclusters(s) ? L2E_SIZE_EXTENDED : L2E_SIZE_NORMAL;
609c8fd8554SAlberto Garcia }
610c8fd8554SAlberto Garcia
get_l2_entry(BDRVQcow2State * s,uint64_t * l2_slice,int idx)61112c6aebeSAlberto Garcia static inline uint64_t get_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,
61212c6aebeSAlberto Garcia int idx)
61312c6aebeSAlberto Garcia {
61439a9f0a5SAlberto Garcia idx *= l2_entry_size(s) / sizeof(uint64_t);
61512c6aebeSAlberto Garcia return be64_to_cpu(l2_slice[idx]);
61612c6aebeSAlberto Garcia }
61712c6aebeSAlberto Garcia
get_l2_bitmap(BDRVQcow2State * s,uint64_t * l2_slice,int idx)61839a9f0a5SAlberto Garcia static inline uint64_t get_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice,
61939a9f0a5SAlberto Garcia int idx)
62039a9f0a5SAlberto Garcia {
62139a9f0a5SAlberto Garcia if (has_subclusters(s)) {
62239a9f0a5SAlberto Garcia idx *= l2_entry_size(s) / sizeof(uint64_t);
62339a9f0a5SAlberto Garcia return be64_to_cpu(l2_slice[idx + 1]);
62439a9f0a5SAlberto Garcia } else {
62539a9f0a5SAlberto Garcia return 0; /* For convenience only; this value has no meaning. */
62639a9f0a5SAlberto Garcia }
62739a9f0a5SAlberto Garcia }
62839a9f0a5SAlberto Garcia
set_l2_entry(BDRVQcow2State * s,uint64_t * l2_slice,int idx,uint64_t entry)62912c6aebeSAlberto Garcia static inline void set_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice,
63012c6aebeSAlberto Garcia int idx, uint64_t entry)
63112c6aebeSAlberto Garcia {
63239a9f0a5SAlberto Garcia idx *= l2_entry_size(s) / sizeof(uint64_t);
63312c6aebeSAlberto Garcia l2_slice[idx] = cpu_to_be64(entry);
63412c6aebeSAlberto Garcia }
63512c6aebeSAlberto Garcia
set_l2_bitmap(BDRVQcow2State * s,uint64_t * l2_slice,int idx,uint64_t bitmap)63639a9f0a5SAlberto Garcia static inline void set_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice,
63739a9f0a5SAlberto Garcia int idx, uint64_t bitmap)
63839a9f0a5SAlberto Garcia {
63939a9f0a5SAlberto Garcia assert(has_subclusters(s));
64039a9f0a5SAlberto Garcia idx *= l2_entry_size(s) / sizeof(uint64_t);
64139a9f0a5SAlberto Garcia l2_slice[idx + 1] = cpu_to_be64(bitmap);
64239a9f0a5SAlberto Garcia }
64339a9f0a5SAlberto Garcia
has_data_file(BlockDriverState * bs)644*8f897341SKevin Wolf static inline bool GRAPH_RDLOCK has_data_file(BlockDriverState *bs)
64593c24936SKevin Wolf {
64693c24936SKevin Wolf BDRVQcow2State *s = bs->opaque;
64793c24936SKevin Wolf return (s->data_file != bs->file);
64893c24936SKevin Wolf }
64993c24936SKevin Wolf
data_file_is_raw(BlockDriverState * bs)6506c3944dcSKevin Wolf static inline bool data_file_is_raw(BlockDriverState *bs)
6516c3944dcSKevin Wolf {
6526c3944dcSKevin Wolf BDRVQcow2State *s = bs->opaque;
6536c3944dcSKevin Wolf return !!(s->autoclear_features & QCOW2_AUTOCLEAR_DATA_FILE_RAW);
6546c3944dcSKevin Wolf }
6556c3944dcSKevin Wolf
start_of_cluster(BDRVQcow2State * s,int64_t offset)656ff99129aSKevin Wolf static inline int64_t start_of_cluster(BDRVQcow2State *s, int64_t offset)
6573b8e2e26SKevin Wolf {
6583b8e2e26SKevin Wolf return offset & ~(s->cluster_size - 1);
6593b8e2e26SKevin Wolf }
6603b8e2e26SKevin Wolf
offset_into_cluster(BDRVQcow2State * s,int64_t offset)661ff99129aSKevin Wolf static inline int64_t offset_into_cluster(BDRVQcow2State *s, int64_t offset)
662c37f4cd7SKevin Wolf {
663c37f4cd7SKevin Wolf return offset & (s->cluster_size - 1);
664c37f4cd7SKevin Wolf }
665c37f4cd7SKevin Wolf
offset_into_subcluster(BDRVQcow2State * s,int64_t offset)6663e719815SAlberto Garcia static inline int64_t offset_into_subcluster(BDRVQcow2State *s, int64_t offset)
6673e719815SAlberto Garcia {
6683e719815SAlberto Garcia return offset & (s->subcluster_size - 1);
6693e719815SAlberto Garcia }
6703e719815SAlberto Garcia
size_to_clusters(BDRVQcow2State * s,uint64_t size)671b6d36defSMax Reitz static inline uint64_t size_to_clusters(BDRVQcow2State *s, uint64_t size)
672f7d0fe02SKevin Wolf {
673f7d0fe02SKevin Wolf return (size + (s->cluster_size - 1)) >> s->cluster_bits;
674f7d0fe02SKevin Wolf }
675f7d0fe02SKevin Wolf
size_to_subclusters(BDRVQcow2State * s,uint64_t size)6763e719815SAlberto Garcia static inline uint64_t size_to_subclusters(BDRVQcow2State *s, uint64_t size)
6773e719815SAlberto Garcia {
6783e719815SAlberto Garcia return (size + (s->subcluster_size - 1)) >> s->subcluster_bits;
6793e719815SAlberto Garcia }
6803e719815SAlberto Garcia
size_to_l1(BDRVQcow2State * s,int64_t size)681ff99129aSKevin Wolf static inline int64_t size_to_l1(BDRVQcow2State *s, int64_t size)
682419b19d9SStefan Hajnoczi {
683419b19d9SStefan Hajnoczi int shift = s->cluster_bits + s->l2_bits;
684419b19d9SStefan Hajnoczi return (size + (1ULL << shift) - 1) >> shift;
685419b19d9SStefan Hajnoczi }
686419b19d9SStefan Hajnoczi
offset_to_l1_index(BDRVQcow2State * s,uint64_t offset)68705b5b6eeSAlberto Garcia static inline int offset_to_l1_index(BDRVQcow2State *s, uint64_t offset)
68805b5b6eeSAlberto Garcia {
68905b5b6eeSAlberto Garcia return offset >> (s->l2_bits + s->cluster_bits);
69005b5b6eeSAlberto Garcia }
69105b5b6eeSAlberto Garcia
offset_to_l2_index(BDRVQcow2State * s,int64_t offset)692ff99129aSKevin Wolf static inline int offset_to_l2_index(BDRVQcow2State *s, int64_t offset)
69317a71e58SKevin Wolf {
69417a71e58SKevin Wolf return (offset >> s->cluster_bits) & (s->l2_size - 1);
69517a71e58SKevin Wolf }
69617a71e58SKevin Wolf
offset_to_l2_slice_index(BDRVQcow2State * s,int64_t offset)6978f818175SAlberto Garcia static inline int offset_to_l2_slice_index(BDRVQcow2State *s, int64_t offset)
6988f818175SAlberto Garcia {
6998f818175SAlberto Garcia return (offset >> s->cluster_bits) & (s->l2_slice_size - 1);
7008f818175SAlberto Garcia }
7018f818175SAlberto Garcia
offset_to_sc_index(BDRVQcow2State * s,int64_t offset)702a53e8b72SAlberto Garcia static inline int offset_to_sc_index(BDRVQcow2State *s, int64_t offset)
703a53e8b72SAlberto Garcia {
704a53e8b72SAlberto Garcia return (offset >> s->subcluster_bits) & (s->subclusters_per_cluster - 1);
705a53e8b72SAlberto Garcia }
706a53e8b72SAlberto Garcia
qcow2_vm_state_offset(BDRVQcow2State * s)707ff99129aSKevin Wolf static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
7081ebf561cSKevin Wolf {
7091ebf561cSKevin Wolf return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
7101ebf561cSKevin Wolf }
7111ebf561cSKevin Wolf
712*8f897341SKevin Wolf static inline QCow2ClusterType GRAPH_RDLOCK
qcow2_get_cluster_type(BlockDriverState * bs,uint64_t l2_entry)713*8f897341SKevin Wolf qcow2_get_cluster_type(BlockDriverState *bs, uint64_t l2_entry)
71468d000a3SKevin Wolf {
71534905d8eSAlberto Garcia BDRVQcow2State *s = bs->opaque;
71634905d8eSAlberto Garcia
71768d000a3SKevin Wolf if (l2_entry & QCOW_OFLAG_COMPRESSED) {
71868d000a3SKevin Wolf return QCOW2_CLUSTER_COMPRESSED;
71934905d8eSAlberto Garcia } else if ((l2_entry & QCOW_OFLAG_ZERO) && !has_subclusters(s)) {
720fdfab37dSEric Blake if (l2_entry & L2E_OFFSET_MASK) {
721fdfab37dSEric Blake return QCOW2_CLUSTER_ZERO_ALLOC;
722fdfab37dSEric Blake }
723fdfab37dSEric Blake return QCOW2_CLUSTER_ZERO_PLAIN;
72468d000a3SKevin Wolf } else if (!(l2_entry & L2E_OFFSET_MASK)) {
725a4ea184dSKevin Wolf /* Offset 0 generally means unallocated, but it is ambiguous with
726a4ea184dSKevin Wolf * external data files because 0 is a valid offset there. However, all
727a4ea184dSKevin Wolf * clusters in external data files always have refcount 1, so we can
728a4ea184dSKevin Wolf * rely on QCOW_OFLAG_COPIED to disambiguate. */
729a4ea184dSKevin Wolf if (has_data_file(bs) && (l2_entry & QCOW_OFLAG_COPIED)) {
730a4ea184dSKevin Wolf return QCOW2_CLUSTER_NORMAL;
731a4ea184dSKevin Wolf } else {
73268d000a3SKevin Wolf return QCOW2_CLUSTER_UNALLOCATED;
733a4ea184dSKevin Wolf }
73468d000a3SKevin Wolf } else {
73568d000a3SKevin Wolf return QCOW2_CLUSTER_NORMAL;
73668d000a3SKevin Wolf }
73768d000a3SKevin Wolf }
73868d000a3SKevin Wolf
73934905d8eSAlberto Garcia /*
74034905d8eSAlberto Garcia * In an image without subsclusters @l2_bitmap is ignored and
74134905d8eSAlberto Garcia * @sc_index must be 0.
74234905d8eSAlberto Garcia * Return QCOW2_SUBCLUSTER_INVALID if an invalid l2 entry is detected
74334905d8eSAlberto Garcia * (this checks the whole entry and bitmap, not only the bits related
74434905d8eSAlberto Garcia * to subcluster @sc_index).
74534905d8eSAlberto Garcia */
746*8f897341SKevin Wolf static inline GRAPH_RDLOCK
qcow2_get_subcluster_type(BlockDriverState * bs,uint64_t l2_entry,uint64_t l2_bitmap,unsigned sc_index)74734905d8eSAlberto Garcia QCow2SubclusterType qcow2_get_subcluster_type(BlockDriverState *bs,
74834905d8eSAlberto Garcia uint64_t l2_entry,
74934905d8eSAlberto Garcia uint64_t l2_bitmap,
75034905d8eSAlberto Garcia unsigned sc_index)
75134905d8eSAlberto Garcia {
75234905d8eSAlberto Garcia BDRVQcow2State *s = bs->opaque;
75334905d8eSAlberto Garcia QCow2ClusterType type = qcow2_get_cluster_type(bs, l2_entry);
75434905d8eSAlberto Garcia assert(sc_index < s->subclusters_per_cluster);
75534905d8eSAlberto Garcia
75634905d8eSAlberto Garcia if (has_subclusters(s)) {
75734905d8eSAlberto Garcia switch (type) {
75834905d8eSAlberto Garcia case QCOW2_CLUSTER_COMPRESSED:
75934905d8eSAlberto Garcia return QCOW2_SUBCLUSTER_COMPRESSED;
76034905d8eSAlberto Garcia case QCOW2_CLUSTER_NORMAL:
76134905d8eSAlberto Garcia if ((l2_bitmap >> 32) & l2_bitmap) {
76234905d8eSAlberto Garcia return QCOW2_SUBCLUSTER_INVALID;
76334905d8eSAlberto Garcia } else if (l2_bitmap & QCOW_OFLAG_SUB_ZERO(sc_index)) {
76434905d8eSAlberto Garcia return QCOW2_SUBCLUSTER_ZERO_ALLOC;
76534905d8eSAlberto Garcia } else if (l2_bitmap & QCOW_OFLAG_SUB_ALLOC(sc_index)) {
76634905d8eSAlberto Garcia return QCOW2_SUBCLUSTER_NORMAL;
76734905d8eSAlberto Garcia } else {
76834905d8eSAlberto Garcia return QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC;
76934905d8eSAlberto Garcia }
77034905d8eSAlberto Garcia case QCOW2_CLUSTER_UNALLOCATED:
77134905d8eSAlberto Garcia if (l2_bitmap & QCOW_L2_BITMAP_ALL_ALLOC) {
77234905d8eSAlberto Garcia return QCOW2_SUBCLUSTER_INVALID;
77334905d8eSAlberto Garcia } else if (l2_bitmap & QCOW_OFLAG_SUB_ZERO(sc_index)) {
77434905d8eSAlberto Garcia return QCOW2_SUBCLUSTER_ZERO_PLAIN;
77534905d8eSAlberto Garcia } else {
77634905d8eSAlberto Garcia return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;
77734905d8eSAlberto Garcia }
77834905d8eSAlberto Garcia default:
77934905d8eSAlberto Garcia g_assert_not_reached();
78034905d8eSAlberto Garcia }
78134905d8eSAlberto Garcia } else {
7823f9c6b3bSAlberto Garcia switch (type) {
7833f9c6b3bSAlberto Garcia case QCOW2_CLUSTER_COMPRESSED:
7843f9c6b3bSAlberto Garcia return QCOW2_SUBCLUSTER_COMPRESSED;
7853f9c6b3bSAlberto Garcia case QCOW2_CLUSTER_ZERO_PLAIN:
7863f9c6b3bSAlberto Garcia return QCOW2_SUBCLUSTER_ZERO_PLAIN;
7873f9c6b3bSAlberto Garcia case QCOW2_CLUSTER_ZERO_ALLOC:
7883f9c6b3bSAlberto Garcia return QCOW2_SUBCLUSTER_ZERO_ALLOC;
7893f9c6b3bSAlberto Garcia case QCOW2_CLUSTER_NORMAL:
7903f9c6b3bSAlberto Garcia return QCOW2_SUBCLUSTER_NORMAL;
7913f9c6b3bSAlberto Garcia case QCOW2_CLUSTER_UNALLOCATED:
7923f9c6b3bSAlberto Garcia return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN;
7933f9c6b3bSAlberto Garcia default:
7943f9c6b3bSAlberto Garcia g_assert_not_reached();
7953f9c6b3bSAlberto Garcia }
79634905d8eSAlberto Garcia }
79734905d8eSAlberto Garcia }
79834905d8eSAlberto Garcia
qcow2_cluster_is_allocated(QCow2ClusterType type)799c94d0378SAlberto Garcia static inline bool qcow2_cluster_is_allocated(QCow2ClusterType type)
800c94d0378SAlberto Garcia {
801c94d0378SAlberto Garcia return (type == QCOW2_CLUSTER_COMPRESSED || type == QCOW2_CLUSTER_NORMAL ||
802c94d0378SAlberto Garcia type == QCOW2_CLUSTER_ZERO_ALLOC);
803c94d0378SAlberto Garcia }
804c94d0378SAlberto Garcia
805bfe8043eSStefan Hajnoczi /* Check whether refcounts are eager or lazy */
qcow2_need_accurate_refcounts(BDRVQcow2State * s)806ff99129aSKevin Wolf static inline bool qcow2_need_accurate_refcounts(BDRVQcow2State *s)
807bfe8043eSStefan Hajnoczi {
808bfe8043eSStefan Hajnoczi return !(s->incompatible_features & QCOW2_INCOMPAT_DIRTY);
809bfe8043eSStefan Hajnoczi }
810c142442bSKevin Wolf
l2meta_cow_start(QCowL2Meta * m)81165eb2e35SKevin Wolf static inline uint64_t l2meta_cow_start(QCowL2Meta *m)
81265eb2e35SKevin Wolf {
81365eb2e35SKevin Wolf return m->offset + m->cow_start.offset;
81465eb2e35SKevin Wolf }
81565eb2e35SKevin Wolf
l2meta_cow_end(QCowL2Meta * m)81665eb2e35SKevin Wolf static inline uint64_t l2meta_cow_end(QCowL2Meta *m)
81765eb2e35SKevin Wolf {
81885567393SKevin Wolf return m->offset + m->cow_end.offset + m->cow_end.nb_bytes;
81965eb2e35SKevin Wolf }
82065eb2e35SKevin Wolf
refcount_diff(uint64_t r1,uint64_t r2)8210e06528eSMax Reitz static inline uint64_t refcount_diff(uint64_t r1, uint64_t r2)
8222aabe7c7SMax Reitz {
8232aabe7c7SMax Reitz return r1 > r2 ? r1 - r2 : r2 - r1;
8242aabe7c7SMax Reitz }
8252aabe7c7SMax Reitz
82646b732cdSPavel Butsykin static inline
offset_to_reftable_index(BDRVQcow2State * s,uint64_t offset)82746b732cdSPavel Butsykin uint32_t offset_to_reftable_index(BDRVQcow2State *s, uint64_t offset)
82846b732cdSPavel Butsykin {
82946b732cdSPavel Butsykin return offset >> (s->refcount_block_bits + s->cluster_bits);
83046b732cdSPavel Butsykin }
83146b732cdSPavel Butsykin
832f7d0fe02SKevin Wolf /* qcow2.c functions */
83312cc30a8SMax Reitz int64_t qcow2_refcount_metadata_size(int64_t clusters, size_t cluster_size,
83412cc30a8SMax Reitz int refcount_order, bool generous_increase,
83512cc30a8SMax Reitz uint64_t *refblock_count);
83612cc30a8SMax Reitz
837*8f897341SKevin Wolf int GRAPH_RDLOCK qcow2_mark_dirty(BlockDriverState *bs);
838*8f897341SKevin Wolf int GRAPH_RDLOCK qcow2_mark_corrupt(BlockDriverState *bs);
839*8f897341SKevin Wolf int GRAPH_RDLOCK qcow2_update_header(BlockDriverState *bs);
840f7d0fe02SKevin Wolf
8410bb79c97SKevin Wolf void GRAPH_RDLOCK
8420bb79c97SKevin Wolf qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
84385186ebdSMax Reitz int64_t size, const char *message_format, ...)
8449edc6313SMarc-André Lureau G_GNUC_PRINTF(5, 6);
84585186ebdSMax Reitz
8460cf0e598SAlberto Garcia int qcow2_validate_table(BlockDriverState *bs, uint64_t offset,
8470cf0e598SAlberto Garcia uint64_t entries, size_t entry_len,
8480cf0e598SAlberto Garcia int64_t max_size_bytes, const char *table_name,
8490cf0e598SAlberto Garcia Error **errp);
8500cf0e598SAlberto Garcia
851f7d0fe02SKevin Wolf /* qcow2-refcount.c functions */
852b9b10c35SKevin Wolf int coroutine_fn GRAPH_RDLOCK qcow2_refcount_init(BlockDriverState *bs);
853ed6ccf0fSKevin Wolf void qcow2_refcount_close(BlockDriverState *bs);
854f7d0fe02SKevin Wolf
8550bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index,
8560e06528eSMax Reitz uint64_t *refcount);
85744751917SMax Reitz
8580bb79c97SKevin Wolf int GRAPH_RDLOCK
8590bb79c97SKevin Wolf qcow2_update_cluster_refcount(BlockDriverState *bs, int64_t cluster_index,
8600e06528eSMax Reitz uint64_t addend, bool decrease,
8612aabe7c7SMax Reitz enum qcow2_discard_type type);
86232b6444dSMax Reitz
8630bb79c97SKevin Wolf int64_t GRAPH_RDLOCK
8640bb79c97SKevin Wolf qcow2_refcount_area(BlockDriverState *bs, uint64_t offset,
865772d1f97SMax Reitz uint64_t additional_clusters, bool exact_size,
866772d1f97SMax Reitz int new_refblock_index,
867772d1f97SMax Reitz uint64_t new_refblock_offset);
868772d1f97SMax Reitz
8690bb79c97SKevin Wolf int64_t GRAPH_RDLOCK
8700bb79c97SKevin Wolf qcow2_alloc_clusters(BlockDriverState *bs, uint64_t size);
8710bb79c97SKevin Wolf
8720bb79c97SKevin Wolf int64_t GRAPH_RDLOCK coroutine_fn
8730bb79c97SKevin Wolf qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
874b6d36defSMax Reitz int64_t nb_clusters);
8750bb79c97SKevin Wolf
87670bacc44SPaolo Bonzini int64_t coroutine_fn GRAPH_RDLOCK qcow2_alloc_bytes(BlockDriverState *bs, int size);
8770bb79c97SKevin Wolf void GRAPH_RDLOCK qcow2_free_clusters(BlockDriverState *bs,
8786cfcb9b8SKevin Wolf int64_t offset, int64_t size,
8796cfcb9b8SKevin Wolf enum qcow2_discard_type type);
8800bb79c97SKevin Wolf void GRAPH_RDLOCK
8810bb79c97SKevin Wolf qcow2_free_any_cluster(BlockDriverState *bs, uint64_t l2_entry,
8823fec237fSAlberto Garcia enum qcow2_discard_type type);
883f7d0fe02SKevin Wolf
8840bb79c97SKevin Wolf int GRAPH_RDLOCK
8850bb79c97SKevin Wolf qcow2_update_snapshot_refcount(BlockDriverState *bs, int64_t l1_table_offset,
8860bb79c97SKevin Wolf int l1_size, int addend);
887f7d0fe02SKevin Wolf
8880bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_flush_caches(BlockDriverState *bs);
8890bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_write_caches(BlockDriverState *bs);
89070bacc44SPaolo Bonzini int coroutine_fn qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
891166acf54SKevin Wolf BdrvCheckMode fix);
892f7d0fe02SKevin Wolf
893*8f897341SKevin Wolf void GRAPH_RDLOCK qcow2_process_discards(BlockDriverState *bs, int ret);
8940b919faeSKevin Wolf
895*8f897341SKevin Wolf int GRAPH_RDLOCK
896*8f897341SKevin Wolf qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
897a40f1c2aSMax Reitz int64_t size);
8980bb79c97SKevin Wolf int GRAPH_RDLOCK
8990bb79c97SKevin Wolf qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
900966b000fSKevin Wolf int64_t size, bool data_file);
9010bb79c97SKevin Wolf
90270bacc44SPaolo Bonzini int coroutine_fn qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
9038a5bb1f1SVladimir Sementsov-Ogievskiy void **refcount_table,
9048a5bb1f1SVladimir Sementsov-Ogievskiy int64_t *refcount_table_size,
9058a5bb1f1SVladimir Sementsov-Ogievskiy int64_t offset, int64_t size);
906a40f1c2aSMax Reitz
9070bb79c97SKevin Wolf int GRAPH_RDLOCK
9080bb79c97SKevin Wolf qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
909791c9a00SMax Reitz BlockDriverAmendStatusCB *status_cb,
910791c9a00SMax Reitz void *cb_opaque, Error **errp);
911b24a4c41SKevin Wolf int coroutine_fn GRAPH_RDLOCK qcow2_shrink_reftable(BlockDriverState *bs);
9120bb79c97SKevin Wolf
9130bb79c97SKevin Wolf int64_t coroutine_fn GRAPH_RDLOCK
9140bb79c97SKevin Wolf qcow2_get_last_cluster(BlockDriverState *bs, int64_t size);
9150050c163SKevin Wolf
9160050c163SKevin Wolf int coroutine_fn GRAPH_RDLOCK
9170050c163SKevin Wolf qcow2_detect_metadata_preallocation(BlockDriverState *bs);
918791c9a00SMax Reitz
91945aba42fSKevin Wolf /* qcow2-cluster.c functions */
9200bb79c97SKevin Wolf int GRAPH_RDLOCK
9210bb79c97SKevin Wolf qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, bool exact_size);
92288095349SEmanuele Giuseppe Esposito
92388095349SEmanuele Giuseppe Esposito int coroutine_fn GRAPH_RDLOCK
92488095349SEmanuele Giuseppe Esposito qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size);
92588095349SEmanuele Giuseppe Esposito
9260bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
927ff99129aSKevin Wolf int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
928446d306dSDaniel P. Berrange uint8_t *buf, int nb_sectors, bool enc, Error **errp);
92945aba42fSKevin Wolf
9300bb79c97SKevin Wolf int GRAPH_RDLOCK
9310bb79c97SKevin Wolf qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset,
932ca4a0bb8SAlberto Garcia unsigned int *bytes, uint64_t *host_offset,
93310dabdc5SAlberto Garcia QCow2SubclusterType *subcluster_type);
9340bb79c97SKevin Wolf
9350bb79c97SKevin Wolf int coroutine_fn GRAPH_RDLOCK
9360bb79c97SKevin Wolf qcow2_alloc_host_offset(BlockDriverState *bs, uint64_t offset,
9370bb79c97SKevin Wolf unsigned int *bytes, uint64_t *host_offset,
9380bb79c97SKevin Wolf QCowL2Meta **m);
9390bb79c97SKevin Wolf
94070bacc44SPaolo Bonzini int coroutine_fn GRAPH_RDLOCK
94170bacc44SPaolo Bonzini qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, uint64_t offset,
94270bacc44SPaolo Bonzini int compressed_size, uint64_t *host_offset);
943*8f897341SKevin Wolf void GRAPH_RDLOCK
944*8f897341SKevin Wolf qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
945a6e09846SVladimir Sementsov-Ogievskiy uint64_t *coffset, int *csize);
94645aba42fSKevin Wolf
9477b1fb72eSKevin Wolf int coroutine_fn GRAPH_RDLOCK
9487b1fb72eSKevin Wolf qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
9497b1fb72eSKevin Wolf
9500bb79c97SKevin Wolf void coroutine_fn GRAPH_RDLOCK
9510bb79c97SKevin Wolf qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
9520bb79c97SKevin Wolf
9530bb79c97SKevin Wolf int GRAPH_RDLOCK
9540bb79c97SKevin Wolf qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
9550bb79c97SKevin Wolf enum qcow2_discard_type type, bool full_discard);
956abaf8b75SKevin Wolf
957abaf8b75SKevin Wolf int coroutine_fn GRAPH_RDLOCK
958abaf8b75SKevin Wolf qcow2_subcluster_zeroize(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
959abaf8b75SKevin Wolf int flags);
96045aba42fSKevin Wolf
9610bb79c97SKevin Wolf int GRAPH_RDLOCK
9620bb79c97SKevin Wolf qcow2_expand_zero_clusters(BlockDriverState *bs,
9638b13976dSMax Reitz BlockDriverAmendStatusCB *status_cb,
9648b13976dSMax Reitz void *cb_opaque);
96532b6444dSMax Reitz
966c142442bSKevin Wolf /* qcow2-snapshot.c functions */
9670bb79c97SKevin Wolf int GRAPH_RDLOCK
9680bb79c97SKevin Wolf qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
9690bb79c97SKevin Wolf
9700bb79c97SKevin Wolf int GRAPH_RDLOCK
9710bb79c97SKevin Wolf qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
9720bb79c97SKevin Wolf
9730bb79c97SKevin Wolf int GRAPH_RDLOCK
9740bb79c97SKevin Wolf qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id,
9750bb79c97SKevin Wolf const char *name, Error **errp);
9760bb79c97SKevin Wolf
97779a55866SKevin Wolf int GRAPH_RDLOCK
97879a55866SKevin Wolf qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
97979a55866SKevin Wolf
98079a55866SKevin Wolf int GRAPH_RDLOCK
98179a55866SKevin Wolf qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_id,
98279a55866SKevin Wolf const char *name, Error **errp);
983c142442bSKevin Wolf
984ed6ccf0fSKevin Wolf void qcow2_free_snapshots(BlockDriverState *bs);
985a39bae4eSPaolo Bonzini int coroutine_fn GRAPH_RDLOCK
986a39bae4eSPaolo Bonzini qcow2_read_snapshots(BlockDriverState *bs, Error **errp);
9870bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_write_snapshots(BlockDriverState *bs);
988c142442bSKevin Wolf
989b9b10c35SKevin Wolf int coroutine_fn GRAPH_RDLOCK
990b9b10c35SKevin Wolf qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
9918bc584feSMax Reitz BdrvCheckMode fix);
992b9b10c35SKevin Wolf
9930bb79c97SKevin Wolf int coroutine_fn GRAPH_RDLOCK
9940bb79c97SKevin Wolf qcow2_check_fix_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result,
995fe446b5dSMax Reitz BdrvCheckMode fix);
9968bc584feSMax Reitz
99749381094SKevin Wolf /* qcow2-cache.c functions */
998*8f897341SKevin Wolf Qcow2Cache * GRAPH_RDLOCK
999*8f897341SKevin Wolf qcow2_cache_create(BlockDriverState *bs, int num_tables, unsigned table_size);
1000*8f897341SKevin Wolf
1001e64d4072SAlberto Garcia int qcow2_cache_destroy(Qcow2Cache *c);
100249381094SKevin Wolf
10032d135ee9SAlberto Garcia void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
10040bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
10050bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c);
10060bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
100749381094SKevin Wolf Qcow2Cache *dependency);
10083de0a294SKevin Wolf void qcow2_cache_depends_on_flush(Qcow2Cache *c);
100949381094SKevin Wolf
1010b2f68bffSAlberto Garcia void qcow2_cache_clean_unused(Qcow2Cache *c);
10110bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_cache_empty(BlockDriverState *bs, Qcow2Cache *c);
1012e7108feaSMax Reitz
10130bb79c97SKevin Wolf int GRAPH_RDLOCK
10140bb79c97SKevin Wolf qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
101549381094SKevin Wolf void **table);
10160bb79c97SKevin Wolf
10170bb79c97SKevin Wolf int GRAPH_RDLOCK
10180bb79c97SKevin Wolf qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
101949381094SKevin Wolf void **table);
10200bb79c97SKevin Wolf
10212013c3d4SAlberto Garcia void qcow2_cache_put(Qcow2Cache *c, void **table);
10226e6fa760SAlberto Garcia void *qcow2_cache_is_table_offset(Qcow2Cache *c, uint64_t offset);
102377aadd7bSAlberto Garcia void qcow2_cache_discard(Qcow2Cache *c, void *table);
102449381094SKevin Wolf
102588ddffaeSVladimir Sementsov-Ogievskiy /* qcow2-bitmap.c functions */
1026*8f897341SKevin Wolf int coroutine_fn GRAPH_RDLOCK
102770bacc44SPaolo Bonzini qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
102888ddffaeSVladimir Sementsov-Ogievskiy void **refcount_table,
102988ddffaeSVladimir Sementsov-Ogievskiy int64_t *refcount_table_size);
1030*8f897341SKevin Wolf
103170bacc44SPaolo Bonzini bool coroutine_fn GRAPH_RDLOCK
1032*8f897341SKevin Wolf qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated,
1033*8f897341SKevin Wolf Error **errp);
1034*8f897341SKevin Wolf
1035*8f897341SKevin Wolf bool GRAPH_RDLOCK
1036*8f897341SKevin Wolf qcow2_get_bitmap_info_list(BlockDriverState *bs,
103783bad8cbSVladimir Sementsov-Ogievskiy Qcow2BitmapInfoList **info_list, Error **errp);
1038*8f897341SKevin Wolf
10390bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp);
10400bb79c97SKevin Wolf int GRAPH_RDLOCK qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp);
1041*8f897341SKevin Wolf
1042*8f897341SKevin Wolf int coroutine_fn GRAPH_RDLOCK
1043*8f897341SKevin Wolf qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp);
10440bb79c97SKevin Wolf
10450bb79c97SKevin Wolf bool GRAPH_RDLOCK
10460bb79c97SKevin Wolf qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, bool release_stored,
10470bb79c97SKevin Wolf Error **errp);
10480bb79c97SKevin Wolf
10494026f1c4SKevin Wolf bool coroutine_fn GRAPH_RDLOCK
10504026f1c4SKevin Wolf qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
10514026f1c4SKevin Wolf uint32_t granularity, Error **errp);
10520bb79c97SKevin Wolf
10530bb79c97SKevin Wolf int coroutine_fn GRAPH_RDLOCK
10540bb79c97SKevin Wolf qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
1055469c71edSVladimir Sementsov-Ogievskiy Error **errp);
10560bb79c97SKevin Wolf
1057ef893b5cSEric Blake bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
10585d72c68bSEric Blake uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
10595d72c68bSEric Blake uint32_t cluster_size);
1060d1258dd0SVladimir Sementsov-Ogievskiy
106156e2f1d8SVladimir Sementsov-Ogievskiy ssize_t coroutine_fn
106256e2f1d8SVladimir Sementsov-Ogievskiy qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
106356e2f1d8SVladimir Sementsov-Ogievskiy const void *src, size_t src_size);
106456e2f1d8SVladimir Sementsov-Ogievskiy ssize_t coroutine_fn
106556e2f1d8SVladimir Sementsov-Ogievskiy qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
106656e2f1d8SVladimir Sementsov-Ogievskiy const void *src, size_t src_size);
10678ac0f15fSVladimir Sementsov-Ogievskiy int coroutine_fn
1068603fbd07SMaxim Levitsky qcow2_co_encrypt(BlockDriverState *bs, uint64_t host_offset,
1069603fbd07SMaxim Levitsky uint64_t guest_offset, void *buf, size_t len);
10708ac0f15fSVladimir Sementsov-Ogievskiy int coroutine_fn
1071603fbd07SMaxim Levitsky qcow2_co_decrypt(BlockDriverState *bs, uint64_t host_offset,
1072603fbd07SMaxim Levitsky uint64_t guest_offset, void *buf, size_t len);
107356e2f1d8SVladimir Sementsov-Ogievskiy
1074f7d0fe02SKevin Wolf #endif
1075