Changeset 65703 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Feb 9, 2017 4:04:03 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
r65487 r65703 29 29 #include <iprt/avl.h> 30 30 #include <iprt/mem.h> 31 #include <iprt/memcache.h> 31 32 #include <iprt/message.h> 32 33 #include <iprt/sg.h> … … 189 190 /** Next free slot in the array */ 190 191 volatile unsigned iNextFreeSlot; 192 /** Request cache. */ 193 RTMEMCACHE hReqCache; 191 194 192 195 /** Flag whether we check for requests completing twice. */ … … 213 216 } DRVDISKINTEGRITY, *PDRVDISKINTEGRITY; 214 217 218 219 #define DISKINTEGRITY_IOREQ_HANDLE_2_DRVDISKAIOREQ(a_pThis, a_hIoReq) ((*(PDRVDISKAIOREQ *)((uintptr_t)(a_hIoReq) + (a_pThis)->cbIoReqOpaque))) 220 #define DISKINTEGRITY_IOREQ_HANDLE_2_UPPER_OPAQUE(a_pThis, a_hIoReq) ((void *)((uintptr_t)(a_hIoReq) + (a_pThis)->cbIoReqOpaque + sizeof(PDRVDISKAIOREQ))) 221 #define DISKINTEGRITY_IOREQ_ALLOC_2_DRVDISKAIOREQ(a_pvIoReqAlloc) (*(PDRVDISKAIOREQ *)(a_pvIoReqAlloc)) 222 #define DISKINTEGRITY_IOREQ_ALLOC_2_UPPER(a_pvIoReqAlloc) ((void *)((uintptr_t)(a_pvIoReqAlloc) + sizeof(PDRVDISKAIOREQ))) 215 223 216 224 static void drvdiskintIoReqCheckForDoubleCompletion(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq, … … 994 1002 { 995 1003 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 996 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc;1004 PDRVDISKAIOREQ pIoReq = DISKINTEGRITY_IOREQ_ALLOC_2_DRVDISKAIOREQ(pvIoReqAlloc); 997 1005 int rc = VINF_SUCCESS; 998 1006 … … 1033 1041 RTSGBUF SgBufCmp; 1034 1042 RTSgBufInit(&SgBufCmp, &SegCmp, 1); 1035 rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, 1043 rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, 1044 DISKINTEGRITY_IOREQ_ALLOC_2_UPPER(pvIoReqAlloc), 1036 1045 0, &SgBufCmp, pIoReq->cbTransfer); 1037 1046 AssertRC(rc); … … 1087 1096 else 1088 1097 { 1089 rc = pThis->pDrvMediaExPort->pfnIoReqCompleteNotify(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, rcReq); 1098 rc = pThis->pDrvMediaExPort->pfnIoReqCompleteNotify(pThis->pDrvMediaExPort, hIoReq, 1099 DISKINTEGRITY_IOREQ_ALLOC_2_UPPER(pvIoReqAlloc), 1100 rcReq); 1090 1101 /* Put on the watch list. */ 1091 1102 if (pThis->fCheckDoubleCompletion) … … 1104 1115 { 1105 1116 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 1106 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc;1117 PDRVDISKAIOREQ pIoReq = DISKINTEGRITY_IOREQ_ALLOC_2_DRVDISKAIOREQ(pvIoReqAlloc); 1107 1118 RTSGBUF SgBuf; 1108 1119 1109 1120 RTSgBufClone(&SgBuf, pSgBuf); 1110 1121 1111 int rc = pThis->pDrvMediaExPort->pfnIoReqCopyFromBuf(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, offDst, 1112 pSgBuf, cbCopy); 1122 int rc = pThis->pDrvMediaExPort->pfnIoReqCopyFromBuf(pThis->pDrvMediaExPort, hIoReq, 1123 DISKINTEGRITY_IOREQ_ALLOC_2_UPPER(pvIoReqAlloc), 1124 offDst, pSgBuf, cbCopy); 1113 1125 if ( RT_SUCCESS(rc) 1114 1126 && pIoReq->IoSeg.pvSeg) … … 1143 1155 { 1144 1156 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 1145 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc;1157 PDRVDISKAIOREQ pIoReq = DISKINTEGRITY_IOREQ_ALLOC_2_DRVDISKAIOREQ(pvIoReqAlloc); 1146 1158 RTSGBUF SgBuf; 1147 1159 1148 1160 RTSgBufClone(&SgBuf, pSgBuf); 1149 1161 1150 int rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, offSrc, 1151 pSgBuf, cbCopy); 1162 int rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, 1163 DISKINTEGRITY_IOREQ_ALLOC_2_UPPER(pvIoReqAlloc), 1164 offSrc, pSgBuf, cbCopy); 1152 1165 if ( RT_SUCCESS(rc) 1153 1166 && pIoReq->IoSeg.pvSeg) … … 1185 1198 { 1186 1199 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 1187 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc; 1188 1189 return pThis->pDrvMediaExPort->pfnIoReqQueryDiscardRanges(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, idxRangeStart, 1190 cRanges, paRanges, pcRanges); 1200 return pThis->pDrvMediaExPort->pfnIoReqQueryDiscardRanges(pThis->pDrvMediaExPort, hIoReq, 1201 DISKINTEGRITY_IOREQ_ALLOC_2_UPPER(pvIoReqAlloc), 1202 idxRangeStart, cRanges, paRanges, pcRanges); 1191 1203 } 1192 1204 … … 1198 1210 { 1199 1211 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 1200 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc;1201 1202 pThis->pDrvMediaExPort->pfnIoReqStateChanged(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1,enmState);1212 pThis->pDrvMediaExPort->pfnIoReqStateChanged(pThis->pDrvMediaExPort, hIoReq, 1213 DISKINTEGRITY_IOREQ_ALLOC_2_UPPER(pvIoReqAlloc), 1214 enmState); 1203 1215 } 1204 1216 … … 1221 1233 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1222 1234 1223 /* Increase the amount by our private tracking structure. */1224 cbIoReqAlloc += sizeof( DRVDISKAIOREQ);1235 /* Increase the amount by the size of a pointer to our private tracking structure. */ 1236 cbIoReqAlloc += sizeof(PDRVDISKAIOREQ); 1225 1237 1226 1238 pThis->fCheckDoubleCompletion = false; … … 1236 1248 { 1237 1249 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1238 PDRVDISKAIOREQ pIoReq = NULL; 1239 1240 int rc = pThis->pDrvMediaEx->pfnIoReqAlloc(pThis->pDrvMediaEx, phIoReq, (void **)&pIoReq, uIoReqId, fFlags); 1241 if RT_SUCCESS(rc) 1250 int rc = VINF_SUCCESS; 1251 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)RTMemCacheAlloc(pThis->hReqCache); 1252 if (RT_LIKELY(pIoReq)) 1242 1253 { 1243 1254 pIoReq->enmTxDir = DRVDISKAIOTXDIR_INVALID; … … 1254 1265 pIoReq->IoSeg.cbSeg = 0; 1255 1266 1256 /* 1257 * Store the size off the start of our tracking structure because it is 1258 * required to access it for the read/write callbacks. 1259 * 1260 * ASSUMPTION that the offset is constant. 1261 */ 1262 if (!pThis->cbIoReqOpaque) 1263 pThis->cbIoReqOpaque = (uintptr_t)pIoReq - (uintptr_t)*phIoReq; 1267 PDRVDISKAIOREQ *ppIoReq = NULL; 1268 rc = pThis->pDrvMediaEx->pfnIoReqAlloc(pThis->pDrvMediaEx, phIoReq, (void **)&ppIoReq, uIoReqId, fFlags); 1269 if RT_SUCCESS(rc) 1270 { 1271 /* 1272 * Store the size off the start of our tracking structure because it is 1273 * required to access it for the read/write callbacks. 1274 * 1275 * ASSUMPTION that the offset is constant. 1276 */ 1277 if (!pThis->cbIoReqOpaque) 1278 pThis->cbIoReqOpaque = (uintptr_t)ppIoReq - (uintptr_t)*phIoReq; 1279 else 1280 Assert(pThis->cbIoReqOpaque == (uintptr_t)ppIoReq - (uintptr_t)*phIoReq); 1281 1282 *ppIoReq = pIoReq; 1283 *ppvIoReqAlloc = ((uint8_t *)ppIoReq) + sizeof(PDRVDISKAIOREQ); 1284 } 1264 1285 else 1265 Assert(pThis->cbIoReqOpaque == (uintptr_t)pIoReq - (uintptr_t)*phIoReq);1266 1267 *ppvIoReqAlloc = pIoReq + 1;1268 }1286 RTMemCacheFree(pThis->hReqCache, pIoReq); 1287 } 1288 else 1289 rc = VERR_NO_MEMORY; 1269 1290 1270 1291 return rc; … … 1277 1298 { 1278 1299 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1279 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)((uintptr_t)hIoReq + pThis->cbIoReqOpaque);1300 PDRVDISKAIOREQ pIoReq = DISKINTEGRITY_IOREQ_HANDLE_2_DRVDISKAIOREQ(pThis, hIoReq); 1280 1301 1281 1302 if (pIoReq->IoSeg.pvSeg) … … 1327 1348 { 1328 1349 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1329 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)((uintptr_t)hIoReq + pThis->cbIoReqOpaque);1350 PDRVDISKAIOREQ pIoReq = DISKINTEGRITY_IOREQ_HANDLE_2_DRVDISKAIOREQ(pThis, hIoReq); 1330 1351 1331 1352 pIoReq->enmTxDir = DRVDISKAIOTXDIR_READ; … … 1384 1405 { 1385 1406 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1386 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)((uintptr_t)hIoReq + pThis->cbIoReqOpaque);1407 PDRVDISKAIOREQ pIoReq = DISKINTEGRITY_IOREQ_HANDLE_2_DRVDISKAIOREQ(pThis, hIoReq); 1387 1408 1388 1409 pIoReq->enmTxDir = DRVDISKAIOTXDIR_WRITE; … … 1407 1428 1408 1429 RTSgBufInit(&SgBuf, &pIoReq->IoSeg, 1); 1409 int rc2 = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, 0, 1410 &SgBuf, cbWrite); 1430 int rc2 = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, 1431 DISKINTEGRITY_IOREQ_HANDLE_2_UPPER_OPAQUE(pThis, hIoReq), 1432 0, &SgBuf, cbWrite); 1411 1433 AssertRC(rc2); 1412 1434 } … … 1464 1486 { 1465 1487 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1466 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)((uintptr_t)hIoReq + pThis->cbIoReqOpaque);1488 PDRVDISKAIOREQ pIoReq = DISKINTEGRITY_IOREQ_HANDLE_2_DRVDISKAIOREQ(pThis, hIoReq); 1467 1489 1468 1490 pIoReq->enmTxDir = DRVDISKAIOTXDIR_FLUSH; … … 1623 1645 if (pThis->hIoLogger) 1624 1646 VDDbgIoLogDestroy(pThis->hIoLogger); 1647 1648 if (pThis->hReqCache != NIL_RTMEMCACHE) 1649 { 1650 RTMemCacheDestroy(pThis->hReqCache); 1651 pThis->hReqCache = NIL_RTMEMCACHE; 1652 } 1625 1653 } 1626 1654 … … 1686 1714 */ 1687 1715 pThis->pDrvIns = pDrvIns; 1716 pThis->hReqCache = NIL_RTMEMCACHE; 1688 1717 1689 1718 /* IBase. */ … … 1745 1774 /* Try to attach extended media port interface above.*/ 1746 1775 pThis->pDrvMediaExPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAEXPORT); 1776 1777 rc = RTMemCacheCreate(&pThis->hReqCache, sizeof(DRVDISKAIOREQ), 0, UINT32_MAX, 1778 NULL, NULL, NULL, 0); 1779 if (RT_FAILURE(rc)) 1780 return PDMDRV_SET_ERROR(pDrvIns, rc, 1781 N_("Failed to create request tracking structure cache")); 1747 1782 1748 1783 /*
Note:
See TracChangeset
for help on using the changeset viewer.