Changeset 63727 in vbox
- Timestamp:
- Sep 5, 2016 4:27:27 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 110503
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
r63700 r63727 47 47 typedef enum DRVDISKAIOTXDIR 48 48 { 49 /** Invalid. */ 50 DRVDISKAIOTXDIR_INVALID = 0, 49 51 /** Read */ 50 DRVDISKAIOTXDIR_READ = 0,52 DRVDISKAIOTXDIR_READ, 51 53 /** Write */ 52 54 DRVDISKAIOTXDIR_WRITE, … … 88 90 /** Number of ranges. */ 89 91 unsigned cRanges; 92 /** I/O segment for the extended media interface 93 * to hold the data. */ 94 RTSGSEG IoSeg; 90 95 } DRVDISKAIOREQ, *PDRVDISKAIOREQ; 91 96 … … 210 215 * Useful in case the data is modified in place later on (encryption for instance). */ 211 216 bool fRecordWriteBeforeCompletion; 217 /** Flag whether to validate memory buffers when the extended media interface is used. */ 218 bool fValidateMemBufs; 212 219 213 220 /** I/O logger to use if enabled. */ 214 221 VDIOLOGGER hIoLogger; 222 /** Size of the opaque handle until our tracking structure starts in bytes. */ 223 size_t cbIoReqOpaque; 215 224 } DRVDISKINTEGRITY, *PDRVDISKINTEGRITY; 216 225 … … 249 258 } 250 259 260 static void drvdiskintIoReqCheckForDoubleCompletion(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq, 261 bool fMediaEx) 262 { 263 /* Search if the I/O request completed already. */ 264 for (unsigned i = 0; i < pThis->cEntries; i++) 265 { 266 if (RT_UNLIKELY(pThis->papIoReq[i] == pIoReq)) 267 { 268 RTMsgError("Request %#p completed already!\n", pIoReq); 269 if (!fMediaEx) 270 RTMsgError("Start timestamp %llu Completion timestamp %llu (completed after %llu ms)\n", 271 pIoReq->tsStart, pIoReq->tsComplete, pIoReq->tsComplete - pIoReq->tsStart); 272 RTAssertDebugBreak(); 273 } 274 } 275 276 pIoReq->tsComplete = RTTimeSystemMilliTS(); 277 Assert(!pThis->papIoReq[pThis->iEntry]); 278 pThis->papIoReq[pThis->iEntry] = pIoReq; 279 280 pThis->iEntry = (pThis->iEntry+1) % pThis->cEntries; 281 if (pThis->papIoReq[pThis->iEntry]) 282 { 283 if (!fMediaEx) 284 RTMemFree(pThis->papIoReq[pThis->iEntry]); 285 pThis->papIoReq[pThis->iEntry] = NULL; 286 } 287 } 288 251 289 /** 252 290 * Free a async I/O request. … … 256 294 * @param pIoReq The I/O request to free. 257 295 */ 258 static void drvdiskint IoReqFree(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)296 static void drvdiskintReqFree(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq) 259 297 { 260 298 if (pThis->fCheckDoubleCompletion) 261 { 262 /* Search if the I/O request completed already. */ 263 for (unsigned i = 0; i < pThis->cEntries; i++) 264 { 265 if (RT_UNLIKELY(pThis->papIoReq[i] == pIoReq)) 266 { 267 RTMsgError("Request %#p completed already!\n", pIoReq); 268 RTMsgError("Start timestamp %llu Completion timestamp %llu (completed after %llu ms)\n", 269 pIoReq->tsStart, pIoReq->tsComplete, pIoReq->tsComplete - pIoReq->tsStart); 270 RTAssertDebugBreak(); 271 } 272 } 273 274 pIoReq->tsComplete = RTTimeSystemMilliTS(); 275 Assert(!pThis->papIoReq[pThis->iEntry]); 276 pThis->papIoReq[pThis->iEntry] = pIoReq; 277 278 pThis->iEntry = (pThis->iEntry+1) % pThis->cEntries; 279 if (pThis->papIoReq[pThis->iEntry]) 280 { 281 RTMemFree(pThis->papIoReq[pThis->iEntry]); 282 pThis->papIoReq[pThis->iEntry] = NULL; 283 } 284 } 299 drvdiskintIoReqCheckForDoubleCompletion(pThis, pIoReq, false /* fMediaEx */); 285 300 else 286 301 RTMemFree(pIoReq); … … 359 374 { 360 375 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core); 361 AssertMsg(fInserted, ("Bug!\n")); 376 AssertMsg(fInserted, ("Bug!\n")); RT_NOREF(fInserted); 362 377 fSet = true; 363 378 } … … 375 390 AssertPtr(pSeg); 376 391 size_t cbCopied = RTSgBufCopyToBuf(&SgBuf, pSeg->pbSeg + offSeg, cbRange); 377 Assert(cbCopied == cbRange); 392 Assert(cbCopied == cbRange); RT_NOREF(cbCopied); 378 393 379 394 /* Update the I/O log pointers */ … … 589 604 pSeg->cIoLogEntries = cbPreLeft / 512; 590 605 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core); 591 Assert(fInserted); 606 Assert(fInserted); RT_NOREF(fInserted); 592 607 } 593 608 else if (!cbPreLeft && cbPostLeft) … … 606 621 pSeg->cIoLogEntries = cbPostLeft / 512; 607 622 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core); 608 Assert(fInserted); 623 Assert(fInserted); RT_NOREF(fInserted); 609 624 } 610 625 else … … 629 644 630 645 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSegPost->Core); 631 Assert(fInserted); 646 Assert(fInserted); RT_NOREF(fInserted); 632 647 } 633 648 } … … 642 657 pSeg->cIoLogEntries = cbPreLeft / 512; 643 658 bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core); 644 Assert(fInserted); 659 Assert(fInserted); RT_NOREF(fInserted); 645 660 } /* if (cbPreLeft && cbPostLeft) */ 646 661 } … … 712 727 break; 713 728 714 Assert(rc == VERR_TIMEOUT); 729 Assert(rc == VERR_TIMEOUT); RT_NOREF(rc); 715 730 716 731 /* Get current timestamp for comparison. */ … … 1093 1108 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 1094 1109 return pThis->pDrvMedia->pfnIsReadOnly(pThis->pDrvMedia); 1110 } 1111 1112 /** @interface_method_impl{PDMIMEDIA,pfnBiosIsVisible} */ 1113 static DECLCALLBACK(bool) drvdiskintBiosIsVisible(PPDMIMEDIA pInterface) 1114 { 1115 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 1116 return pThis->pDrvMedia->pfnBiosIsVisible(pInterface); 1117 } 1118 1119 /** @interface_method_impl{PDMIMEDIA,pfnGetType} */ 1120 static DECLCALLBACK(PDMMEDIATYPE) drvdiskintGetType(PPDMIMEDIA pInterface) 1121 { 1122 PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface); 1123 return pThis->pDrvMedia->pfnGetType(pThis->pDrvMedia); 1095 1124 } 1096 1125 … … 1248 1277 pIoReq->enmTxDir = DRVDISKAIOTXDIR_READ_AFTER_WRITE; 1249 1278 1250 /* Readd because it was rmeoved above. */1279 /* Add again because it was removed above. */ 1251 1280 if (pThis->fTraceRequests) 1252 1281 drvdiskintIoReqAdd(pThis, pIoReq); … … 1270 1299 { 1271 1300 void *pvUserComplete = pIoReq->pvUser; 1272 drvdiskint IoReqFree(pThis, pIoReq);1301 drvdiskintReqFree(pThis, pIoReq); 1273 1302 1274 1303 rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq); … … 1304 1333 { 1305 1334 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 1306 return pThis->pDrvMediaExPort->pfnIoReqCompleteNotify(pThis->pDrvMediaExPort, hIoReq, pvIoReqAlloc, rcReq); 1335 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc; 1336 int rc = VINF_SUCCESS; 1337 1338 LogFlowFunc(("pIoReq=%#p\n", pIoReq)); 1339 1340 /* Remove from the active list. */ 1341 if (pThis->fTraceRequests) 1342 drvdiskintIoReqRemove(pThis, pIoReq); 1343 1344 if (RT_SUCCESS(rcReq) && pThis->fCheckConsistency) 1345 { 1346 if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ) 1347 rc = drvdiskintReadVerify(pThis, &pIoReq->IoSeg, 1, pIoReq->off, pIoReq->cbTransfer); 1348 else if ( pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE 1349 && !pThis->fRecordWriteBeforeCompletion) 1350 rc = drvdiskintWriteRecord(pThis, &pIoReq->IoSeg, 1, pIoReq->off, pIoReq->cbTransfer); 1351 else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_DISCARD) 1352 rc = drvdiskintDiscardRecords(pThis, pIoReq->paRanges, pIoReq->cRanges); 1353 else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ_AFTER_WRITE) 1354 rc = drvdiskintReadAfterWriteVerify(pThis, pIoReq); 1355 else 1356 AssertMsg( pIoReq->enmTxDir == DRVDISKAIOTXDIR_FLUSH 1357 || ( pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE 1358 && pThis->fRecordWriteBeforeCompletion), ("Huh?\n")); 1359 1360 AssertRC(rc); 1361 } 1362 1363 if ( RT_SUCCESS(rcReq) 1364 && pThis->fValidateMemBufs 1365 && pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ) 1366 { 1367 /* Check that the guest memory buffer matches what was written. */ 1368 RTSGSEG SegCmp; 1369 SegCmp.pvSeg = RTMemAlloc(pIoReq->cbTransfer); 1370 SegCmp.cbSeg = pIoReq->cbTransfer; 1371 1372 RTSGBUF SgBufCmp; 1373 RTSgBufInit(&SgBufCmp, &SegCmp, 1); 1374 rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, 1375 0, &SgBufCmp, pIoReq->cbTransfer); 1376 AssertRC(rc); 1377 1378 RTSGBUF SgBuf; 1379 RTSgBufInit(&SgBuf, &pIoReq->IoSeg, 1); 1380 if (RTSgBufCmp(&SgBuf, &SgBufCmp, pIoReq->cbTransfer)) 1381 { 1382 RTMsgError("Corrupted memory buffer at offset %llu!\n", 0); 1383 RTAssertDebugBreak(); 1384 } 1385 1386 RTMemFree(SegCmp.pvSeg); 1387 } 1388 1389 if (pThis->hIoLogger) 1390 { 1391 RTSGBUF SgBuf; 1392 1393 if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ) 1394 RTSgBufInit(&SgBuf, &pIoReq->IoSeg, 1); 1395 1396 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, rc, &SgBuf); 1397 AssertRC(rc2); 1398 } 1399 1400 if ( pThis->fReadAfterWrite 1401 && pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE) 1402 { 1403 #if 0 /** @todo */ 1404 pIoReq->enmTxDir = DRVDISKAIOTXDIR_READ_AFTER_WRITE; 1405 1406 /* Add again because it was removed above. */ 1407 if (pThis->fTraceRequests) 1408 drvdiskintIoReqAdd(pThis, pIoReq); 1409 1410 rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, pIoReq->off, pIoReq->paSeg, pIoReq->cSeg, 1411 pIoReq->cbTransfer, pIoReq); 1412 if (rc == VINF_VD_ASYNC_IO_FINISHED) 1413 { 1414 rc = drvdiskintReadAfterWriteVerify(pThis, pIoReq); 1415 1416 if (pThis->fTraceRequests) 1417 drvdiskintIoReqRemove(pThis, pIoReq); 1418 RTMemFree(pIoReq); 1419 } 1420 else if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS) 1421 rc = VINF_SUCCESS; 1422 else if (RT_FAILURE(rc)) 1423 RTMemFree(pIoReq); 1424 #endif 1425 } 1426 else 1427 { 1428 rc = pThis->pDrvMediaExPort->pfnIoReqCompleteNotify(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, rcReq); 1429 /* Put on the watch list. */ 1430 if (pThis->fCheckDoubleCompletion) 1431 drvdiskintIoReqCheckForDoubleCompletion(pThis, pIoReq, true /* fMediaEx */); 1432 } 1433 1434 return rc; 1307 1435 } 1308 1436 … … 1315 1443 { 1316 1444 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 1317 return pThis->pDrvMediaExPort->pfnIoReqCopyFromBuf(pThis->pDrvMediaExPort, hIoReq, pvIoReqAlloc, offDst, 1318 pSgBuf, cbCopy); 1445 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc; 1446 RTSGBUF SgBuf; 1447 1448 RTSgBufClone(&SgBuf, pSgBuf); 1449 1450 int rc = pThis->pDrvMediaExPort->pfnIoReqCopyFromBuf(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, offDst, 1451 pSgBuf, cbCopy); 1452 if ( RT_SUCCESS(rc) 1453 && pIoReq->IoSeg.pvSeg) 1454 { 1455 /* Update our copy. */ 1456 RTSgBufCopyToBuf(&SgBuf, (uint8_t *)pIoReq->IoSeg.pvSeg + offDst, cbCopy); 1457 } 1458 1459 return rc; 1319 1460 } 1320 1461 … … 1327 1468 { 1328 1469 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 1329 return pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, pvIoReqAlloc, offSrc, 1330 pSgBuf, cbCopy); 1470 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc; 1471 RTSGBUF SgBuf; 1472 1473 RTSgBufClone(&SgBuf, pSgBuf); 1474 1475 int rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, offSrc, 1476 pSgBuf, cbCopy); 1477 if ( RT_SUCCESS(rc) 1478 && pIoReq->IoSeg.pvSeg) 1479 { 1480 if (pThis->fValidateMemBufs) 1481 { 1482 /* Make sure what the caller requested matches what we got earlier. */ 1483 RTSGBUF SgBufCmp; 1484 RTSgBufInit(&SgBufCmp, &pIoReq->IoSeg, 1); 1485 RTSgBufAdvance(&SgBufCmp, offSrc); 1486 1487 if (RTSgBufCmp(&SgBuf, &SgBufCmp, cbCopy)) 1488 { 1489 RTMsgError("Corrupted memory buffer at offset %llu!\n", offSrc); 1490 RTAssertDebugBreak(); 1491 } 1492 } 1493 else 1494 { 1495 /* Update our copy. */ 1496 RTSgBufCopyToBuf(&SgBuf, (uint8_t *)pIoReq->IoSeg.pvSeg + offSrc, cbCopy); 1497 } 1498 } 1499 1500 return rc; 1331 1501 } 1332 1502 … … 1338 1508 { 1339 1509 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaExPort); 1340 pThis->pDrvMediaExPort->pfnIoReqStateChanged(pThis->pDrvMediaExPort, hIoReq, pvIoReqAlloc, enmState); 1510 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)pvIoReqAlloc; 1511 1512 pThis->pDrvMediaExPort->pfnIoReqStateChanged(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, enmState); 1341 1513 } 1342 1514 … … 1349 1521 { 1350 1522 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1523 1524 /* Increase the amount by our private tracking structure. */ 1525 cbIoReqAlloc += sizeof(DRVDISKAIOREQ); 1526 1527 pThis->fCheckDoubleCompletion = false; 1528 1351 1529 return pThis->pDrvMediaEx->pfnIoReqAllocSizeSet(pThis->pDrvMediaEx, cbIoReqAlloc); 1352 1530 } … … 1359 1537 { 1360 1538 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1361 return pThis->pDrvMediaEx->pfnIoReqAlloc(pThis->pDrvMediaEx, phIoReq, ppvIoReqAlloc, uIoReqId, fFlags); 1539 PDRVDISKAIOREQ pIoReq = NULL; 1540 1541 int rc = pThis->pDrvMediaEx->pfnIoReqAlloc(pThis->pDrvMediaEx, phIoReq, (void **)&pIoReq, uIoReqId, fFlags); 1542 if RT_SUCCESS(rc) 1543 { 1544 pIoReq->enmTxDir = DRVDISKAIOTXDIR_INVALID; 1545 pIoReq->off = 0; 1546 pIoReq->cbTransfer = 0; 1547 pIoReq->paSeg = NULL; 1548 pIoReq->cSeg = 0; 1549 pIoReq->pvUser = NULL; 1550 pIoReq->iSlot = 0; 1551 pIoReq->tsStart = 0; 1552 pIoReq->tsComplete = 0; 1553 pIoReq->hIoLogEntry = NULL; 1554 pIoReq->IoSeg.pvSeg = NULL; 1555 pIoReq->IoSeg.cbSeg = 0; 1556 1557 /* 1558 * Store the size off the start of our tracking structure because it is 1559 * required to access it for the read/write callbacks. 1560 * 1561 * ASSUMPTION that the offset is constant. 1562 */ 1563 if (!pThis->cbIoReqOpaque) 1564 pThis->cbIoReqOpaque = (uintptr_t)pIoReq - (uintptr_t)*phIoReq; 1565 else 1566 Assert(pThis->cbIoReqOpaque == (uintptr_t)pIoReq - (uintptr_t)*phIoReq); 1567 1568 *ppvIoReqAlloc = pIoReq + 1; 1569 } 1570 1571 return rc; 1362 1572 } 1363 1573 … … 1368 1578 { 1369 1579 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1580 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)((uintptr_t)hIoReq + pThis->cbIoReqOpaque); 1581 1582 if (pIoReq->IoSeg.pvSeg) 1583 RTMemFree(pIoReq->IoSeg.pvSeg); 1584 1370 1585 return pThis->pDrvMediaEx->pfnIoReqFree(pThis->pDrvMediaEx, hIoReq); 1371 1586 } … … 1386 1601 { 1387 1602 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1388 return pThis->pDrvMediaEx->pfnIoReqRead(pThis->pDrvMediaEx, hIoReq, off, cbRead); 1603 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)((uintptr_t)hIoReq + pThis->cbIoReqOpaque); 1604 1605 pIoReq->enmTxDir = DRVDISKAIOTXDIR_READ; 1606 pIoReq->off = off; 1607 pIoReq->cbTransfer = cbRead; 1608 1609 /* Allocate a I/O buffer if the I/O is verified.*/ 1610 if (pThis->fCheckConsistency) 1611 { 1612 pIoReq->IoSeg.pvSeg = RTMemAlloc(cbRead); 1613 pIoReq->IoSeg.cbSeg = cbRead; 1614 } 1615 1616 if (pThis->fTraceRequests) 1617 drvdiskintIoReqAdd(pThis, pIoReq); 1618 1619 if (pThis->hIoLogger) 1620 { 1621 int rc2 = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGREQ_READ, off, 1622 cbRead, NULL, &pIoReq->hIoLogEntry); 1623 AssertRC(rc2); 1624 } 1625 1626 int rc = pThis->pDrvMediaEx->pfnIoReqRead(pThis->pDrvMediaEx, hIoReq, off, cbRead); 1627 if (rc == VINF_SUCCESS) 1628 { 1629 /* Verify the read now. */ 1630 if (pThis->fCheckConsistency) 1631 { 1632 int rc2 = drvdiskintReadVerify(pThis, &pIoReq->IoSeg, 1, off, cbRead); 1633 AssertRC(rc2); 1634 } 1635 1636 if (pThis->hIoLogger) 1637 { 1638 RTSGBUF SgBuf; 1639 1640 RTSgBufInit(&SgBuf, &pIoReq->IoSeg, 1); 1641 1642 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, &SgBuf); 1643 AssertRC(rc2); 1644 } 1645 1646 if (pThis->fTraceRequests) 1647 drvdiskintIoReqRemove(pThis, pIoReq); 1648 } 1649 1650 LogFlowFunc(("returns %Rrc\n", rc)); 1651 return rc; 1389 1652 } 1390 1653 … … 1395 1658 { 1396 1659 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1397 return pThis->pDrvMediaEx->pfnIoReqWrite(pThis->pDrvMediaEx, hIoReq, off, cbWrite); 1660 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)((uintptr_t)hIoReq + pThis->cbIoReqOpaque); 1661 1662 pIoReq->enmTxDir = DRVDISKAIOTXDIR_WRITE; 1663 pIoReq->off = off; 1664 pIoReq->cbTransfer = cbWrite; 1665 1666 /* Allocate a I/O buffer if the I/O is verified.*/ 1667 if ( pThis->fCheckConsistency 1668 || pThis->fValidateMemBufs 1669 || pThis->hIoLogger 1670 || pThis->fRecordWriteBeforeCompletion) 1671 { 1672 pIoReq->IoSeg.pvSeg = RTMemAlloc(cbWrite); 1673 pIoReq->IoSeg.cbSeg = cbWrite; 1674 1675 /* Sync the memory buffer over if we should validate it. */ 1676 if ( pThis->fValidateMemBufs 1677 || pThis->hIoLogger 1678 || pThis->fRecordWriteBeforeCompletion) 1679 { 1680 RTSGBUF SgBuf; 1681 1682 RTSgBufInit(&SgBuf, &pIoReq->IoSeg, 1); 1683 int rc2 = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, hIoReq, pIoReq + 1, 0, 1684 &SgBuf, cbWrite); 1685 AssertRC(rc2); 1686 } 1687 } 1688 1689 if (pThis->fTraceRequests) 1690 drvdiskintIoReqAdd(pThis, pIoReq); 1691 1692 if (pThis->hIoLogger) 1693 { 1694 RTSGBUF SgBuf; 1695 1696 RTSgBufInit(&SgBuf, &pIoReq->IoSeg, 1); 1697 int rc2 = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGREQ_WRITE, off, 1698 cbWrite, &SgBuf, &pIoReq->hIoLogEntry); 1699 AssertRC(rc2); 1700 } 1701 1702 if (pThis->fRecordWriteBeforeCompletion) 1703 { 1704 1705 int rc2 = drvdiskintWriteRecord(pThis, &pIoReq->IoSeg, 1, off, cbWrite); 1706 AssertRC(rc2); 1707 } 1708 1709 int rc = pThis->pDrvMediaEx->pfnIoReqWrite(pThis->pDrvMediaEx, hIoReq, off, cbWrite); 1710 if (rc == VINF_SUCCESS) 1711 { 1712 /* Record the write. */ 1713 if ( pThis->fCheckConsistency 1714 && !pThis->fRecordWriteBeforeCompletion) 1715 { 1716 int rc2 = drvdiskintWriteRecord(pThis, &pIoReq->IoSeg, 1, off, cbWrite); 1717 AssertRC(rc2); 1718 } 1719 1720 if (pThis->hIoLogger) 1721 { 1722 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, NULL); 1723 AssertRC(rc2); 1724 } 1725 1726 if (pThis->fTraceRequests) 1727 drvdiskintIoReqRemove(pThis, pIoReq); 1728 } 1729 1730 LogFlowFunc(("returns %Rrc\n", rc)); 1731 return rc; 1398 1732 } 1399 1733 … … 1404 1738 { 1405 1739 PDRVDISKINTEGRITY pThis = RT_FROM_MEMBER(pInterface, DRVDISKINTEGRITY, IMediaEx); 1406 return pThis->pDrvMediaEx->pfnIoReqFlush(pThis->pDrvMediaEx, hIoReq); 1740 PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)((uintptr_t)hIoReq + pThis->cbIoReqOpaque); 1741 1742 pIoReq->enmTxDir = DRVDISKAIOTXDIR_FLUSH; 1743 pIoReq->off = 0; 1744 pIoReq->cbTransfer = 0; 1745 1746 if (pThis->fTraceRequests) 1747 drvdiskintIoReqAdd(pThis, pIoReq); 1748 1749 if (pThis->hIoLogger) 1750 { 1751 int rc2 = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGREQ_FLUSH, 0, 1752 0, NULL, &pIoReq->hIoLogEntry); 1753 AssertRC(rc2); 1754 } 1755 1756 int rc = pThis->pDrvMediaEx->pfnIoReqFlush(pThis->pDrvMediaEx, hIoReq); 1757 if (rc == VINF_SUCCESS) 1758 { 1759 if (pThis->hIoLogger) 1760 { 1761 int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, NULL); 1762 AssertRC(rc2); 1763 } 1764 } 1765 1766 LogFlowFunc(("returns %Rrc\n", rc)); 1767 return rc; 1407 1768 } 1408 1769 … … 1564 1925 "PrepopulateRamDisk\0" 1565 1926 "ReadAfterWrite\0" 1566 "RecordWriteBeforeCompletion\0")) 1927 "RecordWriteBeforeCompletion\0" 1928 "ValidateMemoryBuffers\0")) 1567 1929 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES; 1568 1930 … … 1585 1947 rc = CFGMR3QueryBoolDef(pCfg, "RecordWriteBeforeCompletion", &pThis->fRecordWriteBeforeCompletion, false); 1586 1948 AssertRC(rc); 1949 rc = CFGMR3QueryBoolDef(pCfg, "ValidateMemoryBuffers", &pThis->fValidateMemBufs, true); 1950 AssertRC(rc); 1587 1951 1588 1952 char *pszIoLogFilename = NULL; … … 1604 1968 pThis->IMedia.pfnGetSize = drvdiskintGetSize; 1605 1969 pThis->IMedia.pfnIsReadOnly = drvdiskintIsReadOnly; 1970 pThis->IMedia.pfnBiosIsVisible = drvdiskintBiosIsVisible; 1606 1971 pThis->IMedia.pfnBiosGetPCHSGeometry = drvdiskintBiosGetPCHSGeometry; 1607 1972 pThis->IMedia.pfnBiosSetPCHSGeometry = drvdiskintBiosSetPCHSGeometry; … … 1610 1975 pThis->IMedia.pfnGetUuid = drvdiskintGetUuid; 1611 1976 pThis->IMedia.pfnGetSectorSize = drvdiskintGetSectorSize; 1977 pThis->IMedia.pfnGetType = drvdiskintGetType; 1612 1978 pThis->IMedia.pfnIoBufAlloc = drvdiskintIoBufAlloc; 1613 1979 pThis->IMedia.pfnIoBufFree = drvdiskintIoBufFree;
Note:
See TracChangeset
for help on using the changeset viewer.