VirtualBox

Changeset 59536 in vbox for trunk/src/VBox/Devices/Storage


Ignore:
Timestamp:
Feb 1, 2016 9:03:33 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
105329
Message:

Storage: Move the suspend on recoverable error handling down to DrvVD when PDMIMEDIAEX is used

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r59476 r59536  
    153153    /** The request was allocated and is in use. */
    154154    VDIOREQSTATE_ACTIVE,
     155    /** The request was suspended and is not actively processed. */
     156    VDIOREQSTATE_SUSPENDED,
    155157    /** The request is in the last step of completion and syncs memory. */
    156158    VDIOREQSTATE_COMPLETING,
     
    171173    /** List node for the list of allocated requests. */
    172174    RTLISTNODE                    NdAllocatedList;
    173     /** List for requests waiting for I/O memory. */
    174     RTLISTNODE                    NdLstIoBufWait;
     175    /** List for requests waiting for I/O memory or on the redo list. */
     176    RTLISTNODE                    NdLstWait;
    175177    /** I/O request type. */
    176178    PDMMEDIAEXIOREQTYPE           enmType;
     
    183185    /** Flags. */
    184186    uint32_t                      fFlags;
    185     /** Start offset of the request. */
    186     uint64_t                      offStart;
    187     /** Size of the request. */
    188     size_t                        cbReq;
    189     /** Size left for this request. */
    190     size_t                        cbReqLeft;
    191     /** Size of the allocated I/O buffer. */
    192     size_t                        cbIoBuf;
    193     /** I/O buffer descriptor. */
    194     IOBUFDESC                     IoBuf;
     187    /** Type dependent data. */
     188    union
     189    {
     190        /** Read/Write request sepcific data. */
     191        struct
     192        {
     193            /** Start offset of the request. */
     194            uint64_t                      offStart;
     195            /** Size of the request. */
     196            size_t                        cbReq;
     197            /** Size left for this request. */
     198            size_t                        cbReqLeft;
     199            /** Size of the allocated I/O buffer. */
     200            size_t                        cbIoBuf;
     201            /** I/O buffer descriptor. */
     202            IOBUFDESC                     IoBuf;
     203        } ReadWrite;
     204        /** Discard specific data. */
     205        struct
     206        {
     207            /** Pointer to array of ranges to discard. */
     208            PRTRANGE                      paRanges;
     209            /** Number of ranges to discard. */
     210            unsigned                      cRanges;
     211        } Discard;
     212    };
    195213    /** Allocator specific memory - variable size. */
    196214    uint8_t                       abAlloc[1];
     
    357375    /** Bins for allocated requests. */
    358376    VDLSTIOREQALLOC          aIoReqAllocBins[DRVVD_VDIOREQ_ALLOC_BINS];
    359     /** List of requests for I/O memory to be available - VDIOREQ::NdLstIoBufWait. */
     377    /** List of requests for I/O memory to be available - VDIOREQ::NdLstWait. */
    360378    RTLISTANCHOR             LstIoReqIoBufWait;
    361379    /** Critical section protecting the list of requests waiting for I/O memory. */
     
    363381    /** Number of requests waiting for a I/O buffer. */
    364382    volatile uint32_t        cIoReqsWaiting;
     383    /** Flag whether we have to resubmit requests on resume because the
     384     * VM was suspended due to a recoverable I/O error.
     385     */
     386    volatile bool            fRedo;
     387    /** List of requests we have to redo. */
     388    RTLISTANCHOR             LstIoReqRedo;
     389    /** Criticial section protecting the list of waiting requests. */
     390    RTCRITSECT               CritSectIoReqRedo;
    365391    /** @} */
    366392} VBOXDISK;
     
    26902716*********************************************************************************************************************************/
    26912717
     2718static void drvvdMediaExIoReqWarningDiskFull(PPDMDRVINS pDrvIns)
     2719{
     2720    int rc;
     2721    LogRel(("VD#%u: Host disk full\n", pDrvIns->iInstance));
     2722    rc = PDMDrvHlpVMSetRuntimeError(pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DISKFULL",
     2723                                    N_("Host system reported disk full. VM execution is suspended. You can resume after freeing some space"));
     2724    AssertRC(rc);
     2725}
     2726
     2727static void drvvdMediaExIoReqWarningFileTooBig(PPDMDRVINS pDrvIns)
     2728{
     2729    int rc;
     2730    LogRel(("VD#%u: File too big\n", pDrvIns->iInstance));
     2731    rc = PDMDrvHlpVMSetRuntimeError(pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_FILETOOBIG",
     2732                                    N_("Host system reported that the file size limit of the host file system has been exceeded. VM execution is suspended. You need to move your virtual hard disk to a filesystem which allows bigger files"));
     2733    AssertRC(rc);
     2734}
     2735
     2736static void drvvdMediaExIoReqWarningISCSI(PPDMDRVINS pDrvIns)
     2737{
     2738    int rc;
     2739    LogRel(("VD#%u: iSCSI target unavailable\n", pDrvIns->iInstance));
     2740    rc = PDMDrvHlpVMSetRuntimeError(pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_ISCSIDOWN",
     2741                                    N_("The iSCSI target has stopped responding. VM execution is suspended. You can resume when it is available again"));
     2742    AssertRC(rc);
     2743}
     2744
     2745/**
     2746 * Checks whether a given status code indicates a recoverable error
     2747 * suspending the VM if it is.
     2748 *
     2749 * @returns Flag indicating whether the status code is a recoverable error
     2750 *          (full disk, broken network connection).
     2751 * @param   pThis     VBox disk container instance data.
     2752 * @param   rc        Status code to check.
     2753 */
     2754bool drvvdMediaExIoReqIsRedoSetWarning(PVBOXDISK pThis, int rc)
     2755{
     2756    if (rc == VERR_DISK_FULL)
     2757    {
     2758        if (ASMAtomicCmpXchgBool(&pThis->fRedo, true, false))
     2759            drvvdMediaExIoReqWarningDiskFull(pThis->pDrvIns);
     2760        return true;
     2761    }
     2762    if (rc == VERR_FILE_TOO_BIG)
     2763    {
     2764        if (ASMAtomicCmpXchgBool(&pThis->fRedo, true, false))
     2765            drvvdMediaExIoReqWarningFileTooBig(pThis->pDrvIns);
     2766        return true;
     2767    }
     2768    if (rc == VERR_BROKEN_PIPE || rc == VERR_NET_CONNECTION_REFUSED)
     2769    {
     2770        /* iSCSI connection abort (first error) or failure to reestablish
     2771         * connection (second error). Pause VM. On resume we'll retry. */
     2772        if (ASMAtomicCmpXchgBool(&pThis->fRedo, true, false))
     2773            drvvdMediaExIoReqWarningISCSI(pThis->pDrvIns);
     2774        return true;
     2775    }
     2776    if (rc == VERR_VD_DEK_MISSING)
     2777    {
     2778        /* Error message already set. */
     2779        ASMAtomicCmpXchgBool(&pThis->fRedo, true, false);
     2780        return true;
     2781    }
     2782
     2783    return false;
     2784}
     2785
    26922786/**
    26932787 * Syncs the memory buffers between the I/O request allocator and the internal buffer.
     
    27042798    int rc = VINF_SUCCESS;
    27052799
     2800    Assert(pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE);
     2801
    27062802    /* Make sure the buffer is reset. */
    2707     RTSgBufReset(&pIoReq->IoBuf.SgBuf);
     2803    RTSgBufReset(&pIoReq->ReadWrite.IoBuf.SgBuf);
    27082804
    27092805    if (fToIoBuf)
    27102806        rc = pThis->pDrvMediaExPort->pfnIoReqCopyToBuf(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0],
    2711                                                        pIoReq->cbReq - pIoReq->cbReqLeft, &pIoReq->IoBuf.SgBuf,
    2712                                                        RT_MIN(pIoReq->cbIoBuf, pIoReq->cbReqLeft));
     2807                                                       pIoReq->ReadWrite.cbReq - pIoReq->ReadWrite.cbReqLeft,
     2808                                                       &pIoReq->ReadWrite.IoBuf.SgBuf,
     2809                                                       RT_MIN(pIoReq->ReadWrite.cbIoBuf, pIoReq->ReadWrite.cbReqLeft));
    27132810    else
    27142811        rc = pThis->pDrvMediaExPort->pfnIoReqCopyFromBuf(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0],
    2715                                                          pIoReq->cbReq - pIoReq->cbReqLeft, &pIoReq->IoBuf.SgBuf,
    2716                                                          RT_MIN(pIoReq->cbIoBuf, pIoReq->cbReqLeft));
    2717 
    2718     RTSgBufReset(&pIoReq->IoBuf.SgBuf);
     2812                                                         pIoReq->ReadWrite.cbReq - pIoReq->ReadWrite.cbReqLeft,
     2813                                                         &pIoReq->ReadWrite.IoBuf.SgBuf,
     2814                                                         RT_MIN(pIoReq->ReadWrite.cbIoBuf, pIoReq->ReadWrite.cbReqLeft));
     2815
     2816    RTSgBufReset(&pIoReq->ReadWrite.IoBuf.SgBuf);
    27192817    return rc;
    27202818}
     
    28292927DECLINLINE(int) drvvdMediaExIoReqBufAlloc(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, size_t cb)
    28302928{
    2831     int rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReq->IoBuf, cb, &pIoReq->cbIoBuf);
     2929    int rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReq->ReadWrite.IoBuf, cb, &pIoReq->ReadWrite.cbIoBuf);
    28322930    if (rc == VERR_NO_MEMORY)
    28332931    {
    28342932        RTCritSectEnter(&pThis->CritSectIoReqsIoBufWait);
    2835         RTListAppend(&pThis->LstIoReqIoBufWait, &pIoReq->NdLstIoBufWait);
     2933        RTListAppend(&pThis->LstIoReqIoBufWait, &pIoReq->NdLstWait);
    28362934        RTCritSectLeave(&pThis->CritSectIoReqsIoBufWait);
    28372935        ASMAtomicIncU32(&pThis->cIoReqsWaiting);
     
    28572955    Assert(pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE);
    28582956
    2859     while (   pIoReq->cbReqLeft
     2957    while (   pIoReq->ReadWrite.cbReqLeft
    28602958           && rc == VINF_SUCCESS)
    28612959    {
    2862         size_t cbReqIo = RT_MIN(pIoReq->cbReqLeft, pIoReq->cbIoBuf);
     2960        size_t cbReqIo = RT_MIN(pIoReq->ReadWrite.cbReqLeft, pIoReq->ReadWrite.cbIoBuf);
    28632961
    28642962        if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ)
    2865             rc = VDAsyncRead(pThis->pDisk, pIoReq->offStart, cbReqIo, &pIoReq->IoBuf.SgBuf,
     2963            rc = VDAsyncRead(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo, &pIoReq->ReadWrite.IoBuf.SgBuf,
    28662964                             drvvdMediaExIoReqComplete, pThis, pIoReq);
    28672965        else
     
    28712969            if (RT_SUCCESS(rc))
    28722970            {
    2873                 rc = VDAsyncWrite(pThis->pDisk, pIoReq->offStart, cbReqIo, &pIoReq->IoBuf.SgBuf,
     2971                rc = VDAsyncWrite(pThis->pDisk, pIoReq->ReadWrite.offStart, cbReqIo,
     2972                                  &pIoReq->ReadWrite.IoBuf.SgBuf,
    28742973                                  drvvdMediaExIoReqComplete, pThis, pIoReq);
    28752974            }
     
    28842983            else
    28852984                rc = VINF_SUCCESS;
    2886             pIoReq->offStart  += cbReqIo;
    2887             pIoReq->cbReqLeft -= cbReqIo;
     2985            pIoReq->ReadWrite.offStart  += cbReqIo;
     2986            pIoReq->ReadWrite.cbReqLeft -= cbReqIo;
    28882987        }
    28892988    }
     
    28912990    if (rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS)
    28922991    {
    2893         Assert(!pIoReq->cbReqLeft || RT_FAILURE(rc));
     2992        Assert(!pIoReq->ReadWrite.cbReqLeft || RT_FAILURE(rc));
    28942993        rc = drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rc, fUpNotify);
    28952994    }
     
    29113010        || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE)
    29123011    {
    2913         IOBUFMgrFreeBuf(&pIoReq->IoBuf);
     3012        IOBUFMgrFreeBuf(&pIoReq->ReadWrite.IoBuf);
    29143013
    29153014        if (ASMAtomicReadU32(&pThis->cIoReqsWaiting) > 0)
     
    29193018            PPDMMEDIAEXIOREQINT pIoReqCur, pIoReqNext;
    29203019
    2921             RTListForEachSafe(&pThis->LstIoReqIoBufWait, pIoReqCur, pIoReqNext, PDMMEDIAEXIOREQINT, NdLstIoBufWait)
     3020            RTListForEachSafe(&pThis->LstIoReqIoBufWait, pIoReqCur, pIoReqNext, PDMMEDIAEXIOREQINT, NdLstWait)
    29223021            {
    29233022                /* Allocate a suitable I/O buffer for this request. */
    2924                 int rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReqCur->IoBuf, pIoReqCur->cbReq, &pIoReqCur->cbIoBuf);
     3023                int rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReqCur->ReadWrite.IoBuf, pIoReqCur->ReadWrite.cbReq,
     3024                                          &pIoReqCur->ReadWrite.cbIoBuf);
    29253025                if (rc == VINF_SUCCESS)
    29263026                {
    29273027                    ASMAtomicDecU32(&pThis->cIoReqsWaiting);
    2928                     RTListNodeRemove(&pIoReqCur->NdLstIoBufWait);
     3028                    RTListNodeRemove(&pIoReqCur->NdLstWait);
    29293029
    29303030                    bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReqCur->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_ALLOCATED);
     
    29663066        rcReq = drvvdMediaExIoReqBufSync(pThis, pIoReq, false /* fToIoBuf */);
    29673067
    2968     /* Adjust the remaining amount to transfer. */
    2969     size_t cbReqIo = RT_MIN(pIoReq->cbReqLeft, pIoReq->cbIoBuf);
    2970     pIoReq->offStart  += cbReqIo;
    2971     pIoReq->cbReqLeft -= cbReqIo;
    2972 
     3068    /*
     3069     * When the request owner instructs us to handle recoverable errors like full disks
     3070     * do it. Mark the request as suspended, notify the owner and put the request on the
     3071     * redo list.
     3072     */
    29733073    if (   RT_FAILURE(rcReq)
    2974         || !pIoReq->cbReqLeft
    2975         || (   pIoReq->enmType != PDMMEDIAEXIOREQTYPE_READ
    2976             && pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE))
    2977         drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rcReq, true /* fUpNotify */);
     3074        && (pIoReq->fFlags & PDMIMEDIAEX_F_SUSPEND_ON_RECOVERABLE_ERR)
     3075        && drvvdMediaExIoReqIsRedoSetWarning(pThis, rcReq))
     3076    {
     3077        int rc;
     3078        bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_SUSPENDED, VDIOREQSTATE_ACTIVE);
     3079        if (fXchg)
     3080        {
     3081            /* Put on redo list and adjust active request counter. */
     3082            RTCritSectEnter(&pThis->CritSectIoReqRedo);
     3083            RTListAppend(&pThis->LstIoReqRedo, &pIoReq->NdLstWait);
     3084            RTCritSectLeave(&pThis->CritSectIoReqRedo);
     3085            ASMAtomicDecU32(&pThis->cIoReqsActive);
     3086            pThis->pDrvMediaExPort->pfnIoReqStateChanged(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0],
     3087                                                         PDMMEDIAEXIOREQSTATE_SUSPENDED);
     3088        }
     3089        else
     3090        {
     3091            /* Request was canceled inbetween, so don't care and notify the owner about the completed request. */
     3092            Assert(pIoReq->enmState == VDIOREQSTATE_CANCELED);
     3093            drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rcReq, true /* fUpNotify */);
     3094        }
     3095    }
    29783096    else
    2979         drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, true /* fUpNotify */);
     3097    {
     3098        /* Adjust the remaining amount to transfer. */
     3099        size_t cbReqIo = RT_MIN(pIoReq->ReadWrite.cbReqLeft, pIoReq->ReadWrite.cbIoBuf);
     3100        pIoReq->ReadWrite.offStart  += cbReqIo;
     3101        pIoReq->ReadWrite.cbReqLeft -= cbReqIo;
     3102
     3103        if (   RT_FAILURE(rcReq)
     3104            || !pIoReq->ReadWrite.cbReqLeft
     3105            || (   pIoReq->enmType != PDMMEDIAEXIOREQTYPE_READ
     3106                && pIoReq->enmType != PDMMEDIAEXIOREQTYPE_WRITE))
     3107            drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rcReq, true /* fUpNotify */);
     3108        else
     3109            drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, true /* fUpNotify */);
     3110    }
    29803111}
    29813112
     
    30023133{
    30033134    PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMediaEx);
     3135
     3136    AssertReturn(!(fFlags & ~PDMIMEDIAEX_F_VALID), VERR_INVALID_PARAMETER);
     3137
    30043138    PPDMMEDIAEXIOREQINT pIoReq = (PPDMMEDIAEXIOREQINT)RTMemCacheAlloc(pThis->hIoReqCache);
    30053139
     
    30123146    pIoReq->enmState      = VDIOREQSTATE_ALLOCATED;
    30133147    pIoReq->enmType       = PDMMEDIAEXIOREQTYPE_INVALID;
    3014     pIoReq->cbIoBuf       = 0;
    30153148
    30163149    int rc = drvvdMediaExIoReqInsert(pThis, pIoReq);
     
    30453178    /* Free any associated I/O memory. */
    30463179    drvvdMediaExIoReqBufFree(pThis, pIoReq);
     3180
     3181    /* For discard request discard the range array. */
     3182    if (   pIoReq->enmType == PDMMEDIAEXIOREQTYPE_DISCARD
     3183        && pIoReq->Discard.paRanges)
     3184    {
     3185        RTMemFree(pIoReq->Discard.paRanges);
     3186        pIoReq->Discard.paRanges = NULL;
     3187    }
    30473188
    30483189    pIoReq->enmState = VDIOREQSTATE_FREE;
     
    31153256        return VERR_PDM_MEDIAEX_IOREQ_INVALID_STATE;
    31163257
    3117     pIoReq->enmType   = PDMMEDIAEXIOREQTYPE_READ;
    3118     pIoReq->offStart  = off;
    3119     pIoReq->cbReq     = cbRead;
    3120     pIoReq->cbReqLeft = cbRead;
     3258    pIoReq->enmType             = PDMMEDIAEXIOREQTYPE_READ;
     3259    pIoReq->ReadWrite.offStart  = off;
     3260    pIoReq->ReadWrite.cbReq     = cbRead;
     3261    pIoReq->ReadWrite.cbReqLeft = cbRead;
    31213262    /* Allocate a suitable I/O buffer for this request. */
    31223263    int rc = drvvdMediaExIoReqBufAlloc(pThis, pIoReq, cbRead);
     
    31533294        return VERR_PDM_MEDIAEX_IOREQ_INVALID_STATE;
    31543295
    3155     pIoReq->enmType   = PDMMEDIAEXIOREQTYPE_WRITE;
    3156     pIoReq->offStart  = off;
    3157     pIoReq->cbReq     = cbWrite;
    3158     pIoReq->cbReqLeft = cbWrite;
     3296    pIoReq->enmType             = PDMMEDIAEXIOREQTYPE_WRITE;
     3297    pIoReq->ReadWrite.offStart  = off;
     3298    pIoReq->ReadWrite.cbReq     = cbWrite;
     3299    pIoReq->ReadWrite.cbReqLeft = cbWrite;
    31593300    /* Allocate a suitable I/O buffer for this request. */
    31603301    int rc = drvvdMediaExIoReqBufAlloc(pThis, pIoReq, cbWrite);
     
    31923333
    31933334    pIoReq->enmType  = PDMMEDIAEXIOREQTYPE_FLUSH;
    3194     pIoReq->offStart = 0;
    3195     pIoReq->cbReq    = 0;
    31963335    bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_ALLOCATED);
    31973336    if (RT_UNLIKELY(!fXchg))
     
    32303369        return VERR_PDM_MEDIAEX_IOREQ_INVALID_STATE;
    32313370
    3232     pIoReq->enmType  = PDMMEDIAEXIOREQTYPE_DISCARD;
    3233     pIoReq->offStart = 0;
    3234     pIoReq->cbReq    = 0;
     3371    pIoReq->enmType = PDMMEDIAEXIOREQTYPE_DISCARD;
     3372    /* Copy the ranges over because they might not be valid anymore when this method returns. */
     3373    pIoReq->Discard.paRanges = (PRTRANGE)RTMemDup(paRanges, cRanges * sizeof(RTRANGE));
     3374    if (RT_UNLIKELY(!pIoReq->Discard.paRanges))
     3375        return VERR_NO_MEMORY;
    32353376
    32363377    bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_ALLOCATED);
     
    35453686        AssertRC(rc);
    35463687    }
     3688
     3689    if (pThis->pDrvMediaExPort)
     3690    {
     3691        /* Kick of any request we have to redo. */
     3692        PPDMMEDIAEXIOREQINT pIoReq, pIoReqNext;
     3693        RTCritSectEnter(&pThis->CritSectIoReqRedo);
     3694        RTListForEachSafe(&pThis->LstIoReqRedo, pIoReq, pIoReqNext, PDMMEDIAEXIOREQINT, NdLstWait)
     3695        {
     3696            int rc;
     3697            bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_SUSPENDED);
     3698
     3699            RTListNodeRemove(&pIoReq->NdLstWait);
     3700            ASMAtomicIncU32(&pThis->cIoReqsActive);
     3701
     3702            if (fXchg)
     3703            {
     3704                pThis->pDrvMediaExPort->pfnIoReqStateChanged(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0],
     3705                                                             PDMMEDIAEXIOREQSTATE_ACTIVE);
     3706                if (   pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ
     3707                    || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE)
     3708                    rc = drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, false /* fUpNotify */);
     3709                else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_FLUSH)
     3710                {
     3711                    rc = VDAsyncFlush(pThis->pDisk, drvvdMediaExIoReqComplete, pThis, pIoReq);
     3712                    if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     3713                        rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS;
     3714                    else if (rc == VINF_VD_ASYNC_IO_FINISHED)
     3715                        rc = VINF_SUCCESS;
     3716                }
     3717                else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_DISCARD)
     3718                {
     3719                    rc = VDAsyncDiscardRanges(pThis->pDisk, pIoReq->Discard.paRanges, pIoReq->Discard.cRanges,
     3720                                              drvvdMediaExIoReqComplete, pThis, pIoReq);
     3721                    if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     3722                        rc = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS;
     3723                    else if (rc == VINF_VD_ASYNC_IO_FINISHED)
     3724                        rc = VINF_SUCCESS;
     3725                }
     3726
     3727                if (rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS)
     3728                {
     3729                    Assert(   (   pIoReq->enmType != PDMMEDIAEXIOREQTYPE_WRITE
     3730                               && pIoReq->enmType != PDMMEDIAEXIOREQTYPE_READ)
     3731                           || !pIoReq->ReadWrite.cbReqLeft
     3732                           || RT_FAILURE(rc));
     3733                    drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rc, true /* fUpNotify */);
     3734                }
     3735
     3736            }
     3737            else
     3738            {
     3739                /* Request was canceled inbetween, so don't care and notify the owner about the completed request. */
     3740                Assert(pIoReq->enmState == VDIOREQSTATE_CANCELED);
     3741                drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, VERR_PDM_MEDIAEX_IOREQ_CANCELED, true /* fUpNotify */);
     3742            }
     3743        }
     3744        Assert(RTListIsEmpty(&pThis->LstIoReqRedo));
     3745        RTCritSectLeave(&pThis->CritSectIoReqRedo);
     3746    }
    35473747}
    35483748
     
    36543854    if (RTCritSectIsInitialized(&pThis->CritSectIoReqsIoBufWait))
    36553855        RTCritSectDelete(&pThis->CritSectIoReqsIoBufWait);
     3856    if (RTCritSectIsInitialized(&pThis->CritSectIoReqRedo))
     3857        RTCritSectDelete(&pThis->CritSectIoReqRedo);
    36563858    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aIoReqAllocBins); i++)
    36573859    {
     
    37873989            rc = RTCritSectInit(&pThis->CritSectIoReqsIoBufWait);
    37883990
     3991        if (RT_SUCCESS(rc))
     3992            rc = RTCritSectInit(&pThis->CritSectIoReqRedo);
     3993
    37893994        if (RT_FAILURE(rc))
    37903995            return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Creating Mutex failed"));
    37913996
    37923997        RTListInit(&pThis->LstIoReqIoBufWait);
     3998        RTListInit(&pThis->LstIoReqRedo);
    37933999    }
    37944000
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