VirtualBox

Ignore:
Timestamp:
Sep 5, 2011 10:53:16 AM (13 years ago)
Author:
vboxsync
Message:

IoLog+DrvDiskIntegrity: Add logging of discard requests

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/Debug/VDDbgIoLog.cpp

    r38552 r38631  
    6363{
    6464    /** Event type. */
    65     uint8_t     u8Type;
     65    uint32_t    u32Type;
     66    /** Transfer type. */
     67    uint32_t    u32ReqType;
    6668    /** Flag whether this is a sync or async request. */
    6769    uint8_t     u8AsyncIo;
    6870    /** Id of the entry. */
    6971    uint64_t    u64Id;
    70     /** Transfer direction. */
    71     uint8_t     u8TxDir;
    72     /** Start offset. */
    73     uint64_t    u64Off;
    74     /** Size of the request. */
    75     uint64_t    u64IoSize;
     72    /** Type dependent data. */
     73    union
     74    {
     75        /** I/O. */
     76        struct
     77        {
     78            /** Start offset. */
     79            uint64_t    u64Off;
     80            /** Size of the request. */
     81            uint64_t    u64IoSize;
     82        } Io;
     83        /** Discard */
     84        struct
     85        {
     86            /** Number of ranges to discard. */
     87            uint32_t    cRanges;
     88        } Discard;
     89    };
    7690} IoLogEntryStart;
    7791#pragma pack()
     
    8498{
    8599    /** Event type. */
    86     uint8_t     u8Type;
     100    uint8_t     u32Type;
    87101    /** Id of the matching start entry. */
    88102    uint64_t    u64Id;
     
    94108    uint64_t    u64IoBuffer;
    95109} IoLogEntryComplete;
     110#pragma pack()
     111
     112#pragma pack(1)
     113typedef struct IoLogEntryDiscard
     114{
     115    /** Start offset. */
     116    uint64_t    u64Off;
     117    /** Number of bytes to discard. */
     118    uint32_t    u32Discard;
     119} IoLogEntryDiscard;
    96120#pragma pack()
    97121
     
    120144    RTSEMFASTMUTEX hMtx;
    121145    /** Cached event type of the next event. */
    122     uint8_t        u8EventTypeNext;
     146    uint32_t       u32EventTypeNext;
     147    /** Cached request type of the next request. */
     148    VDDBGIOLOGREQ  enmReqTypeNext;
    123149} VDIOLOGGERINT;
    124150/** Pointer to the internal I/O logger instance data. */
     
    348374}
    349375
    350 VBOXDDU_DECL(int) VDDbgIoLogStart(VDIOLOGGER hIoLogger, bool fAsync, VDDBGIOLOGTXDIR enmTxDir, uint64_t off, size_t cbIo, PCRTSGBUF pSgBuf,
     376VBOXDDU_DECL(int) VDDbgIoLogStart(VDIOLOGGER hIoLogger, bool fAsync, VDDBGIOLOGREQ enmTxDir, uint64_t off, size_t cbIo, PCRTSGBUF pSgBuf,
    351377                                  PVDIOLOGENT phIoLogEntry)
    352378{
     
    357383    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    358384    AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER);
    359     AssertReturn(enmTxDir > VDDBGIOLOGTXDIR_INVALID && enmTxDir <= VDDBGIOLOGTXDIR_FLUSH, VERR_INVALID_PARAMETER);
     385    AssertReturn(enmTxDir > VDDBGIOLOGREQ_INVALID && enmTxDir <= VDDBGIOLOGREQ_FLUSH, VERR_INVALID_PARAMETER);
    360386
    361387    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
     
    369395        pIoLogEntry->idStart = pIoLogger->idNext++;
    370396
    371         Entry.u8Type    = VDIOLOG_EVENT_START;
    372         Entry.u8AsyncIo = fAsync ? 1 : 0;
    373         Entry.u8TxDir   = (uint8_t)enmTxDir;
    374         Entry.u64Off    = RT_H2LE_U64(off);
    375         Entry.u64IoSize = RT_H2LE_U64(cbIo);
    376         Entry.u64Id     = RT_H2LE_U64(pIoLogEntry->idStart);
     397        Entry.u32Type       = VDIOLOG_EVENT_START;
     398        Entry.u8AsyncIo    = fAsync ? 1 : 0;
     399        Entry.u32ReqType   = enmTxDir;
     400        Entry.u64Id        = RT_H2LE_U64(pIoLogEntry->idStart);
     401        Entry.Io.u64Off    = RT_H2LE_U64(off);
     402        Entry.Io.u64IoSize = RT_H2LE_U64(cbIo);
    377403
    378404        /* Write new entry. */
     
    382408            pIoLogger->offWriteNext += sizeof(Entry);
    383409
    384             if (   enmTxDir == VDDBGIOLOGTXDIR_WRITE
     410            if (   enmTxDir == VDDBGIOLOGREQ_WRITE
    385411                && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN))
    386412            {
     
    401427            pIoLogEntry->tsStart = RTTimeProgramMilliTS();
    402428
    403             if (   enmTxDir == VDDBGIOLOGTXDIR_READ
     429            if (   enmTxDir == VDDBGIOLOGREQ_READ
    404430                && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_READ))
    405431                pIoLogEntry->cbIo = cbIo;
     
    422448}
    423449
    424 VBOXDDU_DECL(int) VDDbgIoLogComplete(VDIOLOGGER hIoLogger, VDIOLOGENT hIoLogEntry, int rcReq, PCRTSGBUF pSgBuf)
    425 {
    426     int rc = VINF_SUCCESS;
    427     PVDIOLOGGERINT pIoLogger = hIoLogger;
    428     PVDIOLOGENTINT pIoLogEntry = hIoLogEntry;
    429 
    430     AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
    431     AssertPtrReturn(pIoLogEntry, VERR_INVALID_HANDLE);
     450VBOXDDU_DECL(int) VDDbgIoLogStartDiscard(VDIOLOGGER hIoLogger, bool fAsync, PVDRANGE paRanges, unsigned cRanges,
     451                                         PVDIOLOGENT phIoLogEntry)
     452{
     453    int rc = VINF_SUCCESS;
     454    PVDIOLOGGERINT pIoLogger = hIoLogger;
     455    PVDIOLOGENTINT pIoLogEntry = NULL;
     456
     457    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
     458    AssertPtrReturn(phIoLogEntry, VERR_INVALID_POINTER);
    432459
    433460    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
    434461    AssertRCReturn(rc, rc);
    435462
     463    pIoLogEntry = (PVDIOLOGENTINT)RTMemCacheAlloc(pIoLogger->hMemCacheIoLogEntries);
     464    if (pIoLogEntry)
     465    {
     466        IoLogEntryStart Entry;
     467
     468        pIoLogEntry->idStart = pIoLogger->idNext++;
     469
     470        Entry.u32Type          = VDIOLOG_EVENT_START;
     471        Entry.u8AsyncIo       = fAsync ? 1 : 0;
     472        Entry.u32ReqType      = VDDBGIOLOGREQ_DISCARD;
     473        Entry.Discard.cRanges = RT_H2LE_U32(cRanges);
     474
     475        /* Write new entry. */
     476        rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext, &Entry, sizeof(Entry), NULL);
     477        if (RT_SUCCESS(rc))
     478        {
     479            pIoLogger->offWriteNext += sizeof(Entry);
     480
     481            IoLogEntryDiscard DiscardRange;
     482
     483            for (unsigned i = 0; i < cRanges; i++)
     484            {
     485                DiscardRange.u64Off = RT_H2LE_U64(paRanges[i].offStart);
     486                DiscardRange.u32Discard = RT_H2LE_U32(paRanges[i].cbRange);
     487                rc = RTFileWriteAt(pIoLogger->hFile, pIoLogger->offWriteNext + i*sizeof(DiscardRange),
     488                                   &DiscardRange, sizeof(DiscardRange), NULL);
     489                if (RT_FAILURE(rc))
     490                    break;
     491            }
     492
     493            if (RT_FAILURE(rc))
     494            {
     495                pIoLogger->offWriteNext -= sizeof(Entry);
     496                rc = RTFileSetSize(pIoLogger->hFile, pIoLogger->offWriteNext);
     497            }
     498            else
     499                pIoLogger->offWriteNext += cRanges * sizeof(DiscardRange);
     500        }
     501
     502        if (RT_SUCCESS(rc))
     503        {
     504            pIoLogEntry->tsStart = RTTimeProgramMilliTS();
     505            pIoLogEntry->cbIo = 0;
     506
     507            *phIoLogEntry = pIoLogEntry;
     508        }
     509        else
     510        {
     511            pIoLogger->idNext--;
     512            RTMemCacheFree(pIoLogger->hMemCacheIoLogEntries, pIoLogEntry);
     513        }
     514    }
     515    else
     516        rc = VERR_NO_MEMORY;
     517
     518    RTSemFastMutexRelease(pIoLogger->hMtx);
     519    return rc;
     520}
     521
     522VBOXDDU_DECL(int) VDDbgIoLogComplete(VDIOLOGGER hIoLogger, VDIOLOGENT hIoLogEntry, int rcReq, PCRTSGBUF pSgBuf)
     523{
     524    int rc = VINF_SUCCESS;
     525    PVDIOLOGGERINT pIoLogger = hIoLogger;
     526    PVDIOLOGENTINT pIoLogEntry = hIoLogEntry;
     527
     528    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
     529    AssertPtrReturn(pIoLogEntry, VERR_INVALID_HANDLE);
     530
     531    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
     532    AssertRCReturn(rc, rc);
     533
    436534    IoLogEntryComplete Entry;
    437535
    438     Entry.u8Type      = VDIOLOG_EVENT_COMPLETE;
     536    Entry.u32Type     = VDIOLOG_EVENT_COMPLETE;
    439537    Entry.u64Id       = RT_H2LE_U64(pIoLogEntry->idStart);
    440538    Entry.msDuration  = RTTimeProgramMilliTS() - RT_H2LE_U64(pIoLogEntry->tsStart);
     
    484582    }
    485583
    486     if (!pIoLogger->u8EventTypeNext)
    487         rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &pIoLogger->u8EventTypeNext, sizeof(uint8_t), NULL);
     584    if (!pIoLogger->u32EventTypeNext)
     585    {
     586        uint32_t abBuf[2];
     587        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &abBuf, sizeof(abBuf), NULL);
     588        if (RT_SUCCESS(rc))
     589        {
     590            pIoLogger->u32EventTypeNext = (VDIOLOGEVENT)abBuf[0];
     591            pIoLogger->enmReqTypeNext   = (VDDBGIOLOGREQ)abBuf[1];
     592        }
     593    }
    488594
    489595    if (RT_SUCCESS(rc))
    490596    {
    491         Assert(pIoLogger->u8EventTypeNext != 0);
    492 
    493         switch (pIoLogger->u8EventTypeNext)
     597        Assert(pIoLogger->u32EventTypeNext != VDIOLOGEVENT_INVALID);
     598
     599        switch (pIoLogger->u32EventTypeNext)
    494600        {
    495601            case VDIOLOG_EVENT_START:
     
    500606                break;
    501607            default:
    502                 AssertMsgFailed(("Invalid event type %d\n", pIoLogger->u8EventTypeNext));
     608                AssertMsgFailed(("Invalid event type %d\n", pIoLogger->u32EventTypeNext));
    503609        }
    504610    }
     
    508614}
    509615
    510 VBOXDDU_DECL(int) VDDbgIoLogEventGetStart(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync, PVDDBGIOLOGTXDIR penmTxDir,
     616VBOXDDU_DECL(int) VDDbgIoLogReqTypeGetNext(VDIOLOGGER hIoLogger, PVDDBGIOLOGREQ penmReq)
     617{
     618    int rc = VINF_SUCCESS;
     619    PVDIOLOGGERINT pIoLogger = hIoLogger;
     620
     621    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
     622    AssertPtrReturn(penmReq, VERR_INVALID_POINTER);
     623
     624    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
     625    AssertRCReturn(rc, rc);
     626
     627    if (pIoLogger->offReadNext == pIoLogger->offWriteNext)
     628    {
     629        *penmReq = VDDBGIOLOGREQ_INVALID;
     630        RTSemFastMutexRelease(pIoLogger->hMtx);
     631        return VERR_INVALID_STATE;
     632    }
     633
     634    if (RT_SUCCESS(rc))
     635    {
     636        Assert(pIoLogger->enmReqTypeNext != VDDBGIOLOGREQ_INVALID);
     637        *penmReq = pIoLogger->enmReqTypeNext;
     638    }
     639
     640    RTSemFastMutexRelease(pIoLogger->hMtx);
     641    return rc;
     642}
     643
     644VBOXDDU_DECL(int) VDDbgIoLogEventGetStart(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
    511645                                          uint64_t *poff, size_t *pcbIo, size_t cbBuf, void *pvBuf)
    512646{
     
    517651    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
    518652    AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);
    519     AssertPtrReturn(penmTxDir, VERR_INVALID_POINTER);
    520653    AssertPtrReturn(poff, VERR_INVALID_POINTER);
    521654    AssertPtrReturn(pcbIo, VERR_INVALID_POINTER);
     
    524657    AssertRCReturn(rc, rc);
    525658
    526     if (pIoLogger->u8EventTypeNext == VDIOLOG_EVENT_START)
     659    if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START)
    527660    {
    528661        IoLogEntryStart Entry;
     
    530663        if (RT_SUCCESS(rc))
    531664        {
    532             *penmTxDir = (VDDBGIOLOGTXDIR)Entry.u8TxDir;
    533665            *pfAsync   = (bool)Entry.u8AsyncIo;
    534666            *pidEvent  = RT_LE2H_U64(Entry.u64Id);
    535             *poff      = RT_LE2H_U64(Entry.u64Off);
    536             *pcbIo     = RT_LE2H_U64(Entry.u64IoSize);
    537 
    538             if (   *penmTxDir == VDDBGIOLOGTXDIR_WRITE
     667            *poff      = RT_LE2H_U64(Entry.Io.u64Off);
     668            *pcbIo     = RT_LE2H_U64(Entry.Io.u64IoSize);
     669
     670            if (   pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_WRITE
    539671                && (pIoLogger->fFlags & VDDBG_IOLOG_LOG_DATA_WRITTEN))
    540672            {
     
    559691}
    560692
     693VBOXDDU_DECL(int) VDDbgIoLogEventGetStartDiscard(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
     694                                                 PVDRANGE *ppaRanges, unsigned *pcRanges)
     695{
     696    int rc = VINF_SUCCESS;
     697    PVDIOLOGGERINT pIoLogger = hIoLogger;
     698
     699    AssertPtrReturn(pIoLogger, VERR_INVALID_HANDLE);
     700    AssertPtrReturn(pidEvent, VERR_INVALID_POINTER);
     701    AssertPtrReturn(pfAsync, VERR_INVALID_POINTER);
     702
     703    rc = RTSemFastMutexRequest(pIoLogger->hMtx);
     704    AssertRCReturn(rc, rc);
     705
     706    if (   pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_START
     707        && pIoLogger->enmReqTypeNext == VDDBGIOLOGREQ_DISCARD)
     708    {
     709        IoLogEntryStart Entry;
     710        rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext, &Entry, sizeof(Entry), NULL);
     711        if (RT_SUCCESS(rc))
     712        {
     713            PVDRANGE paRanges = NULL;
     714            IoLogEntryDiscard DiscardRange;
     715
     716            pIoLogger->offReadNext += sizeof(Entry);
     717            *pfAsync   = (bool)Entry.u8AsyncIo;
     718            *pidEvent  = RT_LE2H_U64(Entry.u64Id);
     719            *pcRanges  = RT_LE2H_U32(Entry.Discard.cRanges);
     720
     721            paRanges = (PVDRANGE)RTMemAllocZ(*pcRanges * sizeof(VDRANGE));
     722            if (paRanges)
     723            {
     724                for (unsigned i = 0; i < *pcRanges; i++)
     725                {
     726                    rc = RTFileReadAt(pIoLogger->hFile, pIoLogger->offReadNext + i*sizeof(DiscardRange),
     727                                      &DiscardRange, sizeof(DiscardRange), NULL);
     728                    if (RT_FAILURE(rc))
     729                        break;
     730
     731                    paRanges[i].offStart = RT_LE2H_U64(DiscardRange.u64Off);
     732                    paRanges[i].cbRange  = RT_LE2H_U32(DiscardRange.u32Discard);
     733                }
     734
     735                if (RT_SUCCESS(rc))
     736                {
     737                    pIoLogger->offReadNext += *pcRanges * sizeof(DiscardRange);
     738                    *ppaRanges = paRanges;
     739                }
     740                else
     741                    pIoLogger->offReadNext -= sizeof(Entry);
     742            }
     743            else
     744                rc = VERR_NO_MEMORY;
     745        }
     746    }
     747    else
     748        rc = VERR_INVALID_STATE;
     749
     750    RTSemFastMutexRelease(pIoLogger->hMtx);
     751    return rc;
     752
     753}
     754
    561755VBOXDDU_DECL(int) VDDbgIoLogEventGetComplete(VDIOLOGGER hIoLogger, uint64_t *pidEvent, int *pRc,
    562756                                             uint64_t *pmsDuration, size_t *pcbIo, size_t cbBuf, void *pvBuf)
     
    573767    AssertRCReturn(rc, rc);
    574768
    575     if (pIoLogger->u8EventTypeNext == VDIOLOG_EVENT_COMPLETE)
     769    if (pIoLogger->u32EventTypeNext == VDIOLOG_EVENT_COMPLETE)
    576770    {
    577771        IoLogEntryComplete Entry;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette