VirtualBox

Changeset 51619 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Jun 16, 2014 9:10:42 AM (11 years ago)
Author:
vboxsync
Message:

Devices/Storage: Add new read after write verification mode and fix driver crash after the interface changed

File:
1 edited

Legend:

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

    r46859 r51619  
    5353    DRVDISKAIOTXDIR_FLUSH,
    5454    /** Discard */
    55     DRVDISKAIOTXDIR_DISCARD
     55    DRVDISKAIOTXDIR_DISCARD,
     56    /** Read after write for immediate verification. */
     57    DRVDISKAIOTXDIR_READ_AFTER_WRITE
    5658} DRVDISKAIOTXDIR;
    5759
     
    191193    /** Current entry in the array. */
    192194    unsigned                iEntry;
     195
     196    /** Flag whether to do a immediate read after write for verification. */
     197    bool                    fReadAfterWrite;
    193198
    194199    /** I/O logger to use if enabled. */
     
    716721}
    717722
     723/**
     724 * Verify a completed read after write request.
     725 *
     726 * @returns VBox status code.
     727 * @param   pThis    The driver instance data.
     728 * @param   pIoReq   The request to be verified.
     729 */
     730static int drvdiskintReadAfterWriteVerify(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)
     731{
     732    int rc = VINF_SUCCESS;
     733
     734    if (pThis->fCheckConsistency)
     735        rc = drvdiskintReadVerify(pThis, pIoReq->paSeg, pIoReq->cSeg, pIoReq->off, pIoReq->cbTransfer);
     736    else /** @todo: Implement read after write verification without a memory based image of the disk. */
     737        AssertMsgFailed(("TODO\n"));
     738
     739    return rc;
     740}
     741
    718742/* -=-=-=-=- IMedia -=-=-=-=- */
    719743
     
    10721096    PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
    10731097    return pThis->pDrvMedia->pfnGetUuid(pThis->pDrvMedia, pUuid);
     1098}
     1099
     1100/** @copydoc PDMIMEDIA::pfnGetSectorSize */
     1101static DECLCALLBACK(uint32_t) drvdiskintGetSectorSize(PPDMIMEDIA pInterface)
     1102{
     1103    PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
     1104    return pThis->pDrvMedia->pfnGetSectorSize(pThis->pDrvMedia);
    10741105}
    10751106
     
    11261157        else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_DISCARD)
    11271158            rc = drvdiskintDiscardRecords(pThis, pIoReq->paRanges, pIoReq->cRanges);
     1159        else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ_AFTER_WRITE)
     1160            rc = drvdiskintReadAfterWriteVerify(pThis, pIoReq);
    11281161        else
    11291162            AssertMsg(pIoReq->enmTxDir == DRVDISKAIOTXDIR_FLUSH, ("Huh?\n"));
     
    11431176    }
    11441177
    1145     void *pvUserComplete = pIoReq->pvUser;
    1146 
    1147     drvdiskintIoReqFree(pThis, pIoReq);
    1148 
    1149     rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);
     1178    if (   pThis->fReadAfterWrite
     1179        && pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE)
     1180    {
     1181        pIoReq->enmTxDir = DRVDISKAIOTXDIR_READ_AFTER_WRITE;
     1182
     1183        /* Readd because it was rmeoved above. */
     1184        if (pThis->fTraceRequests)
     1185            drvdiskintIoReqAdd(pThis, pIoReq);
     1186
     1187        rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, pIoReq->off, pIoReq->paSeg, pIoReq->cSeg,
     1188                                                 pIoReq->cbTransfer, pIoReq);
     1189        if (rc == VINF_VD_ASYNC_IO_FINISHED)
     1190        {
     1191            rc = drvdiskintReadAfterWriteVerify(pThis, pIoReq);
     1192
     1193            if (pThis->fTraceRequests)
     1194                drvdiskintIoReqRemove(pThis, pIoReq);
     1195            RTMemFree(pIoReq);
     1196        }
     1197        else if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     1198            rc = VINF_SUCCESS;
     1199        else if (RT_FAILURE(rc))
     1200            RTMemFree(pIoReq);
     1201    }
     1202    else
     1203    {
     1204        void *pvUserComplete = pIoReq->pvUser;
     1205        drvdiskintIoReqFree(pThis, pIoReq);
     1206
     1207        rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);
     1208    }
    11501209
    11511210    return rc;
     
    12561315                                    "HistorySize\0"
    12571316                                    "IoLog\0"
    1258                                     "PrepopulateRamDisk\0"))
     1317                                    "PrepopulateRamDisk\0"
     1318                                    "ReadAfterWrite\0"))
    12591319        return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
    12601320
     
    12731333    rc = CFGMR3QueryBoolDef(pCfg, "PrepopulateRamDisk", &pThis->fPrepopulateRamDisk, false);
    12741334    AssertRC(rc);
     1335    rc = CFGMR3QueryBoolDef(pCfg, "ReadAfterWrite", &pThis->fReadAfterWrite, false);
     1336    AssertRC(rc);
    12751337
    12761338    char *pszIoLogFilename = NULL;
     
    12971359    pThis->IMedia.pfnBiosSetLCHSGeometry = drvdiskintBiosSetLCHSGeometry;
    12981360    pThis->IMedia.pfnGetUuid             = drvdiskintGetUuid;
     1361    pThis->IMedia.pfnGetSectorSize       = drvdiskintGetSectorSize;
    12991362
    13001363    /* IMediaAsync */
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