Example #1
0
VBOXDDU_DECL(int) VDDbgIoLogEventGetStart(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
                                          uint64_t *poff, size_t *pcbIo, size_t cbBuf, void *pvBuf)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
    AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);
    AssertPtrReturn(poff, VERR_INVALID_POINTER);
    AssertPtrReturn(pcbIo, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START)
    {
        IoLogEntryStart Entry;
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            *pfAsync   = RT_BOOL(Entry.u8AsyncIo);
            *pidEvent  = RT_LE2H_U64(Entry.u64Id);
            *poff      = RT_LE2H_U64(Entry.Io.u64Off);
            *pcbIo     = RT_LE2H_U64(Entry.Io.u64IoSize);

            if (   pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_WRITE
                && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN))
            {
                /* Read data. */
                if (cbBuf < *pcbIo)
                    rc = VERR_BUFFER_OVERFLOW;
                else
                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL);

                if (rc != VERR_BUFFER_OVERFLOW)
                    pIoLogger->offReadNext += *pcbIo + sizeof(Entry);
            }
            else
                pIoLogger->offReadNext += sizeof(Entry);
        }
    }
    else
        rc = VERR_INVALID_STATE;

    if (RT_SUCCESS(rc))
        pIoLogger->u32EventTypeNext = 0;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
Example #2
0
VBOXDDU_DECL(int) VDDbgIoLogEventGetComplete(VDIOLOGGER hIoLogger, uint64_t *pidEvent, int *pRc,
                                             uint64_t *pmsDuration, size_t *pcbIo, size_t cbBuf, void *pvBuf)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
    AssertPtrReturn(pmsDuration, VERR_INVALID_POINTER);
    AssertPtrReturn(pcbIo, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_COMPLETE)
    {
        IoLogEntryComplete Entry;
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            *pidEvent    = RT_LE2H_U64(Entry.u64Id);
            *pRc         = (int)RT_LE2H_U32((int32_t)Entry.i32Rc);
            *pmsDuration = RT_LE2H_U64(Entry.msDuration);
            *pcbIo       = RT_LE2H_U64(Entry.u64IoBuffer);

            if (*pcbIo)
            {
                /* Read data. */
                if (cbBuf < *pcbIo)
                    rc = VERR_BUFFER_OVERFLOW;
                else
                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + sizeof(Entry), pvBuf, *pcbIo, NULL);

                if (rc != VERR_BUFFER_OVERFLOW)
                    pIoLogger->offReadNext += *pcbIo + sizeof(Entry);
            }
            else
                pIoLogger->offReadNext += sizeof(Entry);
        }
    }
    else
        rc = VERR_INVALID_STATE;

    if (RT_SUCCESS(rc))
        pIoLogger->u32EventTypeNext = 0;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
/**
 * Read bytes from a file at a given offset into a S/G buffer.
 * This function may modify the file position.
 *
 * @returns iprt status code.
 * @param   hFile       Handle to the file.
 * @param   off         Where to read.
 * @param   pSgBuf      Pointer to the S/G buffer to read into.
 * @param   cbToRead    How much to read.
 * @param   pcbRead     How much we actually read.
 *                      If NULL an error will be returned for a partial read.
 */
RTR3DECL(int)  RTFileSgReadAt(RTFILE hFile, RTFOFF off, PRTSGBUF pSgBuf, size_t cbToRead, size_t *pcbRead)
{
    int rc = VINF_SUCCESS;
    size_t cbRead = 0;

    while (cbToRead)
    {
        size_t cbThisRead = 0;
        size_t cbBuf = cbToRead;
        void *pvBuf = RTSgBufGetNextSegment(pSgBuf, &cbBuf);

        rc = RTFileReadAt(hFile, off, pvBuf, cbBuf, pcbRead ? &cbThisRead : NULL);
        if (RT_SUCCESS(rc))
            cbRead += cbThisRead;

        if (   RT_FAILURE(rc)
            || (   cbThisRead < cbBuf
                && pcbRead))
            break;

        cbToRead -= cbBuf;
        off += cbBuf;
    }

    if (pcbRead)
        *pcbRead = cbRead;

    return rc;
}
static int dvmDiskRead(void *pvUser, uint64_t off, void *pvBuf, size_t cbRead)
{
    PTSTRTDVMDISK pDisk = (PTSTRTDVMDISK)pvUser;

    if (pDisk->fUseImage)
        return RTFileReadAt(pDisk->hImage, off, pvBuf, cbRead, NULL);
    return RTDvmVolumeRead(pDisk->hVol, off, pvBuf, cbRead);
}
Example #5
0
static int fileReadSyncCallback(void * /* pvUser */, void *pvStorage, uint64_t uOffset,
                                  void *pvBuf, size_t cbRead, size_t *pcbRead)
{
    /* Validate input. */
    AssertPtrReturn(pvStorage, VERR_INVALID_POINTER);

//    DEBUG_PRINT_FLOW();

    PFILESTORAGEINTERNAL pInt = (PFILESTORAGEINTERNAL)pvStorage;

    return RTFileReadAt(pInt->file, uOffset, pvBuf, cbRead, pcbRead);
}
Example #6
0
VBOXDDU_DECL(int) VDDbgIoLogEventTypeGetNext(VDIOLOGGER hIoLogger, VDIOLOGEVENT *penmEvent)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(penmEvent, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (pIoLogger->offReadNext == pIoLogger->offWriteNext)
    {
        *penmEvent = VDIOLOGEVENT_END;
        RTSemFastMutexRelease(pIoLogger->hMtx);
        return VINF_SUCCESS;
    }

    if (!pIoLogger->u32EventTypeNext)
    {
        uint32_t abBuf[2];
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &abBuf, sizeof(abBuf), NULL);
        if (RT_SUCCESS(rc))
        {
            pIoLogger->u32EventTypeNext = abBuf[0];
            pIoLogger->enmReqTypeNext   = (VDDBGIOLOGREQ)abBuf[1];
        }
    }

    if (RT_SUCCESS(rc))
    {
        Assert(pIoLogger->u32EventTypeNext != VDIOLOGEVENT_INVALID);

        switch (pIoLogger->u32EventTypeNext)
        {
            case VDIOLOG_EVENT_START:
                *penmEvent = VDIOLOGEVENT_START;
                break;
            case VDIOLOG_EVENT_COMPLETE:
                *penmEvent = VDIOLOGEVENT_COMPLETE;
                break;
            default:
                AssertMsgFailed(("Invalid event type %d\n", pIoLogger->u32EventTypeNext));
        }
    }

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;
}
DECLHIDDEN(int) drvHostBaseReadOs(PDRVHOSTBASE pThis, uint64_t off, void *pvBuf, size_t cbRead)
{
    return RTFileReadAt(pThis->Os.hFileDevice, off, pvBuf, cbRead, NULL);
}
Example #8
0
/**
 * Processes a given task list for assigned to the given endpoint.
 */
static int pdmacFileAioMgrFailsafeProcessEndpointTaskList(PPDMACEPFILEMGR pAioMgr,
                                                          PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint,
                                                          PPDMACTASKFILE pTasks)
{
    int rc = VINF_SUCCESS;

    while (pTasks)
    {
        RTMSINTERVAL msWhenNext;
        PPDMACTASKFILE pCurr = pTasks;

        if (!pdmacEpIsTransferAllowed(&pEndpoint->Core, (uint32_t)pCurr->DataSeg.cbSeg, &msWhenNext))
        {
            pAioMgr->msBwLimitExpired = RT_MIN(pAioMgr->msBwLimitExpired, msWhenNext);
            break;
        }

        pTasks = pTasks->pNext;

        switch (pCurr->enmTransferType)
        {
            case PDMACTASKFILETRANSFER_FLUSH:
            {
                rc = RTFileFlush(pEndpoint->hFile);
                break;
            }
            case PDMACTASKFILETRANSFER_READ:
            case PDMACTASKFILETRANSFER_WRITE:
            {
                if (pCurr->enmTransferType == PDMACTASKFILETRANSFER_READ)
                {
                    rc = RTFileReadAt(pEndpoint->hFile, pCurr->Off,
                                      pCurr->DataSeg.pvSeg,
                                      pCurr->DataSeg.cbSeg,
                                      NULL);
                }
                else
                {
                    if (RT_UNLIKELY((uint64_t)pCurr->Off + pCurr->DataSeg.cbSeg > pEndpoint->cbFile))
                    {
                        ASMAtomicWriteU64(&pEndpoint->cbFile, pCurr->Off + pCurr->DataSeg.cbSeg);
                        RTFileSetSize(pEndpoint->hFile, pCurr->Off + pCurr->DataSeg.cbSeg);
                    }

                    rc = RTFileWriteAt(pEndpoint->hFile, pCurr->Off,
                                       pCurr->DataSeg.pvSeg,
                                       pCurr->DataSeg.cbSeg,
                                       NULL);
                }

                break;
            }
            default:
                AssertMsgFailed(("Invalid transfer type %d\n", pTasks->enmTransferType));
        }

        pCurr->pfnCompleted(pCurr, pCurr->pvUser, rc);
        pdmacFileTaskFree(pEndpoint, pCurr);
    }

    if (pTasks)
    {
        /* Add the rest of the tasks to the pending list */
        pdmacFileAioMgrEpAddTaskList(pEndpoint, pTasks);
    }

    return VINF_SUCCESS;
}
Example #9
0
VBOXDDU_DECL(int) VDDbgIoLogEventGetStartDiscard(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
                                                 PRTRANGE *ppaRanges, unsigned *pcRanges)
{
    int rc = VINF_SUCCESS;
    PVDIOLOGGERINT pIoLogger = hIoLogger;

    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
    AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);

    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    AssertRCReturn(rc, rc);

    if (   pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START
        && pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_DISCARD)
    {
        IoLogEntryStart Entry;
        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
        if (RT_SUCCESS(rc))
        {
            PRTRANGE paRanges = NULL;
            IoLogEntryDiscard DiscardRange;

            pIoLogger->offReadNext += sizeof(Entry);
            *pfAsync   = RT_BOOL(Entry.u8AsyncIo);
            *pidEvent  = RT_LE2H_U64(Entry.u64Id);
            *pcRanges  = RT_LE2H_U32(Entry.Discard.cRanges);

            paRanges = (PRTRANGE)RTMemAllocZ(*pcRanges * sizeof(RTRANGE));
            if (paRanges)
            {
                for (unsigned i = 0; i < *pcRanges; i++)
                {
                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + i*sizeof(DiscardRange),
                                      &DiscardRange, sizeof(DiscardRange), NULL);
                    if (RT_FAILURE(rc))
                        break;

                    paRanges[i].offStart = RT_LE2H_U64(DiscardRange.u64Off);
                    paRanges[i].cbRange  = RT_LE2H_U32(DiscardRange.u32Discard);
                }

                if (RT_SUCCESS(rc))
                {
                    pIoLogger->offReadNext += *pcRanges * sizeof(DiscardRange);
                    *ppaRanges = paRanges;
                }
                else
                {
                    pIoLogger->offReadNext -= sizeof(Entry);
                    RTMemFree(paRanges);
                }
            }
            else
                rc = VERR_NO_MEMORY;
        }
    }
    else
        rc = VERR_INVALID_STATE;

    if (RT_SUCCESS(rc))
        pIoLogger->u32EventTypeNext = 0;

    RTSemFastMutexRelease(pIoLogger->hMtx);
    return rc;

}