Changeset 63741 in vbox
- Timestamp:
- Sep 7, 2016 7:53:09 AM (8 years ago)
- Location:
- trunk/src/VBox/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/QCOW.cpp
r63635 r63741 888 888 } 889 889 890 /** 891 * Write the given table to image converting to the image endianess if required. 892 * 893 * @returns VBox status code. 894 * @param pImage The image instance data. 895 * @param pIoCtx The I/O context. 896 * @param offTbl The offset the table should be written to. 897 * @param paTbl The table to write. 898 * @param pfnComplete Callback called when the write completes. 899 * @param pvUser Opaque user data to pass in the completion callback. 900 */ 901 static int qcowTblWrite(PQCOWIMAGE pImage, PVDIOCTX pIoCtx, uint64_t offTbl, uint64_t *paTbl, 902 size_t cbTbl, unsigned cTblEntries, 903 PFNVDXFERCOMPLETED pfnComplete, void *pvUser) 904 { 905 int rc = VINF_SUCCESS; 906 907 #if defined(RT_LITTLE_ENDIAN) 908 uint64_t *paTblImg = (uint64_t *)RTMemAllocZ(cbTbl); 909 if (paTblImg) 910 { 911 qcowTableConvertFromHostEndianess(paTblImg, paTbl, cTblEntries); 912 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 913 offTbl, paTblImg, cbTbl, 914 pIoCtx, pfnComplete, pvUser); 915 RTMemFree(paTblImg); 916 } 917 else 918 rc = VERR_NO_MEMORY; 919 #else 920 /* Write table directly. */ 921 RT_NOREF(cTblEntries); 922 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 923 offTbl, paTbl, cbTbl, pIoCtx, 924 pfnComplete, pvUser); 925 #endif 926 927 return rc; 928 } 890 929 891 930 /** … … 951 990 QCowHeader Header; 952 991 953 #if defined(RT_LITTLE_ENDIAN) 954 uint64_t *paL1TblImg = (uint64_t *)RTMemAllocZ(pImage->cbL1Table); 955 if (paL1TblImg) 956 { 957 qcowTableConvertFromHostEndianess(paL1TblImg, pImage->paL1Table, 958 pImage->cL1TableEntries); 959 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 960 pImage->offL1Table, paL1TblImg, 961 pImage->cbL1Table, pIoCtx, NULL, NULL); 962 RTMemFree(paL1TblImg); 963 } 964 else 965 rc = VERR_NO_MEMORY; 966 #else 967 /* Write L1 table directly. */ 968 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 969 pImage->offL1Table, pImage->paL1Table, 970 pImage->cbL1Table, pIoCtx, NULL, NULL); 971 #endif 992 rc = qcowTblWrite(pImage, pIoCtx, pImage->offL1Table, pImage->paL1Table, 993 pImage->cbL1Table, pImage->cL1TableEntries, NULL, NULL); 972 994 if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 973 995 { … … 1381 1403 case QCOWCLUSTERASYNCALLOCSTATE_L2_LINK: 1382 1404 { 1383 /* Assumption right now is that the L1 table is not modified if the link fails. */ 1405 /* Revert the L1 table entry */ 1406 pImage->paL1Table[pClusterAlloc->idxL1] = 0; 1407 1408 /* Assumption right now is that the L1 table is not modified on storage if the link fails. */ 1384 1409 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, pClusterAlloc->offNextClusterOld); 1385 1410 qcowL2TblCacheEntryRelease(pClusterAlloc->pL2Entry); /* Release L2 cache entry. */ … … 1391 1416 { 1392 1417 /* Assumption right now is that the L2 table is not modified if the link fails. */ 1418 pClusterAlloc->pL2Entry->paL2Tbl[pClusterAlloc->idxL2] = 0; 1393 1419 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, pClusterAlloc->offNextClusterOld); 1394 1420 qcowL2TblCacheEntryRelease(pClusterAlloc->pL2Entry); /* Release L2 cache entry. */ … … 1428 1454 case QCOWCLUSTERASYNCALLOCSTATE_L2_ALLOC: 1429 1455 { 1430 uint64_t offUpdateLe = RT_H2BE_U64(pClusterAlloc->pL2Entry->offL2Tbl); 1456 /* Update the link in the in memory L1 table now. */ 1457 pImage->paL1Table[pClusterAlloc->idxL1] = pClusterAlloc->pL2Entry->offL2Tbl; 1431 1458 1432 1459 /* Update the link in the on disk L1 table now. */ 1433 1460 pClusterAlloc->enmAllocState = QCOWCLUSTERASYNCALLOCSTATE_L2_LINK; 1434 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 1435 pImage->offL1Table + pClusterAlloc->idxL1*sizeof(uint64_t), 1436 &offUpdateLe, sizeof(uint64_t), pIoCtx, 1437 qcowAsyncClusterAllocUpdate, pClusterAlloc); 1461 rc = qcowTblWrite(pImage, pIoCtx, pImage->offL1Table, pImage->paL1Table, 1462 pImage->cbL1Table, pImage->cL1TableEntries, 1463 qcowAsyncClusterAllocUpdate, pClusterAlloc); 1438 1464 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1439 1465 break; … … 1451 1477 uint64_t offData = qcowClusterAllocate(pImage, 1); 1452 1478 1453 /* Update the link in the in memory L1 table now. */1454 pImage->paL1Table[pClusterAlloc->idxL1] = pClusterAlloc->pL2Entry->offL2Tbl;1455 1479 qcowL2TblCacheEntryInsert(pImage, pClusterAlloc->pL2Entry); 1456 1480 … … 1474 1498 case QCOWCLUSTERASYNCALLOCSTATE_USER_ALLOC: 1475 1499 { 1476 uint64_t offUpdateLe = RT_H2BE_U64(pClusterAlloc->offClusterNew);1477 1478 1500 pClusterAlloc->enmAllocState = QCOWCLUSTERASYNCALLOCSTATE_USER_LINK; 1501 pClusterAlloc->pL2Entry->paL2Tbl[pClusterAlloc->idxL2] = pClusterAlloc->offClusterNew; 1479 1502 1480 1503 /* Link L2 table and update it. */ 1481 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage,1482 pImage->paL1Table[pClusterAlloc->idxL1] + pClusterAlloc->idxL2*sizeof(uint64_t),1483 &offUpdateLe, sizeof(uint64_t), pIoCtx,1484 qcowAsyncClusterAllocUpdate, pClusterAlloc);1504 rc = qcowTblWrite(pImage, pIoCtx, pImage->paL1Table[pClusterAlloc->idxL1], 1505 pClusterAlloc->pL2Entry->paL2Tbl, 1506 pImage->cbL2Table, pImage->cL2TableEntries, 1507 qcowAsyncClusterAllocUpdate, pClusterAlloc); 1485 1508 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1486 1509 break; … … 1495 1518 { 1496 1519 /* Everything done without errors, signal completion. */ 1497 pClusterAlloc->pL2Entry->paL2Tbl[pClusterAlloc->idxL2] = pClusterAlloc->offClusterNew;1498 1520 qcowL2TblCacheEntryRelease(pClusterAlloc->pL2Entry); 1499 1521 RTMemFree(pClusterAlloc); -
trunk/src/VBox/Storage/QED.cpp
r63636 r63741 566 566 } 567 567 568 #if 0 /* unused */569 /**570 * Fetches the L2 from the given offset trying the LRU cache first and571 * reading it from the image after a cache miss.572 *573 * @returns VBox status code.574 * @param pImage Image instance data.575 * @param offL2Tbl The offset of the L2 table in the image.576 * @param ppL2Entry Where to store the L2 table on success.577 */578 static int qedL2TblCacheFetch(PQEDIMAGE pImage, uint64_t offL2Tbl, PQEDL2CACHEENTRY *ppL2Entry)579 {580 int rc = VINF_SUCCESS;581 582 LogFlowFunc(("pImage=%#p offL2Tbl=%llu ppL2Entry=%#p\n", pImage, offL2Tbl, ppL2Entry));583 584 /* Try to fetch the L2 table from the cache first. */585 PQEDL2CACHEENTRY pL2Entry = qedL2TblCacheRetain(pImage, offL2Tbl);586 if (!pL2Entry)587 {588 LogFlowFunc(("Reading L2 table from image\n"));589 pL2Entry = qedL2TblCacheEntryAlloc(pImage);590 591 if (pL2Entry)592 {593 /* Read from the image. */594 pL2Entry->offL2Tbl = offL2Tbl;595 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, offL2Tbl,596 pL2Entry->paL2Tbl, pImage->cbTable);597 if (RT_SUCCESS(rc))598 {599 #if defined(RT_BIG_ENDIAN)600 qedTableConvertToHostEndianess(pL2Entry->paL2Tbl, pImage->cTableEntries);601 #endif602 qedL2TblCacheEntryInsert(pImage, pL2Entry);603 }604 else605 {606 qedL2TblCacheEntryRelease(pL2Entry);607 qedL2TblCacheEntryFree(pImage, pL2Entry);608 }609 }610 else611 rc = VERR_NO_MEMORY;612 }613 614 if (RT_SUCCESS(rc))615 *ppL2Entry = pL2Entry;616 617 LogFlowFunc(("returns rc=%Rrc\n", rc));618 return rc;619 }620 #endif621 622 568 /** 623 569 * Fetches the L2 from the given offset trying the LRU cache first and … … 822 768 } 823 769 770 /** 771 * Write the given table to image converting to the image endianess if required. 772 * 773 * @returns VBox status code. 774 * @param pImage The image instance data. 775 * @param pIoCtx The I/O context. 776 * @param offTbl The offset the table should be written to. 777 * @param paTbl The table to write. 778 * @param pfnComplete Callback called when the write completes. 779 * @param pvUser Opaque user data to pass in the completion callback. 780 */ 781 static int qedTblWrite(PQEDIMAGE pImage, PVDIOCTX pIoCtx, uint64_t offTbl, uint64_t *paTbl, 782 PFNVDXFERCOMPLETED pfnComplete, void *pvUser) 783 { 784 int rc = VINF_SUCCESS; 785 786 #if defined(RT_BIG_ENDIAN) 787 uint64_t *paTblImg = (uint64_t *)RTMemAllocZ(pImage->cbTable); 788 if (paTblImg) 789 { 790 qedTableConvertFromHostEndianess(paTblImg, paTbl, 791 pImage->cTableEntries); 792 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 793 offTbl, paTblImg, pImage->cbTable, 794 pIoCtx, pfnComplete, pvUser); 795 RTMemFree(paTblImg); 796 } 797 else 798 rc = VERR_NO_MEMORY; 799 #else 800 /* Write table directly. */ 801 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 802 offTbl, paTbl, pImage->cbTable, pIoCtx, 803 pfnComplete, pvUser); 804 #endif 805 806 return rc; 807 } 824 808 825 809 /** … … 885 869 886 870 Assert(!(pImage->cbTable % pImage->cbCluster)); 887 #if defined(RT_BIG_ENDIAN) 888 uint64_t *paL1TblImg = (uint64_t *)RTMemAllocZ(pImage->cbTable); 889 if (paL1TblImg) 890 { 891 qedTableConvertFromHostEndianess(paL1TblImg, pImage->paL1Table, 892 pImage->cTableEntries); 893 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 894 pImage->offL1Table, paL1TblImg, 895 pImage->cbTable, pIoCtx, NULL, NULL); 896 RTMemFree(paL1TblImg); 897 } 898 else 899 rc = VERR_NO_MEMORY; 900 #else 901 /* Write L1 table directly. */ 902 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 903 pImage->offL1Table, pImage->paL1Table, 904 pImage->cbTable, pIoCtx, NULL, NULL); 905 #endif 871 rc = qedTblWrite(pImage, pIoCtx, pImage->offL1Table, pImage->paL1Table, 872 NULL, NULL); 906 873 if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 907 874 { … … 1414 1381 case QEDCLUSTERASYNCALLOCSTATE_L2_LINK: 1415 1382 { 1416 /* Assumption right now is that the L1 table is not modified if the link fails. */ 1383 /* Revert the L1 table entry */ 1384 pImage->paL1Table[pClusterAlloc->idxL1] = 0; 1385 1386 /* Assumption right now is that the L1 table is not modified on storage if the link fails. */ 1417 1387 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, pClusterAlloc->cbImageOld); 1418 1388 qedL2TblCacheEntryRelease(pClusterAlloc->pL2Entry); /* Release L2 cache entry. */ … … 1424 1394 { 1425 1395 /* Assumption right now is that the L2 table is not modified if the link fails. */ 1396 pClusterAlloc->pL2Entry->paL2Tbl[pClusterAlloc->idxL2] = 0; 1426 1397 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, pClusterAlloc->cbImageOld); 1427 1398 qedL2TblCacheEntryRelease(pClusterAlloc->pL2Entry); /* Release L2 cache entry. */ … … 1461 1432 case QEDCLUSTERASYNCALLOCSTATE_L2_ALLOC: 1462 1433 { 1463 uint64_t offUpdateLe = RT_H2LE_U64(pClusterAlloc->pL2Entry->offL2Tbl); 1434 /* Update the link in the in memory L1 table now. */ 1435 pImage->paL1Table[pClusterAlloc->idxL1] = pClusterAlloc->pL2Entry->offL2Tbl; 1464 1436 1465 1437 /* Update the link in the on disk L1 table now. */ 1466 1438 pClusterAlloc->enmAllocState = QEDCLUSTERASYNCALLOCSTATE_L2_LINK; 1467 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 1468 pImage->offL1Table + pClusterAlloc->idxL1*sizeof(uint64_t), 1469 &offUpdateLe, sizeof(uint64_t), pIoCtx, 1470 qedAsyncClusterAllocUpdate, pClusterAlloc); 1439 rc = qedTblWrite(pImage, pIoCtx, pImage->offL1Table, pImage->paL1Table, 1440 qedAsyncClusterAllocUpdate, pClusterAlloc); 1471 1441 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1472 1442 break; … … 1484 1454 uint64_t offData = qedClusterAllocate(pImage, 1); 1485 1455 1486 /* Update the link in the in memory L1 table now. */1487 pImage->paL1Table[pClusterAlloc->idxL1] = pClusterAlloc->pL2Entry->offL2Tbl;1488 1456 qedL2TblCacheEntryInsert(pImage, pClusterAlloc->pL2Entry); 1489 1457 … … 1507 1475 case QEDCLUSTERASYNCALLOCSTATE_USER_ALLOC: 1508 1476 { 1509 uint64_t offUpdateLe = RT_H2LE_U64(pClusterAlloc->offClusterNew);1510 1511 1477 pClusterAlloc->enmAllocState = QEDCLUSTERASYNCALLOCSTATE_USER_LINK; 1478 pClusterAlloc->pL2Entry->paL2Tbl[pClusterAlloc->idxL2] = pClusterAlloc->offClusterNew; 1512 1479 1513 1480 /* Link L2 table and update it. */ 1514 rc = vdIfIoIntFileWriteMeta(pImage->pIfIo, pImage->pStorage, 1515 pImage->paL1Table[pClusterAlloc->idxL1] + pClusterAlloc->idxL2*sizeof(uint64_t), 1516 &offUpdateLe, sizeof(uint64_t), pIoCtx, 1517 qedAsyncClusterAllocUpdate, pClusterAlloc); 1481 rc = qedTblWrite(pImage, pIoCtx, pImage->paL1Table[pClusterAlloc->idxL1], 1482 pClusterAlloc->pL2Entry->paL2Tbl, 1483 qedAsyncClusterAllocUpdate, pClusterAlloc); 1518 1484 if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1519 1485 break; … … 1528 1494 { 1529 1495 /* Everything done without errors, signal completion. */ 1530 pClusterAlloc->pL2Entry->paL2Tbl[pClusterAlloc->idxL2] = pClusterAlloc->offClusterNew;1531 1496 qedL2TblCacheEntryRelease(pClusterAlloc->pL2Entry); 1532 1497 RTMemFree(pClusterAlloc);
Note:
See TracChangeset
for help on using the changeset viewer.

