diff options
Diffstat (limited to 'src/VBox/Devices/Storage/DrvDiskIntegrity.cpp')
| -rw-r--r-- | src/VBox/Devices/Storage/DrvDiskIntegrity.cpp | 66 |
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; } |
