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

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"
                     29: 
                     30: //#define DEBUG_ALLOC
                     31: //#define DEBUG_ALLOC2
                     32: //#define DEBUG_EXT
                     33: 
                     34: #define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
                     35: #define QCOW_VERSION 2
                     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)
                     46: 
                     47: #define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
                     48: 
                     49: #define MIN_CLUSTER_BITS 9
1.1.1.2   root       50: #define MAX_CLUSTER_BITS 21
1.1       root       51: 
                     52: #define L2_CACHE_SIZE 16
                     53: 
1.1.1.5   root       54: /* Must be at least 4 to cover all cases of refcount table growth */
                     55: #define REFCOUNT_CACHE_SIZE 4
                     56: 
1.1.1.6 ! root       57: #define DEFAULT_CLUSTER_SIZE 65536
        !            58: 
1.1       root       59: typedef struct QCowHeader {
                     60:     uint32_t magic;
                     61:     uint32_t version;
                     62:     uint64_t backing_file_offset;
                     63:     uint32_t backing_file_size;
                     64:     uint32_t cluster_bits;
                     65:     uint64_t size; /* in bytes */
                     66:     uint32_t crypt_method;
                     67:     uint32_t l1_size; /* XXX: save number of clusters instead ? */
                     68:     uint64_t l1_table_offset;
                     69:     uint64_t refcount_table_offset;
                     70:     uint32_t refcount_table_clusters;
                     71:     uint32_t nb_snapshots;
                     72:     uint64_t snapshots_offset;
                     73: } QCowHeader;
                     74: 
                     75: typedef struct QCowSnapshot {
                     76:     uint64_t l1_table_offset;
                     77:     uint32_t l1_size;
                     78:     char *id_str;
                     79:     char *name;
                     80:     uint32_t vm_state_size;
                     81:     uint32_t date_sec;
                     82:     uint32_t date_nsec;
                     83:     uint64_t vm_clock_nsec;
                     84: } QCowSnapshot;
                     85: 
1.1.1.5   root       86: struct Qcow2Cache;
                     87: typedef struct Qcow2Cache Qcow2Cache;
                     88: 
1.1       root       89: typedef struct BDRVQcowState {
                     90:     int cluster_bits;
                     91:     int cluster_size;
                     92:     int cluster_sectors;
                     93:     int l2_bits;
                     94:     int l2_size;
                     95:     int l1_size;
                     96:     int l1_vm_state_index;
                     97:     int csize_shift;
                     98:     int csize_mask;
                     99:     uint64_t cluster_offset_mask;
                    100:     uint64_t l1_table_offset;
                    101:     uint64_t *l1_table;
1.1.1.5   root      102: 
                    103:     Qcow2Cache* l2_table_cache;
                    104:     Qcow2Cache* refcount_block_cache;
                    105: 
1.1       root      106:     uint8_t *cluster_cache;
                    107:     uint8_t *cluster_data;
                    108:     uint64_t cluster_cache_offset;
1.1.1.2   root      109:     QLIST_HEAD(QCowClusterAlloc, QCowL2Meta) cluster_allocs;
1.1       root      110: 
                    111:     uint64_t *refcount_table;
                    112:     uint64_t refcount_table_offset;
                    113:     uint32_t refcount_table_size;
                    114:     int64_t free_cluster_index;
                    115:     int64_t free_byte_offset;
                    116: 
                    117:     uint32_t crypt_method; /* current crypt method, 0 if no key yet */
                    118:     uint32_t crypt_method_header;
                    119:     AES_KEY aes_encrypt_key;
                    120:     AES_KEY aes_decrypt_key;
                    121:     uint64_t snapshots_offset;
                    122:     int snapshots_size;
                    123:     int nb_snapshots;
                    124:     QCowSnapshot *snapshots;
                    125: } BDRVQcowState;
                    126: 
                    127: /* XXX: use std qcow open function ? */
                    128: typedef struct QCowCreateState {
                    129:     int cluster_size;
                    130:     int cluster_bits;
                    131:     uint16_t *refcount_block;
                    132:     uint64_t *refcount_table;
                    133:     int64_t l1_table_offset;
                    134:     int64_t refcount_table_offset;
                    135:     int64_t refcount_block_offset;
                    136: } QCowCreateState;
                    137: 
                    138: struct QCowAIOCB;
                    139: 
                    140: /* XXX This could be private for qcow2-cluster.c */
                    141: typedef struct QCowL2Meta
                    142: {
                    143:     uint64_t offset;
1.1.1.3   root      144:     uint64_t cluster_offset;
1.1       root      145:     int n_start;
                    146:     int nb_available;
                    147:     int nb_clusters;
                    148:     struct QCowL2Meta *depends_on;
1.1.1.2   root      149:     QLIST_HEAD(QCowAioDependencies, QCowAIOCB) dependent_requests;
1.1       root      150: 
1.1.1.2   root      151:     QLIST_ENTRY(QCowL2Meta) next_in_flight;
1.1       root      152: } QCowL2Meta;
                    153: 
                    154: static inline int size_to_clusters(BDRVQcowState *s, int64_t size)
                    155: {
                    156:     return (size + (s->cluster_size - 1)) >> s->cluster_bits;
                    157: }
                    158: 
1.1.1.4   root      159: static inline int size_to_l1(BDRVQcowState *s, int64_t size)
                    160: {
                    161:     int shift = s->cluster_bits + s->l2_bits;
                    162:     return (size + (1ULL << shift) - 1) >> shift;
                    163: }
                    164: 
1.1       root      165: static inline int64_t align_offset(int64_t offset, int n)
                    166: {
                    167:     offset = (offset + n - 1) & ~(n - 1);
                    168:     return offset;
                    169: }
                    170: 
                    171: 
                    172: // FIXME Need qcow2_ prefix to global functions
                    173: 
                    174: /* qcow2.c functions */
1.1.1.5   root      175: int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
                    176:                   int64_t sector_num, int nb_sectors);
1.1       root      177: 
                    178: /* qcow2-refcount.c functions */
                    179: int qcow2_refcount_init(BlockDriverState *bs);
                    180: void qcow2_refcount_close(BlockDriverState *bs);
                    181: 
                    182: int64_t qcow2_alloc_clusters(BlockDriverState *bs, int64_t size);
                    183: int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size);
                    184: void qcow2_free_clusters(BlockDriverState *bs,
                    185:     int64_t offset, int64_t size);
                    186: void qcow2_free_any_clusters(BlockDriverState *bs,
                    187:     uint64_t cluster_offset, int nb_clusters);
                    188: 
                    189: void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
                    190:     int64_t size);
                    191: int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                    192:     int64_t l1_table_offset, int l1_size, int addend);
                    193: 
1.1.1.4   root      194: int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res);
1.1       root      195: 
                    196: /* qcow2-cluster.c functions */
1.1.1.5   root      197: int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size);
1.1       root      198: void qcow2_l2_cache_reset(BlockDriverState *bs);
1.1.1.4   root      199: int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
1.1       root      200: void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
                    201:                      uint8_t *out_buf, const uint8_t *in_buf,
                    202:                      int nb_sectors, int enc,
                    203:                      const AES_KEY *key);
                    204: 
1.1.1.4   root      205: int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
                    206:     int *num, uint64_t *cluster_offset);
1.1.1.3   root      207: int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
                    208:     int n_start, int n_end, int *num, QCowL2Meta *m);
1.1       root      209: uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
                    210:                                          uint64_t offset,
                    211:                                          int compressed_size);
                    212: 
1.1.1.3   root      213: int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
1.1.1.5   root      214: int qcow2_discard_clusters(BlockDriverState *bs, uint64_t offset,
                    215:     int nb_sectors);
1.1       root      216: 
                    217: /* qcow2-snapshot.c functions */
                    218: int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
                    219: int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
                    220: int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
                    221: int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
1.1.1.5   root      222: int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name);
1.1       root      223: 
                    224: void qcow2_free_snapshots(BlockDriverState *bs);
                    225: int qcow2_read_snapshots(BlockDriverState *bs);
                    226: 
1.1.1.5   root      227: /* qcow2-cache.c functions */
                    228: Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
                    229:     bool writethrough);
                    230: int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
1.1.1.6 ! root      231: bool qcow2_cache_set_writethrough(BlockDriverState *bs, Qcow2Cache *c,
        !           232:     bool enable);
1.1.1.5   root      233: 
                    234: void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table);
                    235: int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
                    236: int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
                    237:     Qcow2Cache *dependency);
                    238: void qcow2_cache_depends_on_flush(Qcow2Cache *c);
                    239: 
                    240: int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
                    241:     void **table);
                    242: int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset,
                    243:     void **table);
                    244: int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table);
                    245: 
1.1       root      246: #endif

unix.superglobalmegacorp.com

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