Index: /trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp	(revision 51618)
+++ /trunk/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp	(revision 51619)
@@ -53,5 +53,7 @@
     DRVDISKAIOTXDIR_FLUSH,
     /** Discard */
-    DRVDISKAIOTXDIR_DISCARD
+    DRVDISKAIOTXDIR_DISCARD,
+    /** Read after write for immediate verification. */
+    DRVDISKAIOTXDIR_READ_AFTER_WRITE
 } DRVDISKAIOTXDIR;
 
@@ -191,4 +193,7 @@
     /** Current entry in the array. */
     unsigned                iEntry;
+
+    /** Flag whether to do a immediate read after write for verification. */
+    bool                    fReadAfterWrite;
 
     /** I/O logger to use if enabled. */
@@ -716,4 +721,23 @@
 }
 
+/**
+ * Verify a completed read after write request.
+ *
+ * @returns VBox status code.
+ * @param   pThis    The driver instance data.
+ * @param   pIoReq   The request to be verified.
+ */
+static int drvdiskintReadAfterWriteVerify(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)
+{
+    int rc = VINF_SUCCESS;
+
+    if (pThis->fCheckConsistency)
+        rc = drvdiskintReadVerify(pThis, pIoReq->paSeg, pIoReq->cSeg, pIoReq->off, pIoReq->cbTransfer);
+    else /** @todo: Implement read after write verification without a memory based image of the disk. */
+        AssertMsgFailed(("TODO\n"));
+
+    return rc;
+}
+
 /* -=-=-=-=- IMedia -=-=-=-=- */
 
@@ -1072,4 +1096,11 @@
     PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
     return pThis->pDrvMedia->pfnGetUuid(pThis->pDrvMedia, pUuid);
+}
+
+/** @copydoc PDMIMEDIA::pfnGetSectorSize */
+static DECLCALLBACK(uint32_t) drvdiskintGetSectorSize(PPDMIMEDIA pInterface)
+{
+    PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
+    return pThis->pDrvMedia->pfnGetSectorSize(pThis->pDrvMedia);
 }
 
@@ -1126,4 +1157,6 @@
         else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_DISCARD)
             rc = drvdiskintDiscardRecords(pThis, pIoReq->paRanges, pIoReq->cRanges);
+        else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_READ_AFTER_WRITE)
+            rc = drvdiskintReadAfterWriteVerify(pThis, pIoReq);
         else
             AssertMsg(pIoReq->enmTxDir == DRVDISKAIOTXDIR_FLUSH, ("Huh?\n"));
@@ -1143,9 +1176,35 @@
     }
 
-    void *pvUserComplete = pIoReq->pvUser;
-
-    drvdiskintIoReqFree(pThis, pIoReq);
-
-    rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);
+    if (   pThis->fReadAfterWrite
+        && pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE)
+    {
+        pIoReq->enmTxDir = DRVDISKAIOTXDIR_READ_AFTER_WRITE;
+
+        /* Readd because it was rmeoved above. */
+        if (pThis->fTraceRequests)
+            drvdiskintIoReqAdd(pThis, pIoReq);
+
+        rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, pIoReq->off, pIoReq->paSeg, pIoReq->cSeg,
+                                                 pIoReq->cbTransfer, pIoReq);
+        if (rc == VINF_VD_ASYNC_IO_FINISHED)
+        {
+            rc = drvdiskintReadAfterWriteVerify(pThis, pIoReq);
+
+            if (pThis->fTraceRequests)
+                drvdiskintIoReqRemove(pThis, pIoReq);
+            RTMemFree(pIoReq);
+        }
+        else if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
+            rc = VINF_SUCCESS;
+        else if (RT_FAILURE(rc))
+            RTMemFree(pIoReq);
+    }
+    else
+    {
+        void *pvUserComplete = pIoReq->pvUser;
+        drvdiskintIoReqFree(pThis, pIoReq);
+
+        rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);
+    }
 
     return rc;
@@ -1256,5 +1315,6 @@
                                     "HistorySize\0"
                                     "IoLog\0"
-                                    "PrepopulateRamDisk\0"))
+                                    "PrepopulateRamDisk\0"
+                                    "ReadAfterWrite\0"))
         return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
 
@@ -1273,4 +1333,6 @@
     rc = CFGMR3QueryBoolDef(pCfg, "PrepopulateRamDisk", &pThis->fPrepopulateRamDisk, false);
     AssertRC(rc);
+    rc = CFGMR3QueryBoolDef(pCfg, "ReadAfterWrite", &pThis->fReadAfterWrite, false);
+    AssertRC(rc);
 
     char *pszIoLogFilename = NULL;
@@ -1297,4 +1359,5 @@
     pThis->IMedia.pfnBiosSetLCHSGeometry = drvdiskintBiosSetLCHSGeometry;
     pThis->IMedia.pfnGetUuid             = drvdiskintGetUuid;
+    pThis->IMedia.pfnGetSectorSize       = drvdiskintGetSectorSize;
 
     /* IMediaAsync */
