qcow2.h 6.8 KB
Newer Older
K
Kevin Wolf 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * Block driver for the QCOW version 2 format
 *
 * Copyright (c) 2004-2006 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef BLOCK_QCOW2_H
#define BLOCK_QCOW2_H

#include "aes.h"

30 31 32 33
//#define DEBUG_ALLOC
//#define DEBUG_ALLOC2
//#define DEBUG_EXT

K
Kevin Wolf 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
#define QCOW_VERSION 2

#define QCOW_CRYPT_NONE 0
#define QCOW_CRYPT_AES  1

#define QCOW_MAX_CRYPT_CLUSTERS 32

/* indicate that the refcount of the referenced cluster is exactly one. */
#define QCOW_OFLAG_COPIED     (1LL << 63)
/* indicate that the cluster is compressed (they never have the copied flag) */
#define QCOW_OFLAG_COMPRESSED (1LL << 62)

#define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */

#define MIN_CLUSTER_BITS 9
50
#define MAX_CLUSTER_BITS 21
K
Kevin Wolf 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

#define L2_CACHE_SIZE 16

typedef struct QCowHeader {
    uint32_t magic;
    uint32_t version;
    uint64_t backing_file_offset;
    uint32_t backing_file_size;
    uint32_t cluster_bits;
    uint64_t size; /* in bytes */
    uint32_t crypt_method;
    uint32_t l1_size; /* XXX: save number of clusters instead ? */
    uint64_t l1_table_offset;
    uint64_t refcount_table_offset;
    uint32_t refcount_table_clusters;
    uint32_t nb_snapshots;
    uint64_t snapshots_offset;
} QCowHeader;

typedef struct QCowSnapshot {
    uint64_t l1_table_offset;
    uint32_t l1_size;
    char *id_str;
    char *name;
    uint32_t vm_state_size;
    uint32_t date_sec;
    uint32_t date_nsec;
    uint64_t vm_clock_nsec;
} QCowSnapshot;

typedef struct BDRVQcowState {
    BlockDriverState *hd;
    int cluster_bits;
    int cluster_size;
    int cluster_sectors;
    int l2_bits;
    int l2_size;
    int l1_size;
    int l1_vm_state_index;
    int csize_shift;
    int csize_mask;
    uint64_t cluster_offset_mask;
    uint64_t l1_table_offset;
    uint64_t *l1_table;
    uint64_t *l2_cache;
    uint64_t l2_cache_offsets[L2_CACHE_SIZE];
    uint32_t l2_cache_counts[L2_CACHE_SIZE];
    uint8_t *cluster_cache;
    uint8_t *cluster_data;
    uint64_t cluster_cache_offset;
B
Blue Swirl 已提交
101
    QLIST_HEAD(QCowClusterAlloc, QCowL2Meta) cluster_allocs;
K
Kevin Wolf 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131

    uint64_t *refcount_table;
    uint64_t refcount_table_offset;
    uint32_t refcount_table_size;
    uint64_t refcount_block_cache_offset;
    uint16_t *refcount_block_cache;
    int64_t free_cluster_index;
    int64_t free_byte_offset;

    uint32_t crypt_method; /* current crypt method, 0 if no key yet */
    uint32_t crypt_method_header;
    AES_KEY aes_encrypt_key;
    AES_KEY aes_decrypt_key;
    uint64_t snapshots_offset;
    int snapshots_size;
    int nb_snapshots;
    QCowSnapshot *snapshots;
} BDRVQcowState;

/* XXX: use std qcow open function ? */
typedef struct QCowCreateState {
    int cluster_size;
    int cluster_bits;
    uint16_t *refcount_block;
    uint64_t *refcount_table;
    int64_t l1_table_offset;
    int64_t refcount_table_offset;
    int64_t refcount_block_offset;
} QCowCreateState;

132 133
struct QCowAIOCB;

134 135 136 137
/* XXX This could be private for qcow2-cluster.c */
typedef struct QCowL2Meta
{
    uint64_t offset;
138
    uint64_t cluster_offset;
139 140 141
    int n_start;
    int nb_available;
    int nb_clusters;
142
    struct QCowL2Meta *depends_on;
B
Blue Swirl 已提交
143
    QLIST_HEAD(QCowAioDependencies, QCowAIOCB) dependent_requests;
144

B
Blue Swirl 已提交
145
    QLIST_ENTRY(QCowL2Meta) next_in_flight;
146 147 148
} QCowL2Meta;

static inline int size_to_clusters(BDRVQcowState *s, int64_t size)
K
Kevin Wolf 已提交
149 150 151 152
{
    return (size + (s->cluster_size - 1)) >> s->cluster_bits;
}

153 154 155 156 157 158
static inline int size_to_l1(BDRVQcowState *s, int64_t size)
{
    int shift = s->cluster_bits + s->l2_bits;
    return (size + (1ULL << shift) - 1) >> shift;
}

K
Kevin Wolf 已提交
159 160 161 162 163 164 165
static inline int64_t align_offset(int64_t offset, int n)
{
    offset = (offset + n - 1) & ~(n - 1);
    return offset;
}


K
Kevin Wolf 已提交
166 167 168
// FIXME Need qcow2_ prefix to global functions

/* qcow2.c functions */
K
Kevin Wolf 已提交
169
int qcow2_backing_read1(BlockDriverState *bs,
170
                  int64_t sector_num, uint8_t *buf, int nb_sectors);
K
Kevin Wolf 已提交
171 172

/* qcow2-refcount.c functions */
K
Kevin Wolf 已提交
173 174
int qcow2_refcount_init(BlockDriverState *bs);
void qcow2_refcount_close(BlockDriverState *bs);
K
Kevin Wolf 已提交
175

K
Kevin Wolf 已提交
176 177 178
int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size);
int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size);
void qcow2_free_clusters(BlockDriverState *bs,
179
    int64_t offset, int64_t size);
K
Kevin Wolf 已提交
180
void qcow2_free_any_clusters(BlockDriverState *bs,
181
    uint64_t cluster_offset, int nb_clusters);
K
Kevin Wolf 已提交
182

K
Kevin Wolf 已提交
183 184 185 186
void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
    int64_t size);
int qcow2_update_snapshot_refcount(BlockDriverState *bs,
    int64_t l1_table_offset, int l1_size, int addend);
K
Kevin Wolf 已提交
187

K
Kevin Wolf 已提交
188
int qcow2_check_refcounts(BlockDriverState *bs);
K
Kevin Wolf 已提交
189

190
/* qcow2-cluster.c functions */
K
Kevin Wolf 已提交
191 192
int qcow2_grow_l1_table(BlockDriverState *bs, int min_size);
void qcow2_l2_cache_reset(BlockDriverState *bs);
193
int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
K
Kevin Wolf 已提交
194
void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
195 196 197 198
                     uint8_t *out_buf, const uint8_t *in_buf,
                     int nb_sectors, int enc,
                     const AES_KEY *key);

K
Kevin Wolf 已提交
199 200
uint64_t qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
    int *num);
K
Kevin Wolf 已提交
201 202
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
    int n_start, int n_end, int *num, QCowL2Meta *m);
K
Kevin Wolf 已提交
203
uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
204 205 206
                                         uint64_t offset,
                                         int compressed_size);

207
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
208

K
Kevin Wolf 已提交
209
/* qcow2-snapshot.c functions */
K
Kevin Wolf 已提交
210 211 212 213
int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
K
Kevin Wolf 已提交
214

K
Kevin Wolf 已提交
215 216
void qcow2_free_snapshots(BlockDriverState *bs);
int qcow2_read_snapshots(BlockDriverState *bs);
K
Kevin Wolf 已提交
217

K
Kevin Wolf 已提交
218
#endif