DrvDiskIntegrity.cpp revision 81c87bd7ea74d6f5a3a5aa28d5af33f5a7a989d5
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * VBox storage devices: Disk integrity check.
38856343f90103280eb83b5e697f9f618b407d83vboxsync * Copyright (C) 2006-2010 Oracle Corporation
38856343f90103280eb83b5e697f9f618b407d83vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
38856343f90103280eb83b5e697f9f618b407d83vboxsync * available from http://www.virtualbox.org. This file is free software;
38856343f90103280eb83b5e697f9f618b407d83vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * General Public License (GPL) as published by the Free Software
38856343f90103280eb83b5e697f9f618b407d83vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
38856343f90103280eb83b5e697f9f618b407d83vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
38856343f90103280eb83b5e697f9f618b407d83vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync/*******************************************************************************
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync* Header Files *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync*******************************************************************************/
38856343f90103280eb83b5e697f9f618b407d83vboxsync/*******************************************************************************
38856343f90103280eb83b5e697f9f618b407d83vboxsync* Structures and Typedefs *
a4d7fc6f54717c342281099fe14f5666be9b7921vboxsync*******************************************************************************/
38856343f90103280eb83b5e697f9f618b407d83vboxsync * Transfer direction.
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Read */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Write */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Flush */
38856343f90103280eb83b5e697f9f618b407d83vboxsync * async I/O request.
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Transfer direction. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Start offset. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Transfer size. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Segment array. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Number of array entries. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** User argument */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Slot in the array. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Start timestamp */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Completion timestamp. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** I/O log entry if configured. */
99cd1ce586a12bf6b8c6084cbcdebe8fe3553cc2vboxsync * I/O log entry.
38856343f90103280eb83b5e697f9f618b407d83vboxsynctypedef struct IOLOGENT
99cd1ce586a12bf6b8c6084cbcdebe8fe3553cc2vboxsync /** Start offset */
99cd1ce586a12bf6b8c6084cbcdebe8fe3553cc2vboxsync /** Write size */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Number of references to this entry. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync * Disk segment.
b0553043536ae0bdf9921b91597f9dc6c316b1b4vboxsync /** AVL core. */
b0553043536ae0bdf9921b91597f9dc6c316b1b4vboxsync /** Size of the segment */
b0553043536ae0bdf9921b91597f9dc6c316b1b4vboxsync /** Data for this segment */
b0553043536ae0bdf9921b91597f9dc6c316b1b4vboxsync /** Number of entries in the I/O array. */
b0553043536ae0bdf9921b91597f9dc6c316b1b4vboxsync /** Array of I/O log references. */
b0553043536ae0bdf9921b91597f9dc6c316b1b4vboxsync * Active requests list entry.
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Pointer to the request. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Start timestamp. */
1e6f3dcff5f382b0ade59e1e7f3728e59e9b8c90vboxsync * Disk integrity driver instance data.
38856343f90103280eb83b5e697f9f618b407d83vboxsync * @implements PDMIMEDIA
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Pointer driver instance. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Pointer to the media driver below us.
38856343f90103280eb83b5e697f9f618b407d83vboxsync * This is NULL if the media is not mounted. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Our media interface */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** The media port interface above. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Media port interface */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Pointer to the media async driver below us.
38856343f90103280eb83b5e697f9f618b407d83vboxsync * This is NULL if the media is not mounted. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Our media async interface */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** The async media port interface above. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Our media async port interface */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Flag whether consistency checks are enabled. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** AVL tree containing the disk blocks to check. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Flag whether async request tracing is enabled. */
38856343f90103280eb83b5e697f9f618b407d83vboxsync /** Interval the thread should check for expired requests (milliseconds). */
bool fRunning;
volatile unsigned iNextFreeSlot;
bool fCheckDoubleCompletion;
unsigned cEntries;
unsigned iEntry;
return pIoReq;
if (!pIoLogEnt)
return VERR_NO_MEMORY;
while (cbLeft)
bool fSet = false;
unsigned offSeg = 0;
if (!pSeg)
if ( !pSeg
if (pSeg)
fSet = true;
fSet = true;
if (fSet)
if (pIoLogOld)
return rc;
while (cbLeft)
bool fCmp = false;
unsigned offSeg = 0;
if (!pSeg)
if (!pSeg)
fCmp = true;
if (fCmp)
RTMsgError("Last write to this sector started at offset %llu with %u bytes (%u references to this log entry)\n",
return rc;
if ( pIoReq
return VINF_SUCCESS;
#define PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY)((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMedia)) )
#define PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY)((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMediaAsync)) )
return rc;
return rc;
return rc;
return rc;
PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_READ, uOffset, paSeg, cSeg, cbRead, pvUser);
return rc;
PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_WRITE, uOffset, paSeg, cSeg, cbWrite, pvUser);
return rc;
return rc;
return rc;
static DECLCALLBACK(int) drvdiskintDiscard(PPDMIMEDIA pInterface, PPDMRANGE paRanges, unsigned cRanges)
return rc;
#define PDMIMEDIAASYNCPORT_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMediaAsyncPort))) )
static DECLCALLBACK(int) drvdiskintAsyncTransferCompleteNotify(PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq)
rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);
return rc;
#define PDMIMEDIAPORT_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMediaPort))) )
static DECLCALLBACK(int) drvdiskintQueryDeviceLocation(PPDMIMEDIAPORT pInterface, const char **ppcszController,
PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNC, pThis->pDrvMediaAsync ? &pThis->IMediaAsync : NULL);
return NULL;
return VINF_SUCCESS;
rc = CFGMR3QueryU32Def(pCfg, "ExpireIntervalMs", &pThis->uExpireIntervalMs, 20000); /* 20 seconds */
if (pszIoLogFilename)
return rc;
sizeof(DRVDISKINTEGRITY),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,