Changeset 77924 in vbox for trunk/src/VBox/Storage
- Timestamp:
- Mar 27, 2019 6:43:10 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 129637
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/QCOW.cpp
r77921 r77924 37 37 /** @page pg_storage_qcow QCOW Storage Backend 38 38 * The QCOW backend implements support for the qemu copy on write format (short QCOW). 39 * There is no official specification available but the format is described 40 * at http://people.gnome.org/~markmc/qcow-image-format.html for version 2 41 * and http://people.gnome.org/~markmc/qcow-image-format-version-1.html for version 1. 39 * 40 * The official specification for qcow is available at 41 * https://github.com/qemu/qemu/blob/master/docs/interop/qcow2.txt version 2 and 3. 42 * For version 1 there is no official specification available but the format is described 43 * at http://people.gnome.org/~markmc/qcow-image-format-version-1.html. 42 44 * 43 45 * Missing things to implement: … … 86 88 uint64_t u64L1TableOffset; 87 89 } v1; 88 /** Version 2 . */90 /** Version 2 (and also containing extensions for version 3). */ 89 91 struct 90 92 { … … 111 113 /** Offset of the first snapshot header in the image. */ 112 114 uint64_t u64SnapshotsOffset; 115 /** Version 3 additional data. */ 116 struct 117 { 118 /** Incompatible features. */ 119 uint64_t u64IncompatFeat; 120 /** Compatible features. */ 121 uint64_t u64CompatFeat; 122 /** Autoclear features. */ 123 uint64_t u64AutoClrFeat; 124 /** Width in bits of a reference count block. */ 125 uint32_t u32RefCntWidth; 126 /** Lenght of the header structure in bytes (for the header extensions). */ 127 uint32_t u32HdrLenBytes; 128 } v3; 113 129 } v2; 114 130 } Version; … … 134 150 /** The mask for extracting the offset from either the L1 or L2 table. */ 135 151 #define QCOW_V2_TBL_OFFSET_MASK UINT64_C(0x00fffffffffffe00) 152 153 /** Incompatible feature: Dirty bit, reference count may be inconsistent. */ 154 #define QCOW_V3_INCOMPAT_FEAT_F_DIRTY RT_BIT_64(0) 155 /** Incompatible feature: Image is corrupt and needs repair. */ 156 #define QCOW_V3_INCOMPAT_FEAT_F_CORRUPT RT_BIT_64(1) 157 /** Incompatible feature: External data file. */ 158 #define QCOW_V3_INCOMPAT_FEAT_F_EXTERNAL_DATA RT_BIT_64(2) 159 /** The incompatible features we support currently. */ 160 #define QCOW_V3_INCOMPAT_FEAT_SUPPORTED_MASK UINT64_C(0x0) 161 162 /** Compatible feature: Lazy reference counters. */ 163 #define QCOW_V3_COMPAT_FEAT_F_LAZY_REF_COUNT RT_BIT_64(0) 164 /** The compatible features we support currently. */ 165 #define QCOW_V3_COMPAT_FEAT_SUPPORTED_MASK UINT64_C(0x0) 166 167 /** Auto clear feature: Bitmaps extension. */ 168 #define QCOW_V3_AUTOCLR_FEAT_F_BITMAPS RT_BIT_64(0) 169 /** Auto clear feature: The external data file is raw image which can be accessed standalone. */ 170 #define QCOW_V3_AUTOCLR_FEAT_F_EXT_RAW_DATA RT_BIT_64(1) 171 /** The autoclear features we support currently. */ 172 #define QCOW_V3_AUTOCLR_FEAT_SUPPORTED_MASK UINT64_C(0x0) 136 173 137 174 … … 359 396 pHeader->Version.v1.u64L1TableOffset = RT_BE2H_U64(pHeader->Version.v1.u64L1TableOffset); 360 397 } 361 else if (pHeader->u32Version == 2 )398 else if (pHeader->u32Version == 2 || pHeader->u32Version == 3) 362 399 { 363 400 pHeader->Version.v2.u64BackingFileOffset = RT_BE2H_U64(pHeader->Version.v2.u64BackingFileOffset); … … 372 409 pHeader->Version.v2.u32NbSnapshots = RT_BE2H_U32(pHeader->Version.v2.u32NbSnapshots); 373 410 pHeader->Version.v2.u64SnapshotsOffset = RT_BE2H_U64(pHeader->Version.v2.u64SnapshotsOffset); 411 412 if (pHeader->u32Version == 3) 413 { 414 pHeader->Version.v2.v3.u64IncompatFeat = RT_BE2H_U64(pHeader->Version.v2.v3.u64IncompatFeat); 415 pHeader->Version.v2.v3.u64CompatFeat = RT_BE2H_U64(pHeader->Version.v2.v3.u64CompatFeat); 416 pHeader->Version.v2.v3.u64AutoClrFeat = RT_BE2H_U64(pHeader->Version.v2.v3.u64AutoClrFeat); 417 pHeader->Version.v2.v3.u32RefCntWidth = RT_BE2H_U32(pHeader->Version.v2.v3.u32RefCntWidth); 418 pHeader->Version.v2.v3.u32HdrLenBytes = RT_BE2H_U32(pHeader->Version.v2.v3.u32HdrLenBytes); 419 } 374 420 } 375 421 else … … 1031 1077 pImage->pszFilename); 1032 1078 } 1033 else if (pHdr->u32Version == 2 )1079 else if (pHdr->u32Version == 2 || pHdr->u32Version == 3) 1034 1080 { 1035 1081 /* Check that the backing filename is contained in the file. */ … … 1045 1091 N_("QCOW: Cluster size is too small for image '%s' (%u vs %u)"), 1046 1092 pImage->pszFilename, RT_BIT_32(pHdr->Version.v2.u32ClusterBits), 512); 1093 1094 /* Some additional checks for v3 images. */ 1095 if (pHdr->u32Version == 3) 1096 { 1097 if (pHdr->Version.v2.v3.u32RefCntWidth > 6) 1098 return vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1099 N_("QCOW: Reference count width too big for image '%s' (%u vs %u)"), 1100 pImage->pszFilename, RT_BIT_32(pHdr->Version.v2.v3.u32RefCntWidth), 6); 1101 } 1047 1102 } 1048 1103 else … … 1114 1169 pImage->pszFilename); 1115 1170 } 1116 else if (Header.u32Version == 2 )1171 else if (Header.u32Version == 2 || Header.u32Version == 3) 1117 1172 { 1118 1173 if (Header.Version.v2.u32CryptMethod) … … 1138 1193 pImage->cbRefcountTable = qcowCluster2Byte(pImage, Header.Version.v2.u32RefcountTableClusters); 1139 1194 pImage->cRefcountTableEntries = pImage->cbRefcountTable / sizeof(uint64_t); 1195 1196 if (Header.u32Version == 3) 1197 { 1198 if (Header.Version.v2.v3.u64IncompatFeat & ~QCOW_V3_INCOMPAT_FEAT_SUPPORTED_MASK) 1199 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS, 1200 N_("QCow: Image '%s' contains unsupported incompatible features (%llx vs %llx)"), 1201 pImage->pszFilename, Header.Version.v2.v3.u64IncompatFeat, QCOW_V3_INCOMPAT_FEAT_SUPPORTED_MASK); 1202 1203 /** @todo Auto clear features need to be reset as soon as write support is added. */ 1204 } 1140 1205 } 1141 1206 } … … 1145 1210 pImage->pszFilename, Header.u32Version); 1146 1211 1147 pImage->cbL1Table = RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster); 1148 if ((uint64_t)pImage->cbL1Table != RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster)) 1149 rc = vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1150 N_("QCOW: L1 table size overflow in image '%s'"), 1151 pImage->pszFilename); 1212 if (RT_SUCCESS(rc)) 1213 { 1214 pImage->cbL1Table = RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster); 1215 if ((uint64_t)pImage->cbL1Table != RT_ALIGN_64(pImage->cL1TableEntries * sizeof(uint64_t), pImage->cbCluster)) 1216 rc = vdIfError(pImage->pIfError, VERR_INVALID_STATE, RT_SRC_POS, 1217 N_("QCOW: L1 table size overflow in image '%s'"), 1218 pImage->pszFilename); 1219 } 1152 1220 } 1153 1221
Note:
See TracChangeset
for help on using the changeset viewer.