xref: /qemu/block/qcow2.h (revision 8f897341)
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)6448f897341SKevin 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 
7128f897341SKevin Wolf static inline QCow2ClusterType GRAPH_RDLOCK
qcow2_get_cluster_type(BlockDriverState * bs,uint64_t l2_entry)7138f897341SKevin 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  */
7468f897341SKevin 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 
8378f897341SKevin Wolf int GRAPH_RDLOCK qcow2_mark_dirty(BlockDriverState *bs);
8388f897341SKevin Wolf int GRAPH_RDLOCK qcow2_mark_corrupt(BlockDriverState *bs);
8398f897341SKevin 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 
8938f897341SKevin Wolf void GRAPH_RDLOCK qcow2_process_discards(BlockDriverState *bs, int ret);
8940b919faeSKevin Wolf 
8958f897341SKevin Wolf int GRAPH_RDLOCK
8968f897341SKevin 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);
9438f897341SKevin Wolf void GRAPH_RDLOCK
9448f897341SKevin 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 */
9988f897341SKevin Wolf Qcow2Cache * GRAPH_RDLOCK
9998f897341SKevin Wolf qcow2_cache_create(BlockDriverState *bs, int num_tables, unsigned table_size);
10008f897341SKevin 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 */
10268f897341SKevin 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);
10308f897341SKevin Wolf 
103170bacc44SPaolo Bonzini bool coroutine_fn GRAPH_RDLOCK
10328f897341SKevin Wolf qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated,
10338f897341SKevin Wolf                          Error **errp);
10348f897341SKevin Wolf 
10358f897341SKevin Wolf bool GRAPH_RDLOCK
10368f897341SKevin Wolf qcow2_get_bitmap_info_list(BlockDriverState *bs,
103783bad8cbSVladimir Sementsov-Ogievskiy                            Qcow2BitmapInfoList **info_list, Error **errp);
10388f897341SKevin 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);
10418f897341SKevin Wolf 
10428f897341SKevin Wolf int coroutine_fn GRAPH_RDLOCK
10438f897341SKevin 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