Changeset 63792 in vbox
- Timestamp:
- Sep 12, 2016 9:34:28 AM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 110616
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/QED.cpp
r63789 r63792 853 853 854 854 /** 855 * Flush image data to disk - version for async I/O.856 *857 * @returns VBox status code.858 * @param pImage The image instance data.859 * @param pIoCtx The I/o context860 */861 static int qedFlushImageAsync(PQEDIMAGE pImage, PVDIOCTX pIoCtx)862 {863 int rc = VINF_SUCCESS;864 865 if ( pImage->pStorage866 && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))867 {868 QedHeader Header;869 870 Assert(!(pImage->cbTable % pImage->cbCluster));871 rc = qedTblWrite(pImage, pIoCtx, pImage->offL1Table, pImage->paL1Table,872 NULL, NULL);873 if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS)874 {875 /* Write header. */876 qedHdrConvertFromHostEndianess(pImage, &Header);877 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage,878 0, &Header, sizeof(Header),879 pIoCtx, NULL, NULL);880 if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS)881 rc = vdIfIoIntFileFlush(pImage->pIfIo, pImage->pStorage,882 pIoCtx, NULL, NULL);883 }884 }885 886 return rc;887 }888 889 /**890 855 * Checks whether the given cluster offset is valid. 891 856 * … … 1151 1116 static int qedOpenImage(PQEDIMAGE pImage, unsigned uOpenFlags) 1152 1117 { 1153 int rc;1154 1155 1118 pImage->uOpenFlags = uOpenFlags; 1156 1119 … … 1163 1126 * even if opening the image file fails. 1164 1127 */ 1165 rc = qedL2TblCacheCreate(pImage); 1166 if (RT_FAILURE(rc)) 1167 { 1128 int rc = qedL2TblCacheCreate(pImage); 1129 if (RT_SUCCESS(rc)) 1130 { 1131 /* Open the image. */ 1132 rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, 1133 VDOpenFlagsToFileOpenFlags(uOpenFlags, 1134 false /* fCreate */), 1135 &pImage->pStorage); 1136 if (RT_SUCCESS(rc)) 1137 { 1138 uint64_t cbFile; 1139 rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile); 1140 if ( RT_SUCCESS(rc) 1141 && cbFile > sizeof(QedHeader)) 1142 { 1143 QedHeader Header; 1144 1145 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0, &Header, sizeof(Header)); 1146 if ( RT_SUCCESS(rc) 1147 && qedHdrConvertToHostEndianess(&Header)) 1148 { 1149 if ( !(Header.u64FeatureFlags & ~QED_FEATURE_MASK) 1150 && !(Header.u64FeatureFlags & QED_FEATURE_BACKING_FILE_NO_PROBE)) 1151 { 1152 if (Header.u64FeatureFlags & QED_FEATURE_NEED_CHECK) 1153 { 1154 /* Image needs checking. */ 1155 if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY)) 1156 rc = qedCheckImage(pImage, &Header); 1157 else 1158 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS, 1159 N_("Qed: Image '%s' needs checking but is opened readonly"), 1160 pImage->pszFilename); 1161 } 1162 1163 if ( RT_SUCCESS(rc) 1164 && (Header.u64FeatureFlags & QED_FEATURE_BACKING_FILE)) 1165 { 1166 /* Load backing filename from image. */ 1167 pImage->pszBackingFilename = (char *)RTMemAllocZ(Header.u32BackingFilenameSize + 1); /* +1 for \0 terminator. */ 1168 if (pImage->pszBackingFilename) 1169 { 1170 pImage->cbBackingFilename = Header.u32BackingFilenameSize; 1171 pImage->offBackingFilename = Header.u32OffBackingFilename; 1172 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 1173 Header.u32OffBackingFilename, pImage->pszBackingFilename, 1174 Header.u32BackingFilenameSize); 1175 } 1176 else 1177 rc = VERR_NO_MEMORY; 1178 } 1179 1180 if (RT_SUCCESS(rc)) 1181 { 1182 pImage->cbImage = cbFile; 1183 pImage->cbCluster = Header.u32ClusterSize; 1184 pImage->cbTable = Header.u32TableSize * pImage->cbCluster; 1185 pImage->cTableEntries = pImage->cbTable / sizeof(uint64_t); 1186 pImage->offL1Table = Header.u64OffL1Table; 1187 pImage->cbSize = Header.u64Size; 1188 qedTableMasksInit(pImage); 1189 1190 /* Allocate L1 table. */ 1191 pImage->paL1Table = (uint64_t *)RTMemAllocZ(pImage->cbTable); 1192 if (pImage->paL1Table) 1193 { 1194 /* Read from the image. */ 1195 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 1196 pImage->offL1Table, pImage->paL1Table, 1197 pImage->cbTable); 1198 if (RT_SUCCESS(rc)) 1199 { 1200 qedTableConvertToHostEndianess(pImage->paL1Table, pImage->cTableEntries); 1201 1202 /* If the consistency check succeeded, clear the flag by flushing the image. */ 1203 if (Header.u64FeatureFlags & QED_FEATURE_NEED_CHECK) 1204 rc = qedFlushImage(pImage); 1205 } 1206 else 1207 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, 1208 N_("Qed: Reading the L1 table for image '%s' failed"), 1209 pImage->pszFilename); 1210 } 1211 else 1212 rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS, 1213 N_("Qed: Out of memory allocating L1 table for image '%s'"), 1214 pImage->pszFilename); 1215 } 1216 } 1217 else 1218 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS, 1219 N_("Qed: The image '%s' makes use of unsupported features"), 1220 pImage->pszFilename); 1221 } 1222 else if (RT_SUCCESS(rc)) 1223 rc = VERR_VD_GEN_INVALID_HEADER; 1224 } 1225 else if (RT_SUCCESS(rc)) 1226 rc = VERR_VD_GEN_INVALID_HEADER; 1227 } 1228 /* else: Do NOT signal an appropriate error here, as the VD layer has the 1229 * choice of retrying the open if it failed. */ 1230 } 1231 else 1168 1232 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, 1169 1233 N_("Qed: Creating the L2 table cache for image '%s' failed"), 1170 1234 pImage->pszFilename); 1171 1235 1172 goto out;1173 }1174 1175 /*1176 * Open the image.1177 */1178 rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename,1179 VDOpenFlagsToFileOpenFlags(uOpenFlags,1180 false /* fCreate */),1181 &pImage->pStorage);1182 if (RT_FAILURE(rc))1183 {1184 /* Do NOT signal an appropriate error here, as the VD layer has the1185 * choice of retrying the open if it failed. */1186 goto out;1187 }1188 1189 uint64_t cbFile;1190 QedHeader Header;1191 rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile);1192 if (RT_FAILURE(rc))1193 goto out;1194 if (cbFile > sizeof(Header))1195 {1196 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0, &Header, sizeof(Header));1197 if ( RT_SUCCESS(rc)1198 && qedHdrConvertToHostEndianess(&Header))1199 {1200 if ( !(Header.u64FeatureFlags & ~QED_FEATURE_MASK)1201 && !(Header.u64FeatureFlags & QED_FEATURE_BACKING_FILE_NO_PROBE))1202 {1203 if (Header.u64FeatureFlags & QED_FEATURE_NEED_CHECK)1204 {1205 /* Image needs checking. */1206 if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY))1207 rc = qedCheckImage(pImage, &Header);1208 else1209 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,1210 N_("Qed: Image '%s' needs checking but is opened readonly"),1211 pImage->pszFilename);1212 }1213 1214 if ( RT_SUCCESS(rc)1215 && (Header.u64FeatureFlags & QED_FEATURE_BACKING_FILE))1216 {1217 /* Load backing filename from image. */1218 pImage->pszBackingFilename = (char *)RTMemAllocZ(Header.u32BackingFilenameSize + 1); /* +1 for \0 terminator. */1219 if (pImage->pszBackingFilename)1220 {1221 pImage->cbBackingFilename = Header.u32BackingFilenameSize;1222 pImage->offBackingFilename = Header.u32OffBackingFilename;1223 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage,1224 Header.u32OffBackingFilename, pImage->pszBackingFilename,1225 Header.u32BackingFilenameSize);1226 }1227 else1228 rc = VERR_NO_MEMORY;1229 }1230 1231 if (RT_SUCCESS(rc))1232 {1233 pImage->cbImage = cbFile;1234 pImage->cbCluster = Header.u32ClusterSize;1235 pImage->cbTable = Header.u32TableSize * pImage->cbCluster;1236 pImage->cTableEntries = pImage->cbTable / sizeof(uint64_t);1237 pImage->offL1Table = Header.u64OffL1Table;1238 pImage->cbSize = Header.u64Size;1239 qedTableMasksInit(pImage);1240 1241 /* Allocate L1 table. */1242 pImage->paL1Table = (uint64_t *)RTMemAllocZ(pImage->cbTable);1243 if (pImage->paL1Table)1244 {1245 /* Read from the image. */1246 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage,1247 pImage->offL1Table, pImage->paL1Table,1248 pImage->cbTable);1249 if (RT_SUCCESS(rc))1250 {1251 qedTableConvertToHostEndianess(pImage->paL1Table, pImage->cTableEntries);1252 1253 /* If the consistency check succeeded, clear the flag by flushing the image. */1254 if (Header.u64FeatureFlags & QED_FEATURE_NEED_CHECK)1255 rc = qedFlushImage(pImage);1256 }1257 else1258 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,1259 N_("Qed: Reading the L1 table for image '%s' failed"),1260 pImage->pszFilename);1261 }1262 else1263 rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS,1264 N_("Qed: Out of memory allocating L1 table for image '%s'"),1265 pImage->pszFilename);1266 }1267 }1268 else1269 rc = vdIfError(pImage->pIfError, VERR_NOT_SUPPORTED, RT_SRC_POS,1270 N_("Qed: The image '%s' makes use of unsupported features"),1271 pImage->pszFilename);1272 }1273 else if (RT_SUCCESS(rc))1274 rc = VERR_VD_GEN_INVALID_HEADER;1275 }1276 else1277 rc = VERR_VD_GEN_INVALID_HEADER;1278 1279 out:1280 1236 if (RT_FAILURE(rc)) 1281 1237 qedFreeImage(pImage, false); … … 1290 1246 PCVDGEOMETRY pPCHSGeometry, 1291 1247 PCVDGEOMETRY pLCHSGeometry, unsigned uOpenFlags, 1292 P FNVDPROGRESS pfnProgress, void *pvUser,1248 PVDINTERFACEPROGRESS pIfProgress, 1293 1249 unsigned uPercentStart, unsigned uPercentSpan) 1294 1250 { 1295 1251 RT_NOREF1(pszComment); 1296 1252 int rc; 1297 int32_t fOpen; 1298 1299 if (uImageFlags & VD_IMAGE_FLAGS_FIXED) 1300 { 1253 1254 if (!(uImageFlags & VD_IMAGE_FLAGS_FIXED)) 1255 { 1256 rc = qedL2TblCacheCreate(pImage); 1257 if (RT_SUCCESS(rc)) 1258 { 1259 pImage->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY; 1260 pImage->uImageFlags = uImageFlags; 1261 pImage->PCHSGeometry = *pPCHSGeometry; 1262 pImage->LCHSGeometry = *pLCHSGeometry; 1263 1264 pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk); 1265 pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage); 1266 AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER); 1267 1268 /* Create image file. */ 1269 uint32_t fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */); 1270 rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, fOpen, &pImage->pStorage); 1271 if (RT_SUCCESS(rc)) 1272 { 1273 /* Init image state. */ 1274 pImage->cbSize = cbSize; 1275 pImage->cbCluster = QED_CLUSTER_SIZE_DEFAULT; 1276 pImage->cbTable = qedCluster2Byte(pImage, QED_TABLE_SIZE_DEFAULT); 1277 pImage->cTableEntries = pImage->cbTable / sizeof(uint64_t); 1278 pImage->offL1Table = qedCluster2Byte(pImage, 1); /* Cluster 0 is the header. */ 1279 pImage->cbImage = (1 * pImage->cbCluster) + pImage->cbTable; /* Header + L1 table size. */ 1280 pImage->cbBackingFilename = 0; 1281 pImage->offBackingFilename = 0; 1282 qedTableMasksInit(pImage); 1283 1284 /* Init L1 table. */ 1285 pImage->paL1Table = (uint64_t *)RTMemAllocZ(pImage->cbTable); 1286 if (RT_LIKELY(pImage->paL1Table)) 1287 { 1288 vdIfProgress(pIfProgress, uPercentStart + uPercentSpan * 98 / 100); 1289 rc = qedFlushImage(pImage); 1290 } 1291 else 1292 rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS, N_("Qed: cannot allocate memory for L1 table of image '%s'"), 1293 pImage->pszFilename); 1294 } 1295 else 1296 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Qed: cannot create image '%s'"), pImage->pszFilename); 1297 } 1298 else 1299 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Qed: Failed to create L2 cache for image '%s'"), 1300 pImage->pszFilename); 1301 } 1302 else 1301 1303 rc = vdIfError(pImage->pIfError, VERR_VD_INVALID_TYPE, RT_SRC_POS, N_("Qed: cannot create fixed image '%s'"), pImage->pszFilename); 1302 goto out; 1303 } 1304 1305 pImage->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY; 1306 pImage->uImageFlags = uImageFlags; 1307 pImage->PCHSGeometry = *pPCHSGeometry; 1308 pImage->LCHSGeometry = *pLCHSGeometry; 1309 1310 pImage->pIfError = VDIfErrorGet(pImage->pVDIfsDisk); 1311 pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage); 1312 AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER); 1313 1314 /* Create image file. */ 1315 fOpen = VDOpenFlagsToFileOpenFlags(pImage->uOpenFlags, true /* fCreate */); 1316 rc = vdIfIoIntFileOpen(pImage->pIfIo, pImage->pszFilename, fOpen, &pImage->pStorage); 1317 if (RT_FAILURE(rc)) 1318 { 1319 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Qed: cannot create image '%s'"), pImage->pszFilename); 1320 goto out; 1321 } 1322 1323 /* Init image state. */ 1324 pImage->cbSize = cbSize; 1325 pImage->cbCluster = QED_CLUSTER_SIZE_DEFAULT; 1326 pImage->cbTable = qedCluster2Byte(pImage, QED_TABLE_SIZE_DEFAULT); 1327 pImage->cTableEntries = pImage->cbTable / sizeof(uint64_t); 1328 pImage->offL1Table = qedCluster2Byte(pImage, 1); /* Cluster 0 is the header. */ 1329 pImage->cbImage = (1 * pImage->cbCluster) + pImage->cbTable; /* Header + L1 table size. */ 1330 pImage->cbBackingFilename = 0; 1331 pImage->offBackingFilename = 0; 1332 qedTableMasksInit(pImage); 1333 1334 /* Init L1 table. */ 1335 pImage->paL1Table = (uint64_t *)RTMemAllocZ(pImage->cbTable); 1336 if (!pImage->paL1Table) 1337 { 1338 rc = vdIfError(pImage->pIfError, VERR_NO_MEMORY, RT_SRC_POS, N_("Qed: cannot allocate memory for L1 table of image '%s'"), 1339 pImage->pszFilename); 1340 goto out; 1341 } 1342 1343 rc = qedL2TblCacheCreate(pImage); 1344 if (RT_FAILURE(rc)) 1345 { 1346 rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("Qed: Failed to create L2 cache for image '%s'"), 1347 pImage->pszFilename); 1348 goto out; 1349 } 1350 1351 if (RT_SUCCESS(rc) && pfnProgress) 1352 pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100); 1353 1354 rc = qedFlushImage(pImage); 1355 1356 out: 1357 if (RT_SUCCESS(rc) && pfnProgress) 1358 pfnProgress(pvUser, uPercentStart + uPercentSpan); 1359 1360 if (RT_FAILURE(rc)) 1304 1305 if (RT_SUCCESS(rc)) 1306 vdIfProgress(pIfProgress, uPercentStart + uPercentSpan); 1307 else 1361 1308 qedFreeImage(pImage, rc != VERR_ALREADY_EXISTS); 1309 1362 1310 return rc; 1363 1311 } … … 1514 1462 LogFlowFunc(("pszFilename=\"%s\" pVDIfsDisk=%#p pVDIfsImage=%#p\n", pszFilename, pVDIfsDisk, pVDIfsImage)); 1515 1463 PVDIOSTORAGE pStorage = NULL; 1516 uint64_t cbFile;1517 1464 int rc = VINF_SUCCESS; 1518 1465 … … 1520 1467 PVDINTERFACEIOINT pIfIo = VDIfIoIntGet(pVDIfsImage); 1521 1468 AssertPtrReturn(pIfIo, VERR_INVALID_PARAMETER); 1522 1523 if ( !VALID_PTR(pszFilename) 1524 || !*pszFilename) 1525 { 1526 rc = VERR_INVALID_PARAMETER; 1527 goto out; 1528 } 1469 AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER); 1529 1470 1530 1471 /* … … 1537 1478 if (RT_SUCCESS(rc)) 1538 1479 { 1480 uint64_t cbFile; 1481 1539 1482 rc = vdIfIoIntFileGetSize(pIfIo, pStorage, &cbFile); 1540 1483 if ( RT_SUCCESS(rc) … … 1546 1489 if ( RT_SUCCESS(rc) 1547 1490 && qedHdrConvertToHostEndianess(&Header)) 1548 {1549 1491 *penmType = VDTYPE_HDD; 1550 rc = VINF_SUCCESS;1551 }1552 1492 else 1553 1493 rc = VERR_VD_GEN_INVALID_HEADER; … … 1560 1500 vdIfIoIntFileClose(pIfIo, pStorage); 1561 1501 1562 out:1563 1502 LogFlowFunc(("returns %Rrc\n", rc)); 1564 1503 return rc; … … 1570 1509 VDTYPE enmType, void **ppBackendData) 1571 1510 { 1572 LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p enmType=%u ppBackendData=%#p\n", pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, enmType, ppBackendData)); 1511 RT_NOREF1(enmType); /**< @todo r=klaus make use of the type info. */ 1512 1513 LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p enmType=%u ppBackendData=%#p\n", 1514 pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, enmType, ppBackendData)); 1573 1515 int rc; 1574 PQEDIMAGE pImage;1575 1576 NOREF(enmType); /**< @todo r=klaus make use of the type info. */1577 1516 1578 1517 /* Check open flags. All valid flags are supported. */ 1579 if (uOpenFlags & ~VD_OPEN_FLAGS_MASK)1580 {1581 rc = VERR_INVALID_PARAMETER; 1582 goto out;1583 }1584 1585 /* Check remaining arguments. */1586 if ( !VALID_PTR(pszFilename)1587 || !*pszFilename)1588 {1589 rc = VERR_INVALID_PARAMETER; 1590 goto out;1591 }1592 1593 1594 pImage = (PQEDIMAGE)RTMemAllocZ(sizeof(QEDIMAGE));1595 if (!pImage)1596 {1518 AssertReturn(!(uOpenFlags & ~VD_OPEN_FLAGS_MASK), VERR_INVALID_PARAMETER); 1519 AssertReturn((VALID_PTR(pszFilename) && *pszFilename), VERR_INVALID_PARAMETER); 1520 1521 PQEDIMAGE pImage = (PQEDIMAGE)RTMemAllocZ(sizeof(QEDIMAGE)); 1522 if (RT_LIKELY(pImage)) 1523 { 1524 pImage->pszFilename = pszFilename; 1525 pImage->pStorage = NULL; 1526 pImage->pVDIfsDisk = pVDIfsDisk; 1527 pImage->pVDIfsImage = pVDIfsImage; 1528 1529 rc = qedOpenImage(pImage, uOpenFlags); 1530 if (RT_SUCCESS(rc)) 1531 *ppBackendData = pImage; 1532 else 1533 RTMemFree(pImage); 1534 } 1535 else 1597 1536 rc = VERR_NO_MEMORY; 1598 goto out; 1599 } 1600 pImage->pszFilename = pszFilename; 1601 pImage->pStorage = NULL; 1602 pImage->pVDIfsDisk = pVDIfsDisk; 1603 pImage->pVDIfsImage = pVDIfsImage; 1604 1605 rc = qedOpenImage(pImage, uOpenFlags); 1606 if (RT_SUCCESS(rc)) 1607 *ppBackendData = pImage; 1608 else 1609 RTMemFree(pImage); 1610 1611 out: 1537 1612 1538 LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData)); 1613 1539 return rc; … … 1628 1554 pszFilename, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, enmType, ppBackendData)); 1629 1555 int rc; 1630 PQEDIMAGE pImage;1631 1632 PFNVDPROGRESS pfnProgress = NULL;1633 void *pvUser = NULL;1634 PVDINTERFACEPROGRESS pIfProgress = VDIfProgressGet(pVDIfsOperation);1635 if (pIfProgress)1636 {1637 pfnProgress = pIfProgress->pfnProgress;1638 pvUser = pIfProgress->Core.pvUser;1639 }1640 1556 1641 1557 /* Check the VD container type. */ 1642 1558 if (enmType != VDTYPE_HDD) 1643 { 1644 rc = VERR_VD_INVALID_TYPE; 1645 goto out; 1646 } 1559 return VERR_VD_INVALID_TYPE; 1647 1560 1648 1561 /* Check open flags. All valid flags are supported. */ 1649 if (uOpenFlags & ~VD_OPEN_FLAGS_MASK) 1650 { 1651 rc = VERR_INVALID_PARAMETER; 1652 goto out; 1653 } 1654 1655 /* Check remaining arguments. */ 1656 if ( !VALID_PTR(pszFilename) 1657 || !*pszFilename 1658 || !VALID_PTR(pPCHSGeometry) 1659 || !VALID_PTR(pLCHSGeometry)) 1660 { 1661 rc = VERR_INVALID_PARAMETER; 1662 goto out; 1663 } 1664 1665 pImage = (PQEDIMAGE)RTMemAllocZ(sizeof(QEDIMAGE)); 1666 if (!pImage) 1667 { 1562 AssertReturn(!(uOpenFlags & ~VD_OPEN_FLAGS_MASK), VERR_INVALID_PARAMETER); 1563 AssertReturn( VALID_PTR(pszFilename) 1564 && *pszFilename 1565 && VALID_PTR(pPCHSGeometry) 1566 && VALID_PTR(pLCHSGeometry), VERR_INVALID_PARAMETER); 1567 1568 PQEDIMAGE pImage = (PQEDIMAGE)RTMemAllocZ(sizeof(QEDIMAGE)); 1569 if (RT_LIKELY(pImage)) 1570 { 1571 PVDINTERFACEPROGRESS pIfProgress = VDIfProgressGet(pVDIfsOperation); 1572 1573 pImage->pszFilename = pszFilename; 1574 pImage->pStorage = NULL; 1575 pImage->pVDIfsDisk = pVDIfsDisk; 1576 pImage->pVDIfsImage = pVDIfsImage; 1577 1578 rc = qedCreateImage(pImage, cbSize, uImageFlags, pszComment, 1579 pPCHSGeometry, pLCHSGeometry, uOpenFlags, 1580 pIfProgress, uPercentStart, uPercentSpan); 1581 if (RT_SUCCESS(rc)) 1582 { 1583 /* So far the image is opened in read/write mode. Make sure the 1584 * image is opened in read-only mode if the caller requested that. */ 1585 if (uOpenFlags & VD_OPEN_FLAGS_READONLY) 1586 { 1587 qedFreeImage(pImage, false); 1588 rc = qedOpenImage(pImage, uOpenFlags); 1589 } 1590 1591 if (RT_SUCCESS(rc)) 1592 *ppBackendData = pImage; 1593 } 1594 1595 if RT_FAILURE(rc) 1596 RTMemFree(pImage); 1597 } 1598 else 1668 1599 rc = VERR_NO_MEMORY; 1669 goto out; 1670 } 1671 pImage->pszFilename = pszFilename; 1672 pImage->pStorage = NULL; 1673 pImage->pVDIfsDisk = pVDIfsDisk; 1674 pImage->pVDIfsImage = pVDIfsImage; 1675 1676 rc = qedCreateImage(pImage, cbSize, uImageFlags, pszComment, 1677 pPCHSGeometry, pLCHSGeometry, uOpenFlags, 1678 pfnProgress, pvUser, uPercentStart, uPercentSpan); 1679 if (RT_SUCCESS(rc)) 1680 { 1681 /* So far the image is opened in read/write mode. Make sure the 1682 * image is opened in read-only mode if the caller requested that. */ 1683 if (uOpenFlags & VD_OPEN_FLAGS_READONLY) 1684 { 1685 qedFreeImage(pImage, false); 1686 rc = qedOpenImage(pImage, uOpenFlags); 1687 if (RT_FAILURE(rc)) 1688 { 1689 RTMemFree(pImage); 1690 goto out; 1691 } 1692 } 1693 *ppBackendData = pImage; 1694 } 1695 else 1696 RTMemFree(pImage); 1697 1698 out: 1600 1699 1601 LogFlowFunc(("returns %Rrc (pBackendData=%#p)\n", rc, *ppBackendData)); 1700 1602 return rc; … … 1709 1611 1710 1612 /* Check arguments. */ 1711 if ( !pImage 1712 || !pszFilename 1713 || !*pszFilename) 1714 { 1715 rc = VERR_INVALID_PARAMETER; 1716 goto out; 1717 } 1613 AssertReturn((pImage && pszFilename && *pszFilename), VERR_INVALID_PARAMETER); 1718 1614 1719 1615 /* Close the image. */ 1720 1616 rc = qedFreeImage(pImage, false); 1721 if (RT_FAILURE(rc)) 1722 goto out; 1723 1724 /* Rename the file. */ 1725 rc = vdIfIoIntFileMove(pImage->pIfIo, pImage->pszFilename, pszFilename, 0); 1726 if (RT_FAILURE(rc)) 1727 { 1728 /* The move failed, try to reopen the original image. */ 1729 int rc2 = qedOpenImage(pImage, pImage->uOpenFlags); 1730 if (RT_FAILURE(rc2)) 1731 rc = rc2; 1732 1733 goto out; 1734 } 1735 1736 /* Update pImage with the new information. */ 1737 pImage->pszFilename = pszFilename; 1738 1739 /* Open the old image with new name. */ 1740 rc = qedOpenImage(pImage, pImage->uOpenFlags); 1741 if (RT_FAILURE(rc)) 1742 goto out; 1743 1744 out: 1617 if (RT_SUCCESS(rc)) 1618 { 1619 /* Rename the file. */ 1620 rc = vdIfIoIntFileMove(pImage->pIfIo, pImage->pszFilename, pszFilename, 0); 1621 if (RT_SUCCESS(rc)) 1622 { 1623 /* Update pImage with the new information. */ 1624 pImage->pszFilename = pszFilename; 1625 1626 /* Open the old image with new name. */ 1627 rc = qedOpenImage(pImage, pImage->uOpenFlags); 1628 } 1629 else 1630 { 1631 /* The move failed, try to reopen the original image. */ 1632 int rc2 = qedOpenImage(pImage, pImage->uOpenFlags); 1633 if (RT_FAILURE(rc2)) 1634 rc = rc2; 1635 } 1636 } 1637 1745 1638 LogFlowFunc(("returns %Rrc\n", rc)); 1746 1639 return rc; … … 1752 1645 LogFlowFunc(("pBackendData=%#p fDelete=%d\n", pBackendData, fDelete)); 1753 1646 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 1754 int rc; 1755 1756 rc = qedFreeImage(pImage, fDelete); 1647 1648 int rc = qedFreeImage(pImage, fDelete); 1757 1649 RTMemFree(pImage); 1758 1650 … … 1761 1653 } 1762 1654 1655 /** @copydoc VDIMAGEBACKEND::pfnWrite */ 1763 1656 static DECLCALLBACK(int) qedRead(void *pBackendData, uint64_t uOffset, size_t cbToRead, 1764 1657 PVDIOCTX pIoCtx, size_t *pcbActuallyRead) … … 1771 1664 uint32_t idxL2 = 0; 1772 1665 uint64_t offFile = 0; 1773 int rc;1774 1666 1775 1667 AssertPtr(pImage); 1776 1668 Assert(uOffset % 512 == 0); 1777 1669 Assert(cbToRead % 512 == 0); 1778 1779 if (!VALID_PTR(pIoCtx) || !cbToRead) 1780 { 1781 rc = VERR_INVALID_PARAMETER; 1782 goto out; 1783 } 1784 1785 if ( uOffset + cbToRead > pImage->cbSize 1786 || cbToRead == 0) 1787 { 1788 rc = VERR_INVALID_PARAMETER; 1789 goto out; 1790 } 1670 AssertReturn((VALID_PTR(pIoCtx) && cbToRead), VERR_INVALID_PARAMETER); 1671 AssertReturn(uOffset + cbToRead <= pImage->cbSize, VERR_INVALID_PARAMETER); 1791 1672 1792 1673 qedConvertLogicalOffset(pImage, uOffset, &idxL1, &idxL2, &offCluster); … … 1796 1677 1797 1678 /* Get offset in image. */ 1798 rc = qedConvertToImageOffset(pImage, pIoCtx, idxL1, idxL2, offCluster, &offFile);1679 int rc = qedConvertToImageOffset(pImage, pIoCtx, idxL1, idxL2, offCluster, &offFile); 1799 1680 if (RT_SUCCESS(rc)) 1800 1681 rc = vdIfIoIntFileReadUser(pImage->pIfIo, pImage->pStorage, offFile, … … 1807 1688 *pcbActuallyRead = cbToRead; 1808 1689 1809 out:1810 1690 LogFlowFunc(("returns %Rrc\n", rc)); 1811 1691 return rc; 1812 1692 } 1813 1693 1694 /** @copydoc VDIMAGEBACKEND::pfnRead */ 1814 1695 static DECLCALLBACK(int) qedWrite(void *pBackendData, uint64_t uOffset, size_t cbToWrite, 1815 1696 PVDIOCTX pIoCtx, size_t *pcbWriteProcess, size_t *pcbPreRead, … … 1828 1709 Assert(!(uOffset % 512)); 1829 1710 Assert(!(cbToWrite % 512)); 1830 1831 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 1832 { 1833 rc = VERR_VD_IMAGE_READ_ONLY; 1834 goto out; 1835 } 1836 1837 if (!VALID_PTR(pIoCtx) || !cbToWrite) 1838 { 1839 rc = VERR_INVALID_PARAMETER; 1840 goto out; 1841 } 1842 1843 if ( uOffset + cbToWrite > pImage->cbSize 1844 || cbToWrite == 0) 1845 { 1846 rc = VERR_INVALID_PARAMETER; 1847 goto out; 1848 } 1849 1850 /* Convert offset to L1, L2 index and cluster offset. */ 1851 qedConvertLogicalOffset(pImage, uOffset, &idxL1, &idxL2, &offCluster); 1852 1853 /* Clip write size to remain in the cluster. */ 1854 cbToWrite = RT_MIN(cbToWrite, pImage->cbCluster - offCluster); 1855 Assert(!(cbToWrite % 512)); 1856 1857 /* Get offset in image. */ 1858 rc = qedConvertToImageOffset(pImage, pIoCtx, idxL1, idxL2, offCluster, &offImage); 1859 if (RT_SUCCESS(rc)) 1860 rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage, 1861 offImage, pIoCtx, cbToWrite, NULL, NULL); 1862 else if (rc == VERR_VD_BLOCK_FREE) 1863 { 1864 if ( cbToWrite == pImage->cbCluster 1865 && !(fWrite & VD_WRITE_NO_ALLOC)) 1866 { 1867 PQEDL2CACHEENTRY pL2Entry = NULL; 1868 1869 /* Full cluster write to previously unallocated cluster. 1870 * Allocate cluster and write data. */ 1871 Assert(!offCluster); 1872 1873 do 1711 AssertReturn((VALID_PTR(pIoCtx) && cbToWrite), VERR_INVALID_PARAMETER); 1712 AssertReturn(uOffset + cbToWrite <= pImage->cbSize, VERR_INVALID_PARAMETER); 1713 1714 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 1715 { 1716 /* Convert offset to L1, L2 index and cluster offset. */ 1717 qedConvertLogicalOffset(pImage, uOffset, &idxL1, &idxL2, &offCluster); 1718 1719 /* Clip write size to remain in the cluster. */ 1720 cbToWrite = RT_MIN(cbToWrite, pImage->cbCluster - offCluster); 1721 Assert(!(cbToWrite % 512)); 1722 1723 /* Get offset in image. */ 1724 rc = qedConvertToImageOffset(pImage, pIoCtx, idxL1, idxL2, offCluster, &offImage); 1725 if (RT_SUCCESS(rc)) 1726 rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage, 1727 offImage, pIoCtx, cbToWrite, NULL, NULL); 1728 else if (rc == VERR_VD_BLOCK_FREE) 1729 { 1730 if ( cbToWrite == pImage->cbCluster 1731 && !(fWrite & VD_WRITE_NO_ALLOC)) 1874 1732 { 1875 /* Check if we have to allocate a new cluster for L2 tables. */ 1876 if (!pImage->paL1Table[idxL1]) 1733 PQEDL2CACHEENTRY pL2Entry = NULL; 1734 1735 /* Full cluster write to previously unallocated cluster. 1736 * Allocate cluster and write data. */ 1737 Assert(!offCluster); 1738 1739 do 1877 1740 { 1878 uint64_t offL2Tbl; 1879 PQEDCLUSTERASYNCALLOC pL2ClusterAlloc = NULL; 1880 1881 /* Allocate new async cluster allocation state. */ 1882 pL2ClusterAlloc = (PQEDCLUSTERASYNCALLOC)RTMemAllocZ(sizeof(QEDCLUSTERASYNCALLOC)); 1883 if (RT_UNLIKELY(!pL2ClusterAlloc)) 1741 /* Check if we have to allocate a new cluster for L2 tables. */ 1742 if (!pImage->paL1Table[idxL1]) 1884 1743 { 1885 rc = VERR_NO_MEMORY; 1886 break; 1887 } 1888 1889 pL2Entry = qedL2TblCacheEntryAlloc(pImage); 1890 if (!pL2Entry) 1891 { 1892 rc = VERR_NO_MEMORY; 1893 RTMemFree(pL2ClusterAlloc); 1894 break; 1895 } 1896 1897 offL2Tbl = qedClusterAllocate(pImage, qedByte2Cluster(pImage, pImage->cbTable)); 1898 pL2Entry->offL2Tbl = offL2Tbl; 1899 memset(pL2Entry->paL2Tbl, 0, pImage->cbTable); 1900 1901 pL2ClusterAlloc->enmAllocState = QEDCLUSTERASYNCALLOCSTATE_L2_ALLOC; 1902 pL2ClusterAlloc->cbImageOld = offL2Tbl; 1903 pL2ClusterAlloc->offClusterNew = offL2Tbl; 1904 pL2ClusterAlloc->idxL1 = idxL1; 1905 pL2ClusterAlloc->idxL2 = idxL2; 1906 pL2ClusterAlloc->cbToWrite = cbToWrite; 1907 pL2ClusterAlloc->pL2Entry = pL2Entry; 1908 1909 /* 1910 * Write the L2 table first and link to the L1 table afterwards. 1911 * If something unexpected happens the worst case which can happen 1912 * is a leak of some clusters. 1913 */ 1914 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 1915 offL2Tbl, pL2Entry->paL2Tbl, pImage->cbTable, pIoCtx, 1916 qedAsyncClusterAllocUpdate, pL2ClusterAlloc); 1917 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1918 break; 1919 else if (RT_FAILURE(rc)) 1920 { 1921 RTMemFree(pL2ClusterAlloc); 1922 qedL2TblCacheEntryFree(pImage, pL2Entry); 1923 break; 1924 } 1925 1926 rc = qedAsyncClusterAllocUpdate(pImage, pIoCtx, pL2ClusterAlloc, rc); 1927 } 1928 else 1929 { 1930 rc = qedL2TblCacheFetchAsync(pImage, pIoCtx, pImage->paL1Table[idxL1], 1931 &pL2Entry); 1932 1933 if (RT_SUCCESS(rc)) 1934 { 1935 PQEDCLUSTERASYNCALLOC pDataClusterAlloc = NULL; 1744 uint64_t offL2Tbl; 1745 PQEDCLUSTERASYNCALLOC pL2ClusterAlloc = NULL; 1936 1746 1937 1747 /* Allocate new async cluster allocation state. */ 1938 p DataClusterAlloc = (PQEDCLUSTERASYNCALLOC)RTMemAllocZ(sizeof(QEDCLUSTERASYNCALLOC));1939 if (RT_UNLIKELY(!p DataClusterAlloc))1748 pL2ClusterAlloc = (PQEDCLUSTERASYNCALLOC)RTMemAllocZ(sizeof(QEDCLUSTERASYNCALLOC)); 1749 if (RT_UNLIKELY(!pL2ClusterAlloc)) 1940 1750 { 1941 1751 rc = VERR_NO_MEMORY; … … 1943 1753 } 1944 1754 1945 /* Allocate new cluster for the data. */ 1946 uint64_t offData = qedClusterAllocate(pImage, 1); 1947 1948 pDataClusterAlloc->enmAllocState = QEDCLUSTERASYNCALLOCSTATE_USER_ALLOC; 1949 pDataClusterAlloc->cbImageOld = offData; 1950 pDataClusterAlloc->offClusterNew = offData; 1951 pDataClusterAlloc->idxL1 = idxL1; 1952 pDataClusterAlloc->idxL2 = idxL2; 1953 pDataClusterAlloc->cbToWrite = cbToWrite; 1954 pDataClusterAlloc->pL2Entry = pL2Entry; 1955 1956 /* Write data. */ 1957 rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage, 1958 offData, pIoCtx, cbToWrite, 1959 qedAsyncClusterAllocUpdate, pDataClusterAlloc); 1755 pL2Entry = qedL2TblCacheEntryAlloc(pImage); 1756 if (!pL2Entry) 1757 { 1758 rc = VERR_NO_MEMORY; 1759 RTMemFree(pL2ClusterAlloc); 1760 break; 1761 } 1762 1763 offL2Tbl = qedClusterAllocate(pImage, qedByte2Cluster(pImage, pImage->cbTable)); 1764 pL2Entry->offL2Tbl = offL2Tbl; 1765 memset(pL2Entry->paL2Tbl, 0, pImage->cbTable); 1766 1767 pL2ClusterAlloc->enmAllocState = QEDCLUSTERASYNCALLOCSTATE_L2_ALLOC; 1768 pL2ClusterAlloc->cbImageOld = offL2Tbl; 1769 pL2ClusterAlloc->offClusterNew = offL2Tbl; 1770 pL2ClusterAlloc->idxL1 = idxL1; 1771 pL2ClusterAlloc->idxL2 = idxL2; 1772 pL2ClusterAlloc->cbToWrite = cbToWrite; 1773 pL2ClusterAlloc->pL2Entry = pL2Entry; 1774 1775 /* 1776 * Write the L2 table first and link to the L1 table afterwards. 1777 * If something unexpected happens the worst case which can happen 1778 * is a leak of some clusters. 1779 */ 1780 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 1781 offL2Tbl, pL2Entry->paL2Tbl, pImage->cbTable, pIoCtx, 1782 qedAsyncClusterAllocUpdate, pL2ClusterAlloc); 1960 1783 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1961 1784 break; 1962 1785 else if (RT_FAILURE(rc)) 1963 1786 { 1964 RTMemFree(pDataClusterAlloc); 1787 RTMemFree(pL2ClusterAlloc); 1788 qedL2TblCacheEntryFree(pImage, pL2Entry); 1965 1789 break; 1966 1790 } 1967 1791 1968 rc = qedAsyncClusterAllocUpdate(pImage, pIoCtx, p DataClusterAlloc, rc);1792 rc = qedAsyncClusterAllocUpdate(pImage, pIoCtx, pL2ClusterAlloc, rc); 1969 1793 } 1970 } 1971 1972 } while (0); 1973 1974 *pcbPreRead = 0; 1975 *pcbPostRead = 0; 1976 } 1977 else 1978 { 1979 /* Trying to do a partial write to an unallocated cluster. Don't do 1980 * anything except letting the upper layer know what to do. */ 1981 *pcbPreRead = offCluster; 1982 *pcbPostRead = pImage->cbCluster - cbToWrite - *pcbPreRead; 1983 } 1984 } 1985 1986 if (pcbWriteProcess) 1987 *pcbWriteProcess = cbToWrite; 1988 1989 1990 out: 1794 else 1795 { 1796 rc = qedL2TblCacheFetchAsync(pImage, pIoCtx, pImage->paL1Table[idxL1], 1797 &pL2Entry); 1798 1799 if (RT_SUCCESS(rc)) 1800 { 1801 PQEDCLUSTERASYNCALLOC pDataClusterAlloc = NULL; 1802 1803 /* Allocate new async cluster allocation state. */ 1804 pDataClusterAlloc = (PQEDCLUSTERASYNCALLOC)RTMemAllocZ(sizeof(QEDCLUSTERASYNCALLOC)); 1805 if (RT_UNLIKELY(!pDataClusterAlloc)) 1806 { 1807 rc = VERR_NO_MEMORY; 1808 break; 1809 } 1810 1811 /* Allocate new cluster for the data. */ 1812 uint64_t offData = qedClusterAllocate(pImage, 1); 1813 1814 pDataClusterAlloc->enmAllocState = QEDCLUSTERASYNCALLOCSTATE_USER_ALLOC; 1815 pDataClusterAlloc->cbImageOld = offData; 1816 pDataClusterAlloc->offClusterNew = offData; 1817 pDataClusterAlloc->idxL1 = idxL1; 1818 pDataClusterAlloc->idxL2 = idxL2; 1819 pDataClusterAlloc->cbToWrite = cbToWrite; 1820 pDataClusterAlloc->pL2Entry = pL2Entry; 1821 1822 /* Write data. */ 1823 rc = vdIfIoIntFileWriteUser(pImage->pIfIo, pImage->pStorage, 1824 offData, pIoCtx, cbToWrite, 1825 qedAsyncClusterAllocUpdate, pDataClusterAlloc); 1826 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1827 break; 1828 else if (RT_FAILURE(rc)) 1829 { 1830 RTMemFree(pDataClusterAlloc); 1831 break; 1832 } 1833 1834 rc = qedAsyncClusterAllocUpdate(pImage, pIoCtx, pDataClusterAlloc, rc); 1835 } 1836 } 1837 1838 } while (0); 1839 1840 *pcbPreRead = 0; 1841 *pcbPostRead = 0; 1842 } 1843 else 1844 { 1845 /* Trying to do a partial write to an unallocated cluster. Don't do 1846 * anything except letting the upper layer know what to do. */ 1847 *pcbPreRead = offCluster; 1848 *pcbPostRead = pImage->cbCluster - cbToWrite - *pcbPreRead; 1849 } 1850 } 1851 1852 if (pcbWriteProcess) 1853 *pcbWriteProcess = cbToWrite; 1854 } 1855 else 1856 rc = VERR_VD_IMAGE_READ_ONLY; 1857 1991 1858 LogFlowFunc(("returns %Rrc\n", rc)); 1992 1859 return rc; 1993 1860 } 1994 1861 1862 /** @copydoc VDIMAGEBACKEND::pfnFlush */ 1995 1863 static DECLCALLBACK(int) qedFlush(void *pBackendData, PVDIOCTX pIoCtx) 1996 1864 { … … 1999 1867 int rc = VINF_SUCCESS; 2000 1868 2001 Assert(pImage); 2002 2003 if (VALID_PTR(pIoCtx)) 2004 rc = qedFlushImageAsync(pImage, pIoCtx); 2005 else 2006 rc = VERR_INVALID_PARAMETER; 1869 AssertPtr(pImage); 1870 AssertPtrReturn(pIoCtx, VERR_INVALID_PARAMETER); 1871 1872 if ( pImage->pStorage 1873 && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 1874 { 1875 QedHeader Header; 1876 1877 Assert(!(pImage->cbTable % pImage->cbCluster)); 1878 rc = qedTblWrite(pImage, pIoCtx, pImage->offL1Table, pImage->paL1Table, 1879 NULL, NULL); 1880 if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1881 { 1882 /* Write header. */ 1883 qedHdrConvertFromHostEndianess(pImage, &Header); 1884 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 1885 0, &Header, sizeof(Header), 1886 pIoCtx, NULL, NULL); 1887 if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1888 rc = vdIfIoIntFileFlush(pImage->pIfIo, pImage->pStorage, 1889 pIoCtx, NULL, NULL); 1890 } 1891 } 2007 1892 2008 1893 LogFlowFunc(("returns %Rrc\n", rc)); … … 2016 1901 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2017 1902 2018 AssertPtr(pImage); 2019 2020 if (pImage) 2021 return 1; 2022 else 2023 return 0; 1903 AssertPtrReturn(pImage, 0); 1904 1905 return 1; 2024 1906 } 2025 1907 … … 2031 1913 uint32_t cb = 0; 2032 1914 2033 AssertPtr (pImage);2034 2035 if (pImage && pImage->pStorage)1915 AssertPtrReturn(pImage, 0); 1916 1917 if (pImage->pStorage) 2036 1918 cb = 512; 2037 1919 … … 2047 1929 uint64_t cb = 0; 2048 1930 2049 AssertPtr (pImage);2050 2051 if (pImage && pImage->pStorage)1931 AssertPtrReturn(pImage, 0); 1932 1933 if (pImage->pStorage) 2052 1934 cb = pImage->cbSize; 2053 1935 … … 2063 1945 uint64_t cb = 0; 2064 1946 2065 AssertPtr(pImage); 2066 2067 if (pImage) 2068 { 2069 uint64_t cbFile; 2070 if (pImage->pStorage) 2071 { 2072 int rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile); 2073 if (RT_SUCCESS(rc)) 2074 cb += cbFile; 2075 } 1947 AssertPtrReturn(pImage, 0); 1948 1949 uint64_t cbFile; 1950 if (pImage->pStorage) 1951 { 1952 int rc = vdIfIoIntFileGetSize(pImage->pIfIo, pImage->pStorage, &cbFile); 1953 if (RT_SUCCESS(rc)) 1954 cb += cbFile; 2076 1955 } 2077 1956 … … 2086 1965 LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p\n", pBackendData, pPCHSGeometry)); 2087 1966 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2088 int rc; 2089 2090 AssertPtr(pImage); 2091 2092 if (pImage) 2093 { 2094 if (pImage->PCHSGeometry.cCylinders) 2095 { 2096 *pPCHSGeometry = pImage->PCHSGeometry; 2097 rc = VINF_SUCCESS; 2098 } 2099 else 2100 rc = VERR_VD_GEOMETRY_NOT_SET; 2101 } 1967 int rc = VINF_SUCCESS; 1968 1969 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 1970 1971 if (pImage->PCHSGeometry.cCylinders) 1972 *pPCHSGeometry = pImage->PCHSGeometry; 2102 1973 else 2103 rc = VERR_VD_ NOT_OPENED;1974 rc = VERR_VD_GEOMETRY_NOT_SET; 2104 1975 2105 1976 LogFlowFunc(("returns %Rrc (PCHS=%u/%u/%u)\n", rc, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors)); … … 2111 1982 PCVDGEOMETRY pPCHSGeometry) 2112 1983 { 2113 LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n", pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors)); 2114 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2115 int rc; 2116 2117 AssertPtr(pImage); 2118 2119 if (pImage) 2120 { 2121 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2122 { 2123 rc = VERR_VD_IMAGE_READ_ONLY; 2124 goto out; 2125 } 2126 1984 LogFlowFunc(("pBackendData=%#p pPCHSGeometry=%#p PCHS=%u/%u/%u\n", 1985 pBackendData, pPCHSGeometry, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors)); 1986 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 1987 int rc = VINF_SUCCESS; 1988 1989 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 1990 1991 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 1992 rc = VERR_VD_IMAGE_READ_ONLY; 1993 else 2127 1994 pImage->PCHSGeometry = *pPCHSGeometry; 2128 rc = VINF_SUCCESS; 2129 } 1995 1996 LogFlowFunc(("returns %Rrc\n", rc)); 1997 return rc; 1998 } 1999 2000 /** @copydoc VDIMAGEBACKEND::pfnGetLCHSGeometry */ 2001 static DECLCALLBACK(int) qedGetLCHSGeometry(void *pBackendData, PVDGEOMETRY pLCHSGeometry) 2002 { 2003 LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry)); 2004 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2005 int rc = VINF_SUCCESS; 2006 2007 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2008 2009 if (pImage->LCHSGeometry.cCylinders) 2010 *pLCHSGeometry = pImage->LCHSGeometry; 2130 2011 else 2131 rc = VERR_VD_NOT_OPENED; 2132 2133 out: 2134 LogFlowFunc(("returns %Rrc\n", rc)); 2135 return rc; 2136 } 2137 2138 /** @copydoc VDIMAGEBACKEND::pfnGetLCHSGeometry */ 2139 static DECLCALLBACK(int) qedGetLCHSGeometry(void *pBackendData, 2140 PVDGEOMETRY pLCHSGeometry) 2141 { 2142 LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p\n", pBackendData, pLCHSGeometry)); 2143 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2144 int rc; 2145 2146 AssertPtr(pImage); 2147 2148 if (pImage) 2149 { 2150 if (pImage->LCHSGeometry.cCylinders) 2151 { 2152 *pLCHSGeometry = pImage->LCHSGeometry; 2153 rc = VINF_SUCCESS; 2154 } 2155 else 2156 rc = VERR_VD_GEOMETRY_NOT_SET; 2157 } 2012 rc = VERR_VD_GEOMETRY_NOT_SET; 2013 2014 LogFlowFunc(("returns %Rrc (LCHS=%u/%u/%u)\n", rc, pLCHSGeometry->cCylinders, 2015 pLCHSGeometry->cHeads, pLCHSGeometry->cSectors)); 2016 return rc; 2017 } 2018 2019 /** @copydoc VDIMAGEBACKEND::pfnSetLCHSGeometry */ 2020 static DECLCALLBACK(int) qedSetLCHSGeometry(void *pBackendData, PCVDGEOMETRY pLCHSGeometry) 2021 { 2022 LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData, 2023 pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors)); 2024 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2025 int rc = VINF_SUCCESS; 2026 2027 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2028 2029 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2030 rc = VERR_VD_IMAGE_READ_ONLY; 2158 2031 else 2159 rc = VERR_VD_NOT_OPENED;2160 2161 LogFlowFunc(("returns %Rrc (LCHS=%u/%u/%u)\n", rc, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));2162 return rc;2163 }2164 2165 /** @copydoc VDIMAGEBACKEND::pfnSetLCHSGeometry */2166 static DECLCALLBACK(int) qedSetLCHSGeometry(void *pBackendData,2167 PCVDGEOMETRY pLCHSGeometry)2168 {2169 LogFlowFunc(("pBackendData=%#p pLCHSGeometry=%#p LCHS=%u/%u/%u\n", pBackendData, pLCHSGeometry, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));2170 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData;2171 int rc;2172 2173 AssertPtr(pImage);2174 2175 if (pImage)2176 {2177 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)2178 {2179 rc = VERR_VD_IMAGE_READ_ONLY;2180 goto out;2181 }2182 2183 2032 pImage->LCHSGeometry = *pLCHSGeometry; 2184 rc = VINF_SUCCESS; 2185 } 2186 else 2187 rc = VERR_VD_NOT_OPENED; 2188 2189 out: 2033 2190 2034 LogFlowFunc(("returns %Rrc\n", rc)); 2191 2035 return rc; … … 2197 2041 LogFlowFunc(("pBackendData=%#p\n", pBackendData)); 2198 2042 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2199 unsigned uImageFlags; 2200 2201 AssertPtr(pImage); 2202 2203 if (pImage) 2204 uImageFlags = pImage->uImageFlags; 2205 else 2206 uImageFlags = 0; 2207 2208 LogFlowFunc(("returns %#x\n", uImageFlags)); 2209 return uImageFlags; 2043 2044 AssertPtrReturn(pImage, 0); 2045 2046 LogFlowFunc(("returns %#x\n", pImage->uImageFlags)); 2047 return pImage->uImageFlags; 2210 2048 } 2211 2049 … … 2215 2053 LogFlowFunc(("pBackendData=%#p\n", pBackendData)); 2216 2054 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2217 unsigned uOpenFlags; 2218 2219 AssertPtr(pImage); 2220 2221 if (pImage) 2222 uOpenFlags = pImage->uOpenFlags; 2223 else 2224 uOpenFlags = 0; 2225 2226 LogFlowFunc(("returns %#x\n", uOpenFlags)); 2227 return uOpenFlags; 2055 2056 AssertPtrReturn(pImage, 0); 2057 2058 LogFlowFunc(("returns %#x\n", pImage->uOpenFlags)); 2059 return pImage->uOpenFlags; 2228 2060 } 2229 2061 … … 2233 2065 LogFlowFunc(("pBackendData=%#p\n uOpenFlags=%#x", pBackendData, uOpenFlags)); 2234 2066 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2235 int rc ;2067 int rc = VINF_SUCCESS; 2236 2068 2237 2069 /* Image must be opened and the new flags must be valid. */ 2238 2070 if (!pImage || (uOpenFlags & ~( VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO 2239 | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_S KIP_CONSISTENCY_CHECKS)))2240 {2071 | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE 2072 | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS))) 2241 2073 rc = VERR_INVALID_PARAMETER; 2242 goto out; 2243 } 2244 2245 /* Implement this operation via reopening the image. */ 2246 rc = qedFreeImage(pImage, false); 2247 if (RT_FAILURE(rc)) 2248 goto out; 2249 rc = qedOpenImage(pImage, uOpenFlags); 2250 2251 out: 2074 else 2075 { 2076 /* Implement this operation via reopening the image. */ 2077 rc = qedFreeImage(pImage, false); 2078 if (RT_SUCCESS(rc)) 2079 rc = qedOpenImage(pImage, uOpenFlags); 2080 } 2081 2252 2082 LogFlowFunc(("returns %Rrc\n", rc)); 2253 2083 return rc; … … 2261 2091 LogFlowFunc(("pBackendData=%#p pszComment=%#p cbComment=%zu\n", pBackendData, pszComment, cbComment)); 2262 2092 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2263 int rc; 2264 2265 AssertPtr(pImage); 2266 2267 if (pImage) 2268 rc = VERR_NOT_SUPPORTED; 2269 else 2270 rc = VERR_VD_NOT_OPENED; 2271 2272 LogFlowFunc(("returns %Rrc comment='%s'\n", rc, pszComment)); 2273 return rc; 2093 2094 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2095 2096 LogFlowFunc(("returns %Rrc comment='%s'\n", VERR_NOT_SUPPORTED, pszComment)); 2097 return VERR_NOT_SUPPORTED; 2274 2098 } 2275 2099 … … 2280 2104 LogFlowFunc(("pBackendData=%#p pszComment=\"%s\"\n", pBackendData, pszComment)); 2281 2105 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2106 2107 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2108 2282 2109 int rc; 2283 2284 AssertPtr(pImage); 2285 2286 if (pImage) 2287 { 2288 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2289 rc = VERR_VD_IMAGE_READ_ONLY; 2290 else 2291 rc = VERR_NOT_SUPPORTED; 2292 } 2110 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2111 rc = VERR_VD_IMAGE_READ_ONLY; 2293 2112 else 2294 rc = VERR_ VD_NOT_OPENED;2113 rc = VERR_NOT_SUPPORTED; 2295 2114 2296 2115 LogFlowFunc(("returns %Rrc\n", rc)); … … 2304 2123 LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid)); 2305 2124 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2306 int rc; 2307 2308 AssertPtr(pImage); 2309 2310 if (pImage) 2311 rc = VERR_NOT_SUPPORTED; 2312 else 2313 rc = VERR_VD_NOT_OPENED; 2314 2315 LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid)); 2316 return rc; 2125 2126 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2127 2128 LogFlowFunc(("returns %Rrc (%RTuuid)\n", VERR_NOT_SUPPORTED, pUuid)); 2129 return VERR_NOT_SUPPORTED; 2317 2130 } 2318 2131 … … 2323 2136 LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid)); 2324 2137 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2138 2139 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2140 2325 2141 int rc; 2326 2327 LogFlowFunc(("%RTuuid\n", pUuid)); 2328 AssertPtr(pImage); 2329 2330 if (pImage) 2331 { 2332 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 2333 rc = VERR_NOT_SUPPORTED; 2334 else 2335 rc = VERR_VD_IMAGE_READ_ONLY; 2336 } 2142 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2143 rc = VERR_VD_IMAGE_READ_ONLY; 2337 2144 else 2338 rc = VERR_ VD_NOT_OPENED;2145 rc = VERR_NOT_SUPPORTED; 2339 2146 2340 2147 LogFlowFunc(("returns %Rrc\n", rc)); … … 2348 2155 LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid)); 2349 2156 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2350 int rc; 2351 2352 AssertPtr(pImage); 2353 2354 if (pImage) 2355 rc = VERR_NOT_SUPPORTED; 2356 else 2357 rc = VERR_VD_NOT_OPENED; 2358 2359 LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid)); 2360 return rc; 2157 2158 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2159 2160 LogFlowFunc(("returns %Rrc (%RTuuid)\n", VERR_NOT_SUPPORTED, pUuid)); 2161 return VERR_NOT_SUPPORTED; 2361 2162 } 2362 2163 … … 2367 2168 LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid)); 2368 2169 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2170 2171 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2172 2369 2173 int rc; 2370 2371 AssertPtr(pImage); 2372 2373 if (pImage) 2374 { 2375 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 2376 rc = VERR_NOT_SUPPORTED; 2377 else 2378 rc = VERR_VD_IMAGE_READ_ONLY; 2379 } 2174 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2175 rc = VERR_VD_IMAGE_READ_ONLY; 2380 2176 else 2381 rc = VERR_ VD_NOT_OPENED;2177 rc = VERR_NOT_SUPPORTED; 2382 2178 2383 2179 LogFlowFunc(("returns %Rrc\n", rc)); … … 2391 2187 LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid)); 2392 2188 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2393 int rc; 2394 2395 AssertPtr(pImage); 2396 2397 if (pImage) 2398 rc = VERR_NOT_SUPPORTED; 2399 else 2400 rc = VERR_VD_NOT_OPENED; 2401 2402 LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid)); 2403 return rc; 2189 2190 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2191 2192 LogFlowFunc(("returns %Rrc (%RTuuid)\n", VERR_NOT_SUPPORTED, pUuid)); 2193 return VERR_NOT_SUPPORTED; 2404 2194 } 2405 2195 … … 2410 2200 LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid)); 2411 2201 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2202 2203 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2204 2412 2205 int rc; 2413 2414 AssertPtr(pImage); 2415 2416 if (pImage) 2417 { 2418 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 2419 rc = VERR_NOT_SUPPORTED; 2420 else 2421 rc = VERR_VD_IMAGE_READ_ONLY; 2422 } 2206 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2207 rc = VERR_VD_IMAGE_READ_ONLY; 2423 2208 else 2424 rc = VERR_ VD_NOT_OPENED;2209 rc = VERR_NOT_SUPPORTED; 2425 2210 2426 2211 LogFlowFunc(("returns %Rrc\n", rc)); … … 2434 2219 LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid)); 2435 2220 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2436 int rc; 2437 2438 AssertPtr(pImage); 2439 2440 if (pImage) 2441 rc = VERR_NOT_SUPPORTED; 2442 else 2443 rc = VERR_VD_NOT_OPENED; 2444 2445 LogFlowFunc(("returns %Rrc (%RTuuid)\n", rc, pUuid)); 2446 return rc; 2221 2222 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2223 2224 LogFlowFunc(("returns %Rrc (%RTuuid)\n", VERR_NOT_SUPPORTED, pUuid)); 2225 return VERR_NOT_SUPPORTED; 2447 2226 } 2448 2227 … … 2453 2232 LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid)); 2454 2233 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2234 2235 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2236 2455 2237 int rc; 2456 2457 AssertPtr(pImage); 2458 2459 if (pImage) 2460 { 2461 if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) 2462 rc = VERR_NOT_SUPPORTED; 2463 else 2464 rc = VERR_VD_IMAGE_READ_ONLY; 2465 } 2238 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2239 rc = VERR_VD_IMAGE_READ_ONLY; 2466 2240 else 2467 rc = VERR_ VD_NOT_OPENED;2241 rc = VERR_NOT_SUPPORTED; 2468 2242 2469 2243 LogFlowFunc(("returns %Rrc\n", rc)); … … 2476 2250 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2477 2251 2478 AssertPtr(pImage); 2479 if (pImage) 2480 { 2481 vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%llu\n", 2482 pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors, 2483 pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors, 2484 pImage->cbSize / 512); 2485 } 2252 AssertPtrReturnVoid(pImage); 2253 vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%llu\n", 2254 pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors, 2255 pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors, 2256 pImage->cbSize / 512); 2486 2257 } 2487 2258 … … 2492 2263 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2493 2264 2494 AssertPtr(pImage); 2495 if (pImage) 2496 if (pImage->pszBackingFilename) 2497 *ppszParentFilename = RTStrDup(pImage->pszBackingFilename); 2498 else 2499 rc = VERR_NOT_SUPPORTED; 2265 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2266 2267 if (pImage->pszBackingFilename) 2268 *ppszParentFilename = RTStrDup(pImage->pszBackingFilename); 2500 2269 else 2501 rc = VERR_ VD_NOT_OPENED;2270 rc = VERR_NOT_SUPPORTED; 2502 2271 2503 2272 LogFlowFunc(("returns %Rrc\n", rc)); … … 2511 2280 PQEDIMAGE pImage = (PQEDIMAGE)pBackendData; 2512 2281 2513 AssertPtr(pImage); 2514 if (pImage) 2515 { 2516 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2517 rc = VERR_VD_IMAGE_READ_ONLY; 2518 else if ( pImage->pszBackingFilename 2519 && (strlen(pszParentFilename) > pImage->cbBackingFilename)) 2520 rc = VERR_NOT_SUPPORTED; /* The new filename is longer than the old one. */ 2282 AssertPtrReturn(pImage, VERR_VD_NOT_OPENED); 2283 2284 if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY) 2285 rc = VERR_VD_IMAGE_READ_ONLY; 2286 else if ( pImage->pszBackingFilename 2287 && (strlen(pszParentFilename) > pImage->cbBackingFilename)) 2288 rc = VERR_NOT_SUPPORTED; /* The new filename is longer than the old one. */ 2289 else 2290 { 2291 if (pImage->pszBackingFilename) 2292 RTStrFree(pImage->pszBackingFilename); 2293 pImage->pszBackingFilename = RTStrDup(pszParentFilename); 2294 if (!pImage->pszBackingFilename) 2295 rc = VERR_NO_MEMORY; 2521 2296 else 2522 2297 { 2523 if (pImage->pszBackingFilename) 2524 RTStrFree(pImage->pszBackingFilename); 2525 pImage->pszBackingFilename = RTStrDup(pszParentFilename); 2526 if (!pImage->pszBackingFilename) 2527 rc = VERR_NO_MEMORY; 2528 else 2298 if (!pImage->offBackingFilename) 2529 2299 { 2530 if (!pImage->offBackingFilename) 2531 { 2532 /* Allocate new cluster. */ 2533 uint64_t offData = qedClusterAllocate(pImage, 1); 2534 2535 Assert((offData & UINT32_MAX) == offData); 2536 pImage->offBackingFilename = (uint32_t)offData; 2537 pImage->cbBackingFilename = (uint32_t)strlen(pszParentFilename); 2538 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, 2539 offData + pImage->cbCluster); 2540 } 2541 2542 if (RT_SUCCESS(rc)) 2543 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, 2544 pImage->offBackingFilename, 2545 pImage->pszBackingFilename, 2546 strlen(pImage->pszBackingFilename)); 2300 /* Allocate new cluster. */ 2301 uint64_t offData = qedClusterAllocate(pImage, 1); 2302 2303 Assert((offData & UINT32_MAX) == offData); 2304 pImage->offBackingFilename = (uint32_t)offData; 2305 pImage->cbBackingFilename = (uint32_t)strlen(pszParentFilename); 2306 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, 2307 offData + pImage->cbCluster); 2547 2308 } 2548 } 2549 } 2550 else 2551 rc = VERR_VD_NOT_OPENED; 2309 2310 if (RT_SUCCESS(rc)) 2311 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, 2312 pImage->offBackingFilename, 2313 pImage->pszBackingFilename, 2314 strlen(pImage->pszBackingFilename)); 2315 } 2316 } 2552 2317 2553 2318 LogFlowFunc(("returns %Rrc\n", rc));
Note:
See TracChangeset
for help on using the changeset viewer.