summaryrefslogtreecommitdiff
path: root/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Storage/DrvDiskIntegrity.cpp')
-rw-r--r--src/VBox/Devices/Storage/DrvDiskIntegrity.cpp66
1 files changed, 63 insertions, 3 deletions
diff --git a/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp b/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
index fa63d050..76419351 100644
--- a/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
+++ b/src/VBox/Devices/Storage/DrvDiskIntegrity.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -160,6 +160,8 @@ typedef struct DRVDISKINTEGRITY
/** Flag whether consistency checks are enabled. */
bool fCheckConsistency;
+ /** Flag whether the RAM disk was prepopulated. */
+ bool fPrepopulateRamDisk;
/** AVL tree containing the disk blocks to check. */
PAVLRFOFFTREE pTreeSegments;
@@ -437,6 +439,17 @@ static int drvdiskintReadVerify(PDRVDISKINTEGRITY pThis, PCRTSGSEG paSeg, unsign
cbRange = cbLeft;
else
cbRange = pSeg->Core.Key - offCurr;
+
+ if (pThis->fPrepopulateRamDisk)
+ {
+ /* No segment means everything should be 0 for this part. */
+ if (!RTSgBufIsZero(&SgBuf, cbRange))
+ {
+ RTMsgError("Corrupted disk at offset %llu (expected everything to be 0)!\n",
+ offCurr);
+ RTAssertDebugBreak();
+ }
+ }
}
else
{
@@ -522,7 +535,7 @@ static int drvdiskintDiscardRecords(PDRVDISKINTEGRITY pThis, PCRTRANGE paRanges,
{
size_t cbPreLeft, cbPostLeft;
- cbRange = RT_MIN(cbRange, pSeg->Core.KeyLast - offStart + 1);
+ cbRange = RT_MIN(cbLeft, pSeg->Core.KeyLast - offStart + 1);
cbPreLeft = offStart - pSeg->Core.Key;
cbPostLeft = pSeg->cbSeg - cbRange - cbPreLeft;
@@ -1241,7 +1254,8 @@ static DECLCALLBACK(int) drvdiskintConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg,
"ExpireIntervalMs\0"
"CheckDoubleCompletions\0"
"HistorySize\0"
- "IoLog\0"))
+ "IoLog\0"
+ "PrepopulateRamDisk\0"))
return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
rc = CFGMR3QueryBoolDef(pCfg, "CheckConsistency", &pThis->fCheckConsistency, false);
@@ -1256,6 +1270,8 @@ static DECLCALLBACK(int) drvdiskintConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg,
AssertRC(rc);
rc = CFGMR3QueryU32Def(pCfg, "HistorySize", &pThis->cEntries, 512);
AssertRC(rc);
+ rc = CFGMR3QueryBoolDef(pCfg, "PrepopulateRamDisk", &pThis->fPrepopulateRamDisk, false);
+ AssertRC(rc);
char *pszIoLogFilename = NULL;
rc = CFGMR3QueryStringAlloc(pCfg, "IoLog", &pszIoLogFilename);
@@ -1363,6 +1379,50 @@ static DECLCALLBACK(int) drvdiskintConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg,
MMR3HeapFree(pszIoLogFilename);
}
+ /* Read in all data before the start if requested. */
+ if (pThis->fPrepopulateRamDisk)
+ {
+ uint64_t cbDisk = 0;
+
+ LogRel(("DiskIntegrity: Prepopulating RAM disk, this will take some time...\n"));
+
+ cbDisk = pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia);
+ if (cbDisk)
+ {
+ uint64_t off = 0;
+ uint8_t abBuffer[_64K];
+ RTSGSEG Seg;
+
+ Seg.pvSeg = abBuffer;
+
+ while (cbDisk)
+ {
+ size_t cbThisRead = RT_MIN(cbDisk, sizeof(abBuffer));
+
+ rc = pThis->pDrvMedia->pfnRead(pThis->pDrvMedia, off, abBuffer, cbThisRead);
+ if (RT_FAILURE(rc))
+ break;
+
+ if (ASMBitFirstSet(abBuffer, sizeof(abBuffer) * 8) != -1)
+ {
+ Seg.cbSeg = cbThisRead;
+ rc = drvdiskintWriteRecord(pThis, &Seg, 1,
+ off, cbThisRead);
+ if (RT_FAILURE(rc))
+ break;
+ }
+
+ cbDisk -= cbThisRead;
+ off += cbThisRead;
+ }
+
+ LogRel(("DiskIntegrity: Prepopulating RAM disk finished with %Rrc\n", rc));
+ }
+ else
+ return PDMDRV_SET_ERROR(pDrvIns, VERR_INTERNAL_ERROR,
+ N_("DiskIntegrity: Error querying the media size below"));
+ }
+
return rc;
}