VirtualBox

Changeset 63727 in vbox


Ignore:
Timestamp:
Sep 5, 2016 4:27:27 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
110503
Message:

DiskIntegrity: Updates to handle the PDMIMEDIAEX interface

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp

    r63700 r63727  
    4747typedef enum DRVDISKAIOTXDIR
    4848{
     49    /** Invalid. */
     50    DRVDISKAIOTXDIR_INVALID = 0,
    4951    /** Read */
    50     DRVDISKAIOTXDIR_READ = 0,
     52    DRVDISKAIOTXDIR_READ,
    5153    /** Write */
    5254    DRVDISKAIOTXDIR_WRITE,
     
    8890    /** Number of ranges. */
    8991    unsigned        cRanges;
     92    /** I/O segment for the extended media interface
     93     * to hold the data. */
     94    RTSGSEG         IoSeg;
    9095} DRVDISKAIOREQ, *PDRVDISKAIOREQ;
    9196
     
    210215     * Useful in case the data is modified in place later on (encryption for instance). */
    211216    bool                    fRecordWriteBeforeCompletion;
     217    /** Flag whether to validate memory buffers when the extended media interface is used. */
     218    bool                    fValidateMemBufs;
    212219
    213220    /** I/O logger to use if enabled. */
    214221    VDIOLOGGER              hIoLogger;
     222    /** Size of the opaque handle until our tracking structure starts in bytes. */
     223    size_t                  cbIoReqOpaque;
    215224} DRVDISKINTEGRITY, *PDRVDISKINTEGRITY;
    216225
     
    249258}
    250259
     260static 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
    251289/**
    252290 * Free a async I/O request.
     
    256294 * @param   pIoReq    The I/O request to free.
    257295 */
    258 static void drvdiskintIoReqFree(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)
     296static void drvdiskintReqFree(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)
    259297{
    260298    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 */);
    285300    else
    286301        RTMemFree(pIoReq);
     
    359374                {
    360375                    bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core);
    361                     AssertMsg(fInserted, ("Bug!\n"));
     376                    AssertMsg(fInserted, ("Bug!\n")); RT_NOREF(fInserted);
    362377                    fSet = true;
    363378                }
     
    375390            AssertPtr(pSeg);
    376391            size_t cbCopied = RTSgBufCopyToBuf(&SgBuf, pSeg->pbSeg + offSeg, cbRange);
    377             Assert(cbCopied == cbRange);
     392            Assert(cbCopied == cbRange); RT_NOREF(cbCopied);
    378393
    379394            /* Update the I/O log pointers */
     
    589604                    pSeg->cIoLogEntries = cbPreLeft / 512;
    590605                    bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core);
    591                     Assert(fInserted);
     606                    Assert(fInserted); RT_NOREF(fInserted);
    592607                }
    593608                else if (!cbPreLeft && cbPostLeft)
     
    606621                    pSeg->cIoLogEntries = cbPostLeft / 512;
    607622                    bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core);
    608                     Assert(fInserted);
     623                    Assert(fInserted); RT_NOREF(fInserted);
    609624                }
    610625                else
     
    629644
    630645                            bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSegPost->Core);
    631                             Assert(fInserted);
     646                            Assert(fInserted); RT_NOREF(fInserted);
    632647                        }
    633648                    }
     
    642657                    pSeg->cIoLogEntries = cbPreLeft / 512;
    643658                    bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core);
    644                     Assert(fInserted);
     659                    Assert(fInserted); RT_NOREF(fInserted);
    645660                } /* if (cbPreLeft && cbPostLeft) */
    646661            }
     
    712727            break;
    713728
    714         Assert(rc == VERR_TIMEOUT);
     729        Assert(rc == VERR_TIMEOUT); RT_NOREF(rc);
    715730
    716731        /* Get current timestamp for comparison. */
     
    10931108    PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
    10941109    return pThis->pDrvMedia->pfnIsReadOnly(pThis->pDrvMedia);
     1110}
     1111
     1112/** @interface_method_impl{PDMIMEDIA,pfnBiosIsVisible} */
     1113static 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} */
     1120static DECLCALLBACK(PDMMEDIATYPE) drvdiskintGetType(PPDMIMEDIA pInterface)
     1121{
     1122    PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
     1123    return pThis->pDrvMedia->pfnGetType(pThis->pDrvMedia);
    10951124}
    10961125
     
    12481277        pIoReq->enmTxDir = DRVDISKAIOTXDIR_READ_AFTER_WRITE;
    12491278
    1250         /* Readd because it was rmeoved above. */
     1279        /* Add again because it was removed above. */
    12511280        if (pThis->fTraceRequests)
    12521281            drvdiskintIoReqAdd(pThis, pIoReq);
     
    12701299    {
    12711300        void *pvUserComplete = pIoReq->pvUser;
    1272         drvdiskintIoReqFree(pThis, pIoReq);
     1301        drvdiskintReqFree(pThis, pIoReq);
    12731302
    12741303        rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);
     
    13041333{
    13051334    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;
    13071435}
    13081436
     
    13151443{
    13161444    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;
    13191460}
    13201461
     
    13271468{
    13281469    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;
    13311501}
    13321502
     
    13381508{
    13391509    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);
    13411513}
    13421514
     
    13491521{
    13501522    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
    13511529    return pThis->pDrvMediaEx->pfnIoReqAllocSizeSet(pThis->pDrvMediaEx, cbIoReqAlloc);
    13521530}
     
    13591537{
    13601538    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;
    13621572}
    13631573
     
    13681578{
    13691579    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
    13701585    return pThis->pDrvMediaEx->pfnIoReqFree(pThis->pDrvMediaEx, hIoReq);
    13711586}
     
    13861601{
    13871602    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;
    13891652}
    13901653
     
    13951658{
    13961659    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;
    13981732}
    13991733
     
    14041738{
    14051739    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;
    14071768}
    14081769
     
    15641925                                    "PrepopulateRamDisk\0"
    15651926                                    "ReadAfterWrite\0"
    1566                                     "RecordWriteBeforeCompletion\0"))
     1927                                    "RecordWriteBeforeCompletion\0"
     1928                                    "ValidateMemoryBuffers\0"))
    15671929        return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
    15681930
     
    15851947    rc = CFGMR3QueryBoolDef(pCfg, "RecordWriteBeforeCompletion", &pThis->fRecordWriteBeforeCompletion, false);
    15861948    AssertRC(rc);
     1949    rc = CFGMR3QueryBoolDef(pCfg, "ValidateMemoryBuffers", &pThis->fValidateMemBufs, true);
     1950    AssertRC(rc);
    15871951
    15881952    char *pszIoLogFilename = NULL;
     
    16041968    pThis->IMedia.pfnGetSize             = drvdiskintGetSize;
    16051969    pThis->IMedia.pfnIsReadOnly          = drvdiskintIsReadOnly;
     1970    pThis->IMedia.pfnBiosIsVisible       = drvdiskintBiosIsVisible;
    16061971    pThis->IMedia.pfnBiosGetPCHSGeometry = drvdiskintBiosGetPCHSGeometry;
    16071972    pThis->IMedia.pfnBiosSetPCHSGeometry = drvdiskintBiosSetPCHSGeometry;
     
    16101975    pThis->IMedia.pfnGetUuid             = drvdiskintGetUuid;
    16111976    pThis->IMedia.pfnGetSectorSize       = drvdiskintGetSectorSize;
     1977    pThis->IMedia.pfnGetType             = drvdiskintGetType;
    16121978    pThis->IMedia.pfnIoBufAlloc          = drvdiskintIoBufAlloc;
    16131979    pThis->IMedia.pfnIoBufFree           = drvdiskintIoBufFree;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette