DrvDiskIntegrity.cpp revision 2531fa93e6b9dd1b60eac57f360a47e38aaf4d41
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * VBox storage devices: Disk integrity check.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Copyright (C) 2006-2010 Oracle Corporation
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * available from http://www.virtualbox.org. This file is free software;
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * you can redistribute it and/or modify it under the terms of the GNU
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * General Public License (GPL) as published by the Free Software
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
82bcaaf8077ba892f39afb721dca149353c63d2cvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/*******************************************************************************
b6cba2c351e97805b97998ebe48e03ecef16b59avboxsync* Header Files *
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync*******************************************************************************/
8112e0942f1128329b99b22a20b395963d4abceavboxsync/*******************************************************************************
8112e0942f1128329b99b22a20b395963d4abceavboxsync* Structures and Typedefs *
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync*******************************************************************************/
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Transfer direction.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Read */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Write */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Flush */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * async I/O request.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Transfer direction. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Start offset. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Transfer size. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Segment array. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Number of array entries. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** User argument */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Slot in the array. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Start timestamp */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /** Completion timestamp. */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /** I/O log entry if configured. */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * I/O log entry.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsynctypedef struct IOLOGENT
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /** Start offset */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /** Write size */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Number of references to this entry. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Disk segment.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** AVL core. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Size of the segment */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Data for this segment */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Number of entries in the I/O array. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Array of I/O log references. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Active requests list entry.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Pointer to the request. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Start timestamp. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Disk integrity driver instance data.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @implements PDMIMEDIA
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Pointer driver instance. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Pointer to the media driver below us.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * This is NULL if the media is not mounted. */
0cbaa6b7062076428f638cc5afba9d16200c6076vboxsync /** Our media interface */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** The media port interface above. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Media port interface */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Pointer to the media async driver below us.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * This is NULL if the media is not mounted. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Our media async interface */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** The async media port interface above. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Our media async port interface */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Flag whether consistency checks are enabled. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** AVL tree containing the disk blocks to check. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Flag whether async request tracing is enabled. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Interval the thread should check for expired requests (milliseconds). */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Expire timeout for a request (milliseconds). */
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync /** Thread which checks for lost requests. */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /** Event semaphore */
6cd65034f702d9b4122249011835e9639a7bc660vboxsync /** Flag whether the thread should run. */
6cd65034f702d9b4122249011835e9639a7bc660vboxsync /** Array containing active requests. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Next free slot in the array */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync volatile unsigned iNextFreeSlot;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Flag whether we check for requests completing twice. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Number of requests we go back. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Array of completed but still observed requests. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** Current entry in the array. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /** I/O logger to use if enabled. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Allocate a new I/O request.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @returns New I/O request.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param enmTxDir Transfer direction.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param off Start offset.
8112e0942f1128329b99b22a20b395963d4abceavboxsync * @param paSeg Segment array.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param cSeg Number of segments.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param cbTransfer Number of bytes to transfer.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param pvUser User argument.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic PDRVDISKAIOREQ drvdiskintIoReqAlloc(DRVDISKAIOTXDIR enmTxDir, uint64_t off, PCRTSGSEG paSeg,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKAIOREQ pIoReq = (PDRVDISKAIOREQ)RTMemAlloc(sizeof(DRVDISKAIOREQ));
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * Free a async I/O request.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * @returns nothing.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * @param pThis Disk driver.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * @param pIoReq The I/O request to free.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsyncstatic void drvdiskintIoReqFree(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /* Search if the I/O request completed already. */
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync RTMsgError("Request %#p completed already!\n", pIoReq);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync RTMsgError("Start timestamp %llu Completion timestamp %llu (completed after %llu ms)\n",
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync pIoReq->tsStart, pIoReq->tsComplete, pIoReq->tsComplete - pIoReq->tsStart);
8112e0942f1128329b99b22a20b395963d4abceavboxsync pThis->iEntry = (pThis->iEntry+1) % pThis->cEntries;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Record a successful write to the virtual disk.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @returns VBox status code.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param pThis Disk integrity driver instance data.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param paSeg Segment array of the write to record.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param cSeg Number of segments.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param off Start offset.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @param cbWrite Number of bytes to record.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic int drvdiskintWriteRecord(PDRVDISKINTEGRITY pThis, PCRTSGSEG paSeg, unsigned cSeg,
8112e0942f1128329b99b22a20b395963d4abceavboxsync LogFlowFunc(("pThis=%#p paSeg=%#p cSeg=%u off=%llx cbWrite=%u\n",
8112e0942f1128329b99b22a20b395963d4abceavboxsync /* Update the segments */
8112e0942f1128329b99b22a20b395963d4abceavboxsync PIOLOGENT pIoLogEnt = (PIOLOGENT)RTMemAllocZ(sizeof(IOLOGENT));
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKSEGMENT pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetRangeGet(pThis->pTreeSegments, offCurr);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync bool fSet = false;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync unsigned offSeg = 0;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* Get next segment */
500d759609a43a472c7a29b58f3479ed319a5a76vboxsync pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetGetBestFit(pThis->pTreeSegments, offCurr, true);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* Create new segment */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pSeg = (PDRVDISKSEGMENT)RTMemAllocZ(RT_OFFSETOF(DRVDISKSEGMENT, apIoLog[cbRange / 512]));
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pSeg->Core.KeyLast = offCurr + (RTFOFF)cbRange - 1;
8112e0942f1128329b99b22a20b395963d4abceavboxsync bool fInserted = RTAvlrFileOffsetInsert(pThis->pTreeSegments, &pSeg->Core);
8112e0942f1128329b99b22a20b395963d4abceavboxsync cbRange = RT_MIN(cbLeft, (size_t)(pSeg->Core.KeyLast + 1 - offCurr));
8112e0942f1128329b99b22a20b395963d4abceavboxsync size_t cbCopied = RTSgBufCopyToBuf(&SgBuf, pSeg->pbSeg + offSeg, cbRange);
8112e0942f1128329b99b22a20b395963d4abceavboxsync /* Update the I/O log pointers */
500d759609a43a472c7a29b58f3479ed319a5a76vboxsync AssertMsg(uSector < pSeg->cIoLogEntries, ("Internal bug!\n"));
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync * Verifies a read request.
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync * @returns VBox status code.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * @param pThis Disk integrity driver instance data.
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync * @param paSeg Segment array of the containing the data buffers to verify.
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync * @param cSeg Number of segments.
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync * @param off Start offset.
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync * @param cbWrite Number of bytes to verify.
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsyncstatic int drvdiskintReadVerify(PDRVDISKINTEGRITY pThis, PCRTSGSEG paSeg, unsigned cSeg,
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync LogFlowFunc(("pThis=%#p paSeg=%#p cSeg=%u off=%llx cbRead=%u\n",
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /* Compare read data */
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync PDRVDISKSEGMENT pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetRangeGet(pThis->pTreeSegments, offCurr);
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync bool fCmp = false;
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync unsigned offSeg = 0;
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync /* Get next segment */
37b83e04cd69f1fdddc315640acef2cdfddb0f46vboxsync pSeg = (PDRVDISKSEGMENT)RTAvlrFileOffsetGetBestFit(pThis->pTreeSegments, offCurr, true);
8112e0942f1128329b99b22a20b395963d4abceavboxsync /* No data in the tree for this read. Assume everything is ok. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync else if (offCurr + (RTFOFF)cbLeft <= pSeg->Core.Key)
8112e0942f1128329b99b22a20b395963d4abceavboxsync cbRange = RT_MIN(cbLeft, (size_t)(pSeg->Core.KeyLast + 1 - offCurr));
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync if (RTSgBufCmpEx(&SgBuf, &SgBufCmp, cbRange, &cbOff, true))
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /* Corrupted disk, print I/O log entry of the last write which accessed this range. */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync AssertMsg(cSector < pSeg->cIoLogEntries, ("Internal bug!\n"));
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync RTMsgError("Corrupted disk at offset %llu (%u bytes in the current read buffer)!\n",
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync RTMsgError("Last write to this sector started at offset %llu with %u bytes (%u references to this log entry)\n",
d28bd01ede12da4a939e81a155d227ee4d6ff634vboxsync * Adds a request to the active list.
d28bd01ede12da4a939e81a155d227ee4d6ff634vboxsync * @returns nothing.
8112e0942f1128329b99b22a20b395963d4abceavboxsync * @param pThis The driver instance data.
8112e0942f1128329b99b22a20b395963d4abceavboxsync * @param pIoReq The request to add.
8112e0942f1128329b99b22a20b395963d4abceavboxsyncstatic void drvdiskintIoReqAdd(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)
8112e0942f1128329b99b22a20b395963d4abceavboxsync PDRVDISKAIOREQACTIVE pReqActive = &pThis->apReqActive[pThis->iNextFreeSlot];
1a1433dbc5e55f83cbcde6aa9f045c2dc7eeb9e7vboxsync /* Search for the next one. */
8112e0942f1128329b99b22a20b395963d4abceavboxsync while (pThis->apReqActive[pThis->iNextFreeSlot].pIoReq)
8112e0942f1128329b99b22a20b395963d4abceavboxsync pThis->iNextFreeSlot = (pThis->iNextFreeSlot+1) % RT_ELEMENTS(pThis->apReqActive);
d28bd01ede12da4a939e81a155d227ee4d6ff634vboxsync * Removes a request from the active list.
d28bd01ede12da4a939e81a155d227ee4d6ff634vboxsync * @returns nothing.
8112e0942f1128329b99b22a20b395963d4abceavboxsync * @param pThis The driver instance data.
8112e0942f1128329b99b22a20b395963d4abceavboxsync * @param pIoReq The request to remove.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsyncstatic void drvdiskintIoReqRemove(PDRVDISKINTEGRITY pThis, PDRVDISKAIOREQ pIoReq)
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync PDRVDISKAIOREQACTIVE pReqActive = &pThis->apReqActive[pIoReq->iSlot];
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * Thread checking for expired requests.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * @returns IPRT status code.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * @param pThread Thread handle.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * @param pvUser Opaque user data.
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsyncstatic int drvdiskIntIoReqExpiredCheck(RTTHREAD pThread, void *pvUser)
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync PDRVDISKINTEGRITY pThis = (PDRVDISKINTEGRITY)pvUser;
8112e0942f1128329b99b22a20b395963d4abceavboxsync int rc = RTSemEventWait(pThis->SemEvent, pThis->uCheckIntervalMs);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* Get current timestamp for comparison. */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /* Go through the array and check for expired requests. */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync for (unsigned i = 0; i < RT_ELEMENTS(pThis->apReqActive); i++)
8112e0942f1128329b99b22a20b395963d4abceavboxsync PDRVDISKAIOREQACTIVE pReqActive = &pThis->apReqActive[i];
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKAIOREQ pIoReq = ASMAtomicReadPtrT(&pReqActive->pIoReq, PDRVDISKAIOREQ);
8112e0942f1128329b99b22a20b395963d4abceavboxsync && (tsCurr - pReqActive->tsStart) >= pThis->uExpireIntervalMs)
8112e0942f1128329b99b22a20b395963d4abceavboxsync RTMsgError("Request %#p expired (active for %llu ms already)\n",
8112e0942f1128329b99b22a20b395963d4abceavboxsync/* -=-=-=-=- IMedia -=-=-=-=- */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** Makes a PDRVDISKINTEGRITY out of a PPDMIMEDIA. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync#define PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY)((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMedia)) )
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** Makes a PDRVDISKINTEGRITY out of a PPDMIMEDIAASYNC. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync#define PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY)((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMediaAsync)) )
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/*******************************************************************************
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync* Media interface methods *
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync*******************************************************************************/
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnRead */
874be5c5b701726b68fa1391022ae2f5c7768894vboxsyncstatic DECLCALLBACK(int) drvdiskintRead(PPDMIMEDIA pInterface,
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync rc = VDDbgIoLogStart(pThis->hIoLogger, false, VDDBGIOLOGTXDIR_READ, off,
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync rc = pThis->pDrvMedia->pfnRead(pThis->pDrvMedia, off, pvBuf, cbRead);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, hIoLogEntry, rc, &SgBuf);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* Verify the read. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync rc = drvdiskintReadVerify(pThis, &Seg, 1, off, cbRead);
8112e0942f1128329b99b22a20b395963d4abceavboxsync/** @copydoc PDMIMEDIA::pfnWrite */
8112e0942f1128329b99b22a20b395963d4abceavboxsyncstatic DECLCALLBACK(int) drvdiskintWrite(PPDMIMEDIA pInterface,
8112e0942f1128329b99b22a20b395963d4abceavboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync rc = VDDbgIoLogStart(pThis->hIoLogger, false, VDDBGIOLOGTXDIR_WRITE, off,
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync rc = pThis->pDrvMedia->pfnWrite(pThis->pDrvMedia, off, pvBuf, cbWrite);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, hIoLogEntry, rc, NULL);
8112e0942f1128329b99b22a20b395963d4abceavboxsync /* Record the write. */
8112e0942f1128329b99b22a20b395963d4abceavboxsync rc = drvdiskintWriteRecord(pThis, &Seg, 1, off, cbWrite);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintStartRead(PPDMIMEDIAASYNC pInterface, uint64_t uOffset,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync LogFlow(("%s: uOffset=%#llx paSeg=%#p cSeg=%u cbRead=%d pvUser=%#p\n", __FUNCTION__,
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_READ, uOffset, paSeg, cSeg, cbRead, pvUser);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync int rc2 = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGTXDIR_READ, uOffset,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, uOffset, paSeg, cSeg,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* Verify the read now. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc2 = drvdiskintReadVerify(pThis, paSeg, cSeg, uOffset, cbRead);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, &SgBuf);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintStartWrite(PPDMIMEDIAASYNC pInterface, uint64_t uOffset,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync LogFlow(("%s: uOffset=%#llx paSeg=%#p cSeg=%u cbWrite=%d pvUser=%#p\n", __FUNCTION__,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_WRITE, uOffset, paSeg, cSeg, cbWrite, pvUser);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc2 = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGTXDIR_WRITE, uOffset,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc = pThis->pDrvMediaAsync->pfnStartWrite(pThis->pDrvMediaAsync, uOffset, paSeg, cSeg,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* Record the write. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc2 = drvdiskintWriteRecord(pThis, paSeg, cSeg, uOffset, cbWrite);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, NULL);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIAASYNC::pfnStartFlush */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintStartFlush(PPDMIMEDIAASYNC pInterface, void *pvUser)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIAASYNC_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKAIOREQ pIoReq = drvdiskintIoReqAlloc(DRVDISKAIOTXDIR_FLUSH, 0, NULL, 0, 0, pvUser);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync rc = VDDbgIoLogStart(pThis->hIoLogger, true, VDDBGIOLOGTXDIR_FLUSH, 0,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync rc = pThis->pDrvMediaAsync->pfnStartFlush(pThis->pDrvMediaAsync, pIoReq);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, VINF_SUCCESS, NULL);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnFlush */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintFlush(PPDMIMEDIA pInterface)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync rc = VDDbgIoLogStart(pThis->hIoLogger, false, VDDBGIOLOGTXDIR_FLUSH, 0,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, hIoLogEntry, rc, NULL);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnGetSize */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(uint64_t) drvdiskintGetSize(PPDMIMEDIA pInterface)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnIsReadOnly */
eac945b2260779f7c5d44d8015bcc4779498c6f9vboxsyncstatic DECLCALLBACK(bool) drvdiskintIsReadOnly(PPDMIMEDIA pInterface)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return pThis->pDrvMedia->pfnIsReadOnly(pThis->pDrvMedia);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintBiosGetPCHSGeometry(PPDMIMEDIA pInterface,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return pThis->pDrvMedia->pfnBiosGetPCHSGeometry(pThis->pDrvMedia, pPCHSGeometry);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintBiosSetPCHSGeometry(PPDMIMEDIA pInterface,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return pThis->pDrvMedia->pfnBiosSetPCHSGeometry(pThis->pDrvMedia, pPCHSGeometry);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintBiosGetLCHSGeometry(PPDMIMEDIA pInterface,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return pThis->pDrvMedia->pfnBiosGetLCHSGeometry(pThis->pDrvMedia, pLCHSGeometry);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintBiosSetLCHSGeometry(PPDMIMEDIA pInterface,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return pThis->pDrvMedia->pfnBiosSetLCHSGeometry(pThis->pDrvMedia, pLCHSGeometry);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync/** @copydoc PDMIMEDIA::pfnGetUuid */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(int) drvdiskintGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIA_2_DRVDISKINTEGRITY(pInterface);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return pThis->pDrvMedia->pfnGetUuid(pThis->pDrvMedia, pUuid);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync/* -=-=-=-=- IMediaAsyncPort -=-=-=-=- */
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync/** Makes a PDRVBLOCKASYNC out of a PPDMIMEDIAASYNCPORT. */
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync#define PDMIMEDIAASYNCPORT_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMediaAsyncPort))) )
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsyncstatic DECLCALLBACK(int) drvdiskintAsyncTransferCompleteNotify(PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq)
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIAASYNCPORT_2_DRVDISKINTEGRITY(pInterface);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync /* Remove from the active list. */
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync rc = drvdiskintReadVerify(pThis, pIoReq->paSeg, pIoReq->cSeg, pIoReq->off, pIoReq->cbTransfer);
9d7572b5c359aff94b3c20fc0177e24567bdde6evboxsync else if (pIoReq->enmTxDir == DRVDISKAIOTXDIR_WRITE)
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync rc = drvdiskintWriteRecord(pThis, pIoReq->paSeg, pIoReq->cSeg, pIoReq->off, pIoReq->cbTransfer);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync AssertMsg(pIoReq->enmTxDir == DRVDISKAIOTXDIR_FLUSH, ("Huh?\n"));
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync int rc2 = VDDbgIoLogComplete(pThis->hIoLogger, pIoReq->hIoLogEntry, rc, &SgBuf);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort, pvUserComplete, rcReq);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync/* -=-=-=-=- IMediaPort -=-=-=-=- */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync/** Makes a PDRVBLOCK out of a PPDMIMEDIAPORT. */
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync#define PDMIMEDIAPORT_2_DRVDISKINTEGRITY(pInterface) ( (PDRVDISKINTEGRITY((uintptr_t)pInterface - RT_OFFSETOF(DRVDISKINTEGRITY, IMediaPort))) )
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync * @interface_method_impl{PDMIMEDIAPORT,pfnQueryDeviceLocation}
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsyncstatic DECLCALLBACK(int) drvdiskintQueryDeviceLocation(PPDMIMEDIAPORT pInterface, const char **ppcszController,
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync PDRVDISKINTEGRITY pThis = PDMIMEDIAPORT_2_DRVDISKINTEGRITY(pInterface);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync return pThis->pDrvMediaPort->pfnQueryDeviceLocation(pThis->pDrvMediaPort, ppcszController,
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync/* -=-=-=-=- IBase -=-=-=-=- */
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync * @interface_method_impl{PDMIBASE,pfnQueryInterface}
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsyncstatic DECLCALLBACK(void *) drvdiskintQueryInterface(PPDMIBASE pInterface, const char *pszIID)
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync PDRVDISKINTEGRITY pThis = PDMINS_2_DATA(pDrvIns, PDRVDISKINTEGRITY);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNC, pThis->pDrvMediaAsync ? &pThis->IMediaAsync : NULL);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNCPORT, &pThis->IMediaAsyncPort);
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAPORT, &pThis->IMediaPort);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync/* -=-=-=-=- driver interface -=-=-=-=- */
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsyncstatic int drvdiskintTreeDestroy(PAVLRFOFFNODECORE pNode, void *pvUser)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * @copydoc FNPDMDRVDESTRUCT
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsyncstatic DECLCALLBACK(void) drvdiskintDestruct(PPDMDRVINS pDrvIns)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync PDRVDISKINTEGRITY pThis = PDMINS_2_DATA(pDrvIns, PDRVDISKINTEGRITY);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync RTAvlrFileOffsetDestroy(pThis->pTreeSegments, drvdiskintTreeDestroy, NULL);
8112e0942f1128329b99b22a20b395963d4abceavboxsync /* Free all requests */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->iEntry = (pThis->iEntry+1) % pThis->cEntries;
8112e0942f1128329b99b22a20b395963d4abceavboxsync * Construct a disk integrity driver instance.
8112e0942f1128329b99b22a20b395963d4abceavboxsync * @copydoc FNPDMDRVCONSTRUCT
8112e0942f1128329b99b22a20b395963d4abceavboxsyncstatic DECLCALLBACK(int) drvdiskintConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
8112e0942f1128329b99b22a20b395963d4abceavboxsync PDRVDISKINTEGRITY pThis = PDMINS_2_DATA(pDrvIns, PDRVDISKINTEGRITY);
8112e0942f1128329b99b22a20b395963d4abceavboxsync LogFlow(("drvdiskintConstruct: iInstance=%d\n", pDrvIns->iInstance));
8112e0942f1128329b99b22a20b395963d4abceavboxsync * Validate configuration.
8112e0942f1128329b99b22a20b395963d4abceavboxsync if (!CFGMR3AreValuesValid(pCfg, "CheckConsistency\0"
8112e0942f1128329b99b22a20b395963d4abceavboxsync "TraceRequests\0"
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync "CheckIntervalMs\0"
8112e0942f1128329b99b22a20b395963d4abceavboxsync "ExpireIntervalMs\0"
bb2f3a7f00e605b890f8a8a74969f551cc9a0477vboxsync "CheckDoubleCompletions\0"
8112e0942f1128329b99b22a20b395963d4abceavboxsync "HistorySize\0"
8112e0942f1128329b99b22a20b395963d4abceavboxsync "IoLog\0"))
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync rc = CFGMR3QueryBoolDef(pCfg, "CheckConsistency", &pThis->fCheckConsistency, false);
8112e0942f1128329b99b22a20b395963d4abceavboxsync rc = CFGMR3QueryBoolDef(pCfg, "TraceRequests", &pThis->fTraceRequests, false);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync rc = CFGMR3QueryU32Def(pCfg, "CheckIntervalMs", &pThis->uCheckIntervalMs, 5000); /* 5 seconds */
8112e0942f1128329b99b22a20b395963d4abceavboxsync rc = CFGMR3QueryU32Def(pCfg, "ExpireIntervalMs", &pThis->uExpireIntervalMs, 20000); /* 20 seconds */
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync rc = CFGMR3QueryBoolDef(pCfg, "CheckDoubleCompletions", &pThis->fCheckDoubleCompletion, false);
689866c0e5e611f2db46822ae47724b55a27a1a0vboxsync rc = CFGMR3QueryU32Def(pCfg, "HistorySize", &pThis->cEntries, 512);
0cbaa6b7062076428f638cc5afba9d16200c6076vboxsync rc = CFGMR3QueryStringAlloc(pCfg, "IoLog", &pszIoLogFilename);
0cbaa6b7062076428f638cc5afba9d16200c6076vboxsync Assert(RT_SUCCESS(rc) || rc == VERR_CFGM_VALUE_NOT_FOUND);
fdd17dc68230654ee0796918863927fca10a9f0avboxsync * Initialize most of the data members.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* IBase. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pDrvIns->IBase.pfnQueryInterface = drvdiskintQueryInterface;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* IMedia */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMedia.pfnIsReadOnly = drvdiskintIsReadOnly;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMedia.pfnBiosGetPCHSGeometry = drvdiskintBiosGetPCHSGeometry;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMedia.pfnBiosSetPCHSGeometry = drvdiskintBiosSetPCHSGeometry;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMedia.pfnBiosGetLCHSGeometry = drvdiskintBiosGetLCHSGeometry;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMedia.pfnBiosSetLCHSGeometry = drvdiskintBiosSetLCHSGeometry;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* IMediaAsync */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMediaAsync.pfnStartRead = drvdiskintStartRead;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMediaAsync.pfnStartWrite = drvdiskintStartWrite;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMediaAsync.pfnStartFlush = drvdiskintStartFlush;
eb02731cc4b3e9d61f26f793a4e27602826b0d52vboxsync /* IMediaAsyncPort. */
eb02731cc4b3e9d61f26f793a4e27602826b0d52vboxsync pThis->IMediaAsyncPort.pfnTransferCompleteNotify = drvdiskintAsyncTransferCompleteNotify;
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* IMediaPort. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->IMediaPort.pfnQueryDeviceLocation = drvdiskintQueryDeviceLocation;
3fe24a3690526efc4cceece3819d628caadf3140vboxsync /* Query the media port interface above us. */
0cbaa6b7062076428f638cc5afba9d16200c6076vboxsync pThis->pDrvMediaPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAPORT);
0cbaa6b7062076428f638cc5afba9d16200c6076vboxsync return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW,
eb02731cc4b3e9d61f26f793a4e27602826b0d52vboxsync /* Try to attach async media port interface above.*/
eb02731cc4b3e9d61f26f793a4e27602826b0d52vboxsync pThis->pDrvMediaAsyncPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMEDIAASYNCPORT);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Try attach driver below and query it's media interface.
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->pDrvMediaAsync = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIAASYNC);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* Create the AVL tree. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync pThis->pTreeSegments = (PAVLRFOFFTREE)RTMemAllocZ(sizeof(AVLRFOFFTREE));
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync for (unsigned i = 0; i < RT_ELEMENTS(pThis->apReqActive); i++)
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* Init event semaphore. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync rc = RTThreadCreate(&pThis->hThread, drvdiskIntIoReqExpiredCheck, pThis,
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync 0, RTTHREADTYPE_INFREQUENT_POLLER, 0, "DiskIntegrity");
eb02731cc4b3e9d61f26f793a4e27602826b0d52vboxsync pThis->papIoReq = (PDRVDISKAIOREQ *)RTMemAllocZ(pThis->cEntries * sizeof(PDRVDISKAIOREQ));
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync rc = VDDbgIoLogCreate(&pThis->hIoLogger, pszIoLogFilename, VDDBG_IOLOG_LOG_DATA);
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync * Block driver registration record.
eb02731cc4b3e9d61f26f793a4e27602826b0d52vboxsync /* u32Version */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* szName */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync "DiskIntegrity",
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* szRCMod */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* szR0Mod */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pszDescription */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync "Disk integrity driver.",
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* fFlags */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* fClass. */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* cMaxInstances */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* cbInstance */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnConstruct */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnDestruct */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnRelocate */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnIOCtl */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnPowerOn */
eb02731cc4b3e9d61f26f793a4e27602826b0d52vboxsync /* pfnReset */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnSuspend */
eb02731cc4b3e9d61f26f793a4e27602826b0d52vboxsync /* pfnResume */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnAttach */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnDetach */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnPowerOff */
ae0f2178b9a5aded928e0245cb830ba1d3d04c57vboxsync /* pfnSoftReset */
3aab9f739cebfaa93f6a5a51e293310619d55a5bvboxsync /* u32EndVersion */