- 時間撮記:
- 2012-6-15 下午06:40:36 (12 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Storage/VMDK.cpp
r40843 r41767 1099 1099 /* Check grain table and redundant grain table for consistency. */ 1100 1100 size_t cbGT = pExtent->cGTEntries * sizeof(uint32_t); 1101 uint32_t *pTmpGT1 = (uint32_t *)RTMemTmpAlloc(cbGT); 1102 if (!pTmpGT1) 1103 { 1101 size_t cbGTBuffers = cbGT; /* Start with space for one GT. */ 1102 size_t cbGTBuffersMax = _1M; 1103 1104 uint32_t *pTmpGT1 = (uint32_t *)RTMemAlloc(cbGTBuffers); 1105 uint32_t *pTmpGT2 = (uint32_t *)RTMemAlloc(cbGTBuffers); 1106 1107 if ( !pTmpGT1 1108 || !pTmpGT2) 1104 1109 rc = VERR_NO_MEMORY; 1105 goto out; 1106 } 1107 uint32_t *pTmpGT2 = (uint32_t *)RTMemTmpAlloc(cbGT); 1108 if (!pTmpGT2) 1109 { 1110 RTMemTmpFree(pTmpGT1); 1111 rc = VERR_NO_MEMORY; 1112 goto out; 1113 } 1114 1115 for (i = 0, pGDTmp = pExtent->pGD, pRGDTmp = pExtent->pRGD; 1116 i < pExtent->cGDEntries; 1117 i++, pGDTmp++, pRGDTmp++) 1118 { 1110 1111 i = 0; 1112 pGDTmp = pExtent->pGD; 1113 pRGDTmp = pExtent->pRGD; 1114 1115 /* Loop through all entries. */ 1116 while (i < pExtent->cGDEntries) 1117 { 1118 uint32_t uGTStart = *pGDTmp; 1119 uint32_t uRGTStart = *pRGDTmp; 1120 uint32_t cbGTRead = cbGT; 1121 1119 1122 /* If no grain table is allocated skip the entry. */ 1120 1123 if (*pGDTmp == 0 && *pRGDTmp == 0) 1124 { 1125 i++; 1121 1126 continue; 1127 } 1122 1128 1123 1129 if (*pGDTmp == 0 || *pRGDTmp == 0 || *pGDTmp == *pRGDTmp) … … 1126 1132 * grain table or both grain directory copies refer to the same 1127 1133 * grain table. Not allowed. */ 1128 RTMemTmpFree(pTmpGT1);1129 RTMemTmpFree(pTmpGT2);1130 1134 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistent references to grain directory in '%s'"), pExtent->pszFullname); 1131 goto out;1135 break; 1132 1136 } 1133 /* The VMDK 1.1 spec seems to talk about compressed grain tables, 1134 * but in reality they are not compressed. */ 1135 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage, 1136 VMDK_SECTOR2BYTE(*pGDTmp), 1137 pTmpGT1, cbGT, NULL); 1138 if (RT_FAILURE(rc)) 1137 1138 i++; 1139 pGDTmp++; 1140 pRGDTmp++; 1141 1142 /* 1143 * Read a few tables at once if adjacent to decrease the number 1144 * of I/O requests. Read at maximum 1MB at once. 1145 */ 1146 while ( i < pExtent->cGDEntries 1147 && cbGTRead < cbGTBuffersMax) 1139 1148 { 1140 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading grain table in '%s'"), pExtent->pszFullname); 1141 RTMemTmpFree(pTmpGT1); 1142 RTMemTmpFree(pTmpGT2); 1143 goto out; 1149 /* If no grain table is allocated skip the entry. */ 1150 if (*pGDTmp == 0 && *pRGDTmp == 0) 1151 continue; 1152 1153 if (*pGDTmp == 0 || *pRGDTmp == 0 || *pGDTmp == *pRGDTmp) 1154 { 1155 /* Just one grain directory entry refers to a not yet allocated 1156 * grain table or both grain directory copies refer to the same 1157 * grain table. Not allowed. */ 1158 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistent references to grain directory in '%s'"), pExtent->pszFullname); 1159 break; 1160 } 1161 1162 /* Check that the start offsets are adjacent.*/ 1163 if ( VMDK_SECTOR2BYTE(uGTStart) + cbGTRead != VMDK_SECTOR2BYTE(*pGDTmp) 1164 || VMDK_SECTOR2BYTE(uRGTStart) + cbGTRead != VMDK_SECTOR2BYTE(*pRGDTmp)) 1165 break; 1166 1167 i++; 1168 pGDTmp++; 1169 pRGDTmp++; 1170 cbGTRead += cbGT; 1144 1171 } 1145 /* The VMDK 1.1 spec seems to talk about compressed grain tables, 1146 * but in reality they are not compressed. */ 1147 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage, 1148 VMDK_SECTOR2BYTE(*pRGDTmp), 1149 pTmpGT2, cbGT, NULL); 1150 if (RT_FAILURE(rc)) 1172 1173 /* Increase buffers if required. */ 1174 if ( RT_SUCCESS(rc) 1175 && cbGTBuffers < cbGTRead) 1151 1176 { 1152 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VMDK: error reading backup grain table in '%s'"), pExtent->pszFullname); 1153 RTMemTmpFree(pTmpGT1); 1154 RTMemTmpFree(pTmpGT2); 1155 goto out; 1177 uint32_t *pTmp; 1178 pTmp = (uint32_t *)RTMemRealloc(pTmpGT1, cbGTRead); 1179 if (pTmp) 1180 { 1181 pTmpGT1 = pTmp; 1182 pTmp = (uint32_t *)RTMemRealloc(pTmpGT2, cbGTRead); 1183 if (pTmp) 1184 pTmpGT2 = pTmp; 1185 else 1186 rc = VERR_NO_MEMORY; 1187 } 1188 else 1189 rc = VERR_NO_MEMORY; 1190 1191 if (rc == VERR_NO_MEMORY) 1192 { 1193 /* Reset to the old values. */ 1194 rc = VINF_SUCCESS; 1195 i -= cbGTRead / cbGT; 1196 cbGTRead = cbGT; 1197 1198 /* Don't try to increase the buffer again in the next run. */ 1199 cbGTBuffersMax = cbGTBuffers; 1200 } 1156 1201 } 1157 if (memcmp(pTmpGT1, pTmpGT2, cbGT)) 1202 1203 if (RT_SUCCESS(rc)) 1158 1204 { 1159 RTMemTmpFree(pTmpGT1); 1160 RTMemTmpFree(pTmpGT2); 1161 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: inconsistency between grain table and backup grain table in '%s'"), pExtent->pszFullname); 1162 goto out; 1205 /* The VMDK 1.1 spec seems to talk about compressed grain tables, 1206 * but in reality they are not compressed. */ 1207 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage, 1208 VMDK_SECTOR2BYTE(uGTStart), 1209 pTmpGT1, cbGTRead, NULL); 1210 if (RT_FAILURE(rc)) 1211 { 1212 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, 1213 N_("VMDK: error reading grain table in '%s'"), pExtent->pszFullname); 1214 break; 1215 } 1216 /* The VMDK 1.1 spec seems to talk about compressed grain tables, 1217 * but in reality they are not compressed. */ 1218 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pExtent->pFile->pStorage, 1219 VMDK_SECTOR2BYTE(uRGTStart), 1220 pTmpGT2, cbGTRead, NULL); 1221 if (RT_FAILURE(rc)) 1222 { 1223 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, 1224 N_("VMDK: error reading backup grain table in '%s'"), pExtent->pszFullname); 1225 break; 1226 } 1227 if (memcmp(pTmpGT1, pTmpGT2, cbGTRead)) 1228 { 1229 rc = vdIfError(pImage->pIfError, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, 1230 N_("VMDK: inconsistency between grain table and backup grain table in '%s'"), pExtent->pszFullname); 1231 break; 1232 } 1163 1233 } 1164 } 1234 } /* while (i < pExtent->cGDEntries) */ 1165 1235 1166 1236 /** @todo figure out what to do for unclean VMDKs. */ 1167 RTMemTmpFree(pTmpGT1); 1168 RTMemTmpFree(pTmpGT2); 1237 if (pTmpGT1) 1238 RTMemFree(pTmpGT1); 1239 if (pTmpGT2) 1240 RTMemFree(pTmpGT2); 1169 1241 } 1170 1242 … … 1181 1253 unsigned i; 1182 1254 size_t cbGD = pExtent->cGDEntries * sizeof(uint32_t); 1183 size_t cbGDRounded = RT_ALIGN_64( pExtent->cGDEntries * sizeof(uint32_t), 512);1255 size_t cbGDRounded = RT_ALIGN_64(cbGD, 512); 1184 1256 size_t cbGTRounded; 1185 1257 uint64_t cbOverhead;
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器