Annotation of qemu/block/qcow2.h, revision 1.1.1.8

1.1       root        1: /*
                      2:  * Block driver for the QCOW version 2 format
                      3:  *
                      4:  * Copyright (c) 2004-2006 Fabrice Bellard
                      5:  *
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: 
                     25: #ifndef BLOCK_QCOW2_H
                     26: #define BLOCK_QCOW2_H
                     27: 
                     28: #include "aes.h"
1.1.1.7   root       29: #include "qemu-coroutine.h"
1.1       root       30: 
                     31: //#define DEBUG_ALLOC
                     32: //#define DEBUG_ALLOC2
                     33: //#define DEBUG_EXT
                     34: 
                     35: #define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
                     36: 
                     37: #define QCOW_CRYPT_NONE 0
                     38: #define QCOW_CRYPT_AES  1
                     39: 
                     40: #define QCOW_MAX_CRYPT_CLUSTERS 32
                     41: 
                     42: /* indicate that the refcount of the referenced cluster is exactly one. */
                     43: #define QCOW_OFLAG_COPIED     (1LL << 63)
                     44: /* indicate that the cluster is compressed (they never have the copied flag) */
                     45: #define QCOW_OFLAG_COMPRESSED (1LL << 62)
1.1.1.8 ! root       46: /* The cluster reads as all zeros */
        !            47: #define QCOW_OFLAG_ZERO (1LL << 0)
1.1       root       48: 
                     49: #define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
                     50: 
                     51: #define MIN_CLUSTER_BITS 9
1.1.1.2   root       52: #define MAX_CLUSTER_BITS 21
1.1       root       53: 
                     54: #define L2_CACHE_SIZE 16
                     55: 
1.1.1.5   root       56: /* Must be at least 4 to cover all cases of refcount table growth */
                     57: #define REFCOUNT_CACHE_SIZE 4
                     58: 
1.1.1.6   root       59: #define DEFAULT_CLUSTER_SIZE 65536
                     60: 
1.1       root       61: typedef struct QCowHeader {
                     62:     uint32_t magic;
                     63:     uint32_t version;
                     64:     uint64_t backing_file_offset;
                     65:     uint32_t backing_file_size;
                     66:     uint32_t cluster_bits;
                     67:     uint64_t size; /* in bytes */
                     68:     uint32_t crypt_method;
                     69:     uint32_t l1_size; /* XXX: save number of clusters instead ? */
                     70:     uint64_t l1_table_offset;
                     71:     uint64_t refcount_table_offset;
                     72:     uint32_t refcount_table_clusters;
                     73:     uint32_t nb_snapshots;
                     74:     uint64_t snapshots_offset;
1.1.1.8 ! root       75: 
        !            76:     /* The following fields are only valid for version >= 3 */
        !            77:     uint64_t incompatible_features;
        !            78:     uint64_t compatible_features;
        !            79:     uint64_t autoclear_features;
        !            80: 
        !            81:     uint32_t refcount_order;
        !            82:     uint32_t header_length;
1.1       root       83: } QCowHeader;
                     84: 
                     85: typedef struct QCowSnapshot {
                     86:     uint64_t l1_table_offset;
                     87:     uint32_t l1_size;
                     88:     char *id_str;
                     89:     char *name;
1.1.1.8 ! root       90:     uint64_t disk_size;
        !            91:     uint64_t vm_state_size;
1.1       root       92:     uint32_t date_sec;
                     93:     uint32_t date_nsec;
                     94:     uint64_t vm_clock_nsec;
                     95: } QCowSnapshot;
                     96: 
1.1.1.5   root       97: struct Qcow2Cache;
                     98: typedef struct Qcow2Cache Qcow2Cache;
                     99: 
1.1.1.8 ! root      100: typedef struct Qcow2UnknownHeaderExtension {
        !           101:     uint32_t magic;
        !           102:     uint32_t len;
        !           103:     QLIST_ENTRY(Qcow2UnknownHeaderExtension) next;
        !           104:     uint8_t data[];
        !           105: } Qcow2UnknownHeaderExtension;
        !           106: 
        !           107: enum {
        !           108:     QCOW2_FEAT_TYPE_INCOMPATIBLE    = 0,
        !           109:     QCOW2_FEAT_TYPE_COMPATIBLE      = 1,
        !           110:     QCOW2_FEAT_TYPE_AUTOCLEAR       = 2,
        !           111: };
        !           112: 
        !           113: typedef struct Qcow2Feature {
        !           114:     uint8_t type;
        !           115:     uint8_t bit;
        !           116:     char    name[46];
        !           117: } QEMU_PACKED Qcow2Feature;
        !           118: 
1.1       root      119: typedef struct BDRVQcowState {
                    120:     int cluster_bits;
                    121:     int cluster_size;
                    122:     int cluster_sectors;
                    123:     int l2_bits;
                    124:     int l2_size;
                    125:     int l1_size;
                    126:     int l1_vm_state_index;
                    127:     int csize_shift;
                    128:     int csize_mask;
                    129:     uint64_t cluster_offset_mask;
                    130:     uint64_t l1_table_offset;
                    131:     uint64_t *l1_table;
1.1.1.5   root      132: 
                    133:     Qcow2Cache* l2_table_cache;
                    134:     Qcow2Cache* refcount_block_cache;
                    135: 
1.1       root      136:     uint8_t *cluster_cache;
                    137:     uint8_t *cluster_data;
                    138:     uint64_t cluster_cache_offset;
1.1.1.2   root      139:     QLIST_HEAD(QCowClusterAlloc, QCowL2Meta) cluster_allocs;
1.1       root      140: 
                    141:     uint64_t *refcount_table;
                    142:     uint64_t refcount_table_offset;
                    143:     uint32_t refcount_table_size;
                    144:     int64_t free_cluster_index;
                    145:     int64_t free_byte_offset;
                    146: 
1.1.1.7   root      147:     CoMutex lock;
                    148: 
1.1       root      149:     uint32_t crypt_method; /* current crypt method, 0 if no key yet */
                    150:     uint32_t crypt_method_header;
                    151:     AES_KEY aes_encrypt_key;
                    152:     AES_KEY aes_decrypt_key;
                    153:     uint64_t snapshots_offset;
                    154:     int snapshots_size;
                    155:     int nb_snapshots;
                    156:     QCowSnapshot *snapshots;
1.1.1.7   root      157: 
                    158:     int flags;
1.1.1.8 ! root      159:     int qcow_version;
        !           160: 
        !           161:     uint64_t incompatible_features;
        !           162:     uint64_t compatible_features;
        !           163:     uint64_t autoclear_features;
        !           164: 
        !           165:     size_t unknown_header_fields_size;
        !           166:     void* unknown_header_fields;
        !           167:     QLIST_HEAD(, Qcow2UnknownHeaderExtension) unknown_header_ext;
1.1       root      168: } BDRVQcowState;
                    169: 
                    170: /* XXX: use std qcow open function ? */
                    171: typedef struct QCowCreateState {
                    172:     int cluster_size;
                    173:     int cluster_bits;
                    174:     uint16_t *refcount_block;
                    175:     uint64_t *refcount_table;
                    176:     int64_t l1_table_offset;
                    177:     int64_t refcount_table_offset;
                    178:     int64_t refcount_block_offset;
                    179: } QCowCreateState;
                    180: 
                    181: struct QCowAIOCB;
                    182: 
                    183: /* XXX This could be private for qcow2-cluster.c */
                    184: typedef struct QCowL2Meta
                    185: {
                    186:     uint64_t offset;
1.1.1.3   root      187:     uint64_t cluster_offset;
1.1.1.8 ! root      188:     uint64_t alloc_offset;
1.1       root      189:     int n_start;
                    190:     int nb_available;
                    191:     int nb_clusters;
1.1.1.7   root      192:     CoQueue dependent_requests;
1.1       root      193: 
1.1.1.2   root      194:     QLIST_ENTRY(QCowL2Meta) next_in_flight;
1.1       root      195: } QCowL2Meta;
                    196: 
1.1.1.8 ! root      197: enum {
        !           198:     QCOW2_CLUSTER_UNALLOCATED,
        !           199:     QCOW2_CLUSTER_NORMAL,
        !           200:     QCOW2_CLUSTER_COMPRESSED,
        !           201:     QCOW2_CLUSTER_ZERO
        !           202: };
        !           203: 
        !           204: #define L1E_OFFSET_MASK 0x00ffffffffffff00ULL
        !           205: #define L2E_OFFSET_MASK 0x00ffffffffffff00ULL
        !           206: #define L2E_COMPRESSED_OFFSET_SIZE_MASK 0x3fffffffffffffffULL
        !           207: 
        !           208: #define REFT_OFFSET_MASK 0xffffffffffffff00ULL
        !           209: 
1.1       root      210: static inline int size_to_clusters(BDRVQcowState *s, int64_t size)
                    211: {
                    212:     return (size + (s->cluster_size - 1)) >> s->cluster_bits;
                    213: }
                    214: 
1.1.1.4   root      215: static inline int size_to_l1(BDRVQcowState *s, int64_t size)
                    216: {
                    217:     int shift = s->cluster_bits + s->l2_bits;
                    218:     return (size + (1ULL << shift) - 1) >> shift;
                    219: }
                    220: 
1.1       root      221: static inline int64_t align_offset(int64_t offset, int n)
                    222: {
                    223:     offset = (offset + n - 1) & ~(n - 1);
                    224:     return offset;
                    225: }
                    226: 
1.1.1.8 ! root      227: static inline int qcow2_get_cluster_type(uint64_t l2_entry)
        !           228: {
        !           229:     if (l2_entry & QCOW_OFLAG_COMPRESSED) {
        !           230:         return QCOW2_CLUSTER_COMPRESSED;
        !           231:     } else if (l2_entry & QCOW_OFLAG_ZERO) {
        !           232:         return QCOW2_CLUSTER_ZERO;
        !           233:     } else if (!(l2_entry & L2E_OFFSET_MASK)) {
        !           234:         return QCOW2_CLUSTER_UNALLOCATED;
        !           235:     } else {
        !           236:         return QCOW2_CLUSTER_NORMAL;
        !           237:     }
        !           238: }
        !           239: 
1.1       root      240: 
                    241: // FIXME Need qcow2_ prefix to global functions
                    242: 
                    243: /* qcow2.c functions */
1.1.1.5   root      244: int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
                    245:                   int64_t sector_num, int nb_sectors);
1.1.1.8 ! root      246: int qcow2_update_header(BlockDriverState *bs);
1.1       root      247: 
                    248: /* qcow2-refcount.c functions */
                    249: int qcow2_refcount_init(BlockDriverState *bs);
                    250: void qcow2_refcount_close(BlockDriverState *bs);
                    251: 
                    252: int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size);
1.1.1.8 ! root      253: int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
        !           254:     int nb_clusters);
1.1       root      255: int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size);
                    256: void qcow2_free_clusters(BlockDriverState *bs,
                    257:     int64_t offset, int64_t size);
                    258: void qcow2_free_any_clusters(BlockDriverState *bs,
                    259:     uint64_t cluster_offset, int nb_clusters);
                    260: 
                    261: int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                    262:     int64_t l1_table_offset, int l1_size, int addend);
                    263: 
1.1.1.4   root      264: int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res);
1.1       root      265: 
                    266: /* qcow2-cluster.c functions */
1.1.1.5   root      267: int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size);
1.1       root      268: void qcow2_l2_cache_reset(BlockDriverState *bs);
1.1.1.4   root      269: int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
1.1       root      270: void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
                    271:                      uint8_t *out_buf, const uint8_t *in_buf,
                    272:                      int nb_sectors, int enc,
                    273:                      const AES_KEY *key);
                    274: 
1.1.1.4   root      275: int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
                    276:     int *num, uint64_t *cluster_offset);
1.1.1.3   root      277: int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
                    278:     int n_start, int n_end, int *num, QCowL2Meta *m);
1.1       root      279: uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
                    280:                                          uint64_t offset,
                    281:                                          int compressed_size);
                    282: 
1.1.1.3   root      283: int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
1.1.1.5   root      284: int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
                    285:     int nb_sectors);
1.1.1.8 ! root      286: int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors);
1.1       root      287: 
                    288: /* qcow2-snapshot.c functions */
                    289: int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
                    290: int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
                    291: int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
                    292: int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
1.1.1.5   root      293: int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name);
1.1       root      294: 
                    295: void qcow2_free_snapshots(BlockDriverState *bs);
                    296: int qcow2_read_snapshots(BlockDriverState *bs);
                    297: 
1.1.1.5   root      298: /* qcow2-cache.c functions */
                    299: Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
                    300:     bool writethrough);
                    301: int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
1.1.1.6   root      302: bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c,
                    303:     bool enable);
1.1.1.5   root      304: 
                    305: void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
                    306: int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
                    307: int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
                    308:     Qcow2Cache *dependency);
                    309: void qcow2_cache_depends_on_flush(Qcow2Cache *c);
                    310: 
                    311: int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
                    312:     void **table);
                    313: int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
                    314:     void **table);
                    315: int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table);
                    316: 
1.1       root      317: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.