VirtualBox

Changeset 63919 in vbox


Ignore:
Timestamp:
Sep 21, 2016 10:35:33 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
110801
Message:

DrvVD: Fix handling encrypted disks when PDMIMEDIAEX is used (only used by the NVMe controller so far)

File:
1 edited

Legend:

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

    r63917 r63919  
    18211821 *
    18221822 * @returns VBox status code.
    1823  * @param   pThis    The VD driver instance data.
    1824  */
    1825 static int drvvdKeyCheckPrereqs(PVBOXDISK pThis)
     1823 * @param   pThis     The VD driver instance data.
     1824 * @param   fSetError Flag whether to set a runtime error.
     1825 */
     1826static int drvvdKeyCheckPrereqs(PVBOXDISK pThis, bool fSetError)
    18261827{
    18271828    if (   pThis->pCfgCrypto
     
    18311832        pThis->pIfSecKeyHlp->pfnKeyMissingNotify(pThis->pIfSecKeyHlp);
    18321833
    1833         int rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
    1834                                             N_("VD: The DEK for this disk is missing"));
    1835         AssertRC(rc);
     1834        if (fSetError)
     1835        {
     1836            int rc = PDMDrvHlpVMSetRuntimeError(pThis->pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
     1837                                                N_("VD: The DEK for this disk is missing"));
     1838            AssertRC(rc);
     1839        }
    18361840        return VERR_VD_DEK_MISSING;
    18371841    }
     
    18631867    }
    18641868
    1865     rc = drvvdKeyCheckPrereqs(pThis);
     1869    rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */);
    18661870    if (RT_FAILURE(rc))
    18671871        return rc;
     
    19941998    PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_STORAGE);
    19951999
    1996     int rc = drvvdKeyCheckPrereqs(pThis);
     2000    int rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */);
    19972001    if (RT_FAILURE(rc))
    19982002        return rc;
     
    25312535    }
    25322536
    2533     rc = drvvdKeyCheckPrereqs(pThis);
     2537    rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */);
    25342538    if (RT_FAILURE(rc))
    25352539        return rc;
     
    25732577    }
    25742578
    2575     rc = drvvdKeyCheckPrereqs(pThis);
     2579    rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */);
    25762580    if (RT_FAILURE(rc))
    25772581        return rc;
     
    27622766}
    27632767
     2768static void drvvdMediaExIoReqWarningDekMissing(PPDMDRVINS pDrvIns)
     2769{
     2770    LogRel(("VD#%u: DEK is missing\n", pDrvIns->iInstance));
     2771    int rc = PDMDrvHlpVMSetRuntimeError(pDrvIns, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "DrvVD_DEKMISSING",
     2772                                        N_("VD: The DEK for this disk is missing"));
     2773    AssertRC(rc);
     2774}
     2775
    27642776/**
    27652777 * Checks whether a given status code indicates a recoverable error
     
    27962808    {
    27972809        /* Error message already set. */
    2798         ASMAtomicCmpXchgBool(&pThis->fRedo, true, false);
     2810        if (ASMAtomicCmpXchgBool(&pThis->fRedo, true, false))
     2811            drvvdMediaExIoReqWarningDekMissing(pThis->pDrvIns);
    27992812        return true;
    28002813    }
     
    29012914
    29022915/**
    2903  * I/O request completion worker.
     2916 * Retires a given I/O request marking it as complete and notiyfing the
     2917 * device/driver above about the completion if requested.
    29042918 *
    29052919 * @returns VBox status code.
     
    29092923 * @param   fUpNotify Flag whether to notify the driver/device above us about the completion.
    29102924 */
    2911 static int drvvdMediaExIoReqCompleteWorker(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, int rcReq, bool fUpNotify)
     2925static void drvvdMediaExIoReqRetire(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, int rcReq, bool fUpNotify)
    29122926{
    29132927    int rc;
     
    29953009        AssertRC(rc);
    29963010    }
     3011}
     3012
     3013/**
     3014 * I/O request completion worker.
     3015 *
     3016 * @returns VBox status code.
     3017 * @param   pThis     VBox disk container instance data.
     3018 * @param   pIoReq    I/O request to complete.
     3019 * @param   rcReq     The status code the request completed with.
     3020 * @param   fUpNotify Flag whether to notify the driver/device above us about the completion.
     3021 */
     3022static int drvvdMediaExIoReqCompleteWorker(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, int rcReq, bool fUpNotify)
     3023{
     3024    /*
     3025     * For a read we need to sync the memory before continuing to process
     3026     * the request further.
     3027     */
     3028    if (   RT_SUCCESS(rcReq)
     3029        && pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ)
     3030        rcReq = drvvdMediaExIoReqBufSync(pThis, pIoReq, false /* fToIoBuf */);
     3031
     3032    /*
     3033     * When the request owner instructs us to handle recoverable errors like full disks
     3034     * do it. Mark the request as suspended, notify the owner and put the request on the
     3035     * redo list.
     3036     */
     3037    if (   RT_FAILURE(rcReq)
     3038        && (pIoReq->fFlags & PDMIMEDIAEX_F_SUSPEND_ON_RECOVERABLE_ERR)
     3039        && drvvdMediaExIoReqIsRedoSetWarning(pThis, rcReq))
     3040    {
     3041        bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_SUSPENDED, VDIOREQSTATE_ACTIVE);
     3042        if (fXchg)
     3043        {
     3044            /* Put on redo list and adjust active request counter. */
     3045            RTCritSectEnter(&pThis->CritSectIoReqRedo);
     3046            RTListAppend(&pThis->LstIoReqRedo, &pIoReq->NdLstWait);
     3047            RTCritSectLeave(&pThis->CritSectIoReqRedo);
     3048            ASMAtomicDecU32(&pThis->cIoReqsActive);
     3049            pThis->pDrvMediaExPort->pfnIoReqStateChanged(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0],
     3050                                                         PDMMEDIAEXIOREQSTATE_SUSPENDED);
     3051            rcReq = VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS;
     3052        }
     3053        else
     3054        {
     3055            /* Request was canceled inbetween, so don't care and notify the owner about the completed request. */
     3056            Assert(pIoReq->enmState == VDIOREQSTATE_CANCELED);
     3057            drvvdMediaExIoReqRetire(pThis, pIoReq, rcReq, fUpNotify);
     3058        }
     3059    }
     3060    else
     3061    {
     3062        /* Adjust the remaining amount to transfer. */
     3063        size_t cbReqIo = RT_MIN(pIoReq->ReadWrite.cbReqLeft, pIoReq->ReadWrite.cbIoBuf);
     3064        pIoReq->ReadWrite.offStart  += cbReqIo;
     3065        pIoReq->ReadWrite.cbReqLeft -= cbReqIo;
     3066
     3067        if (   RT_FAILURE(rcReq)
     3068            || !pIoReq->ReadWrite.cbReqLeft
     3069            || (   pIoReq->enmType != PDMMEDIAEXIOREQTYPE_READ
     3070                && pIoReq->enmType != PDMMEDIAEXIOREQTYPE_WRITE))
     3071            drvvdMediaExIoReqRetire(pThis, pIoReq, rcReq, fUpNotify);
     3072        else
     3073            drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, fUpNotify);
     3074    }
    29973075
    29983076    return rcReq;
     
    30393117
    30403118    Assert(pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE);
     3119
     3120    rc = drvvdKeyCheckPrereqs(pThis, false /* fSetError */);
    30413121
    30423122    while (   pIoReq->ReadWrite.cbReqLeft
     
    31903270    PPDMMEDIAEXIOREQINT pIoReq = (PPDMMEDIAEXIOREQINT)pvUser2;
    31913271
    3192     /*
    3193      * For a read we need to sync the memory before continuing to process
    3194      * the request further.
    3195      */
    3196     if (   RT_SUCCESS(rcReq)
    3197         && pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ)
    3198         rcReq = drvvdMediaExIoReqBufSync(pThis, pIoReq, false /* fToIoBuf */);
    3199 
    3200     /*
    3201      * When the request owner instructs us to handle recoverable errors like full disks
    3202      * do it. Mark the request as suspended, notify the owner and put the request on the
    3203      * redo list.
    3204      */
    3205     if (   RT_FAILURE(rcReq)
    3206         && (pIoReq->fFlags & PDMIMEDIAEX_F_SUSPEND_ON_RECOVERABLE_ERR)
    3207         && drvvdMediaExIoReqIsRedoSetWarning(pThis, rcReq))
    3208     {
    3209         bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_SUSPENDED, VDIOREQSTATE_ACTIVE);
    3210         if (fXchg)
    3211         {
    3212             /* Put on redo list and adjust active request counter. */
    3213             RTCritSectEnter(&pThis->CritSectIoReqRedo);
    3214             RTListAppend(&pThis->LstIoReqRedo, &pIoReq->NdLstWait);
    3215             RTCritSectLeave(&pThis->CritSectIoReqRedo);
    3216             ASMAtomicDecU32(&pThis->cIoReqsActive);
    3217             pThis->pDrvMediaExPort->pfnIoReqStateChanged(pThis->pDrvMediaExPort, pIoReq, &pIoReq->abAlloc[0],
    3218                                                          PDMMEDIAEXIOREQSTATE_SUSPENDED);
    3219         }
    3220         else
    3221         {
    3222             /* Request was canceled inbetween, so don't care and notify the owner about the completed request. */
    3223             Assert(pIoReq->enmState == VDIOREQSTATE_CANCELED);
    3224             drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rcReq, true /* fUpNotify */);
    3225         }
    3226     }
    3227     else
    3228     {
    3229         /* Adjust the remaining amount to transfer. */
    3230         size_t cbReqIo = RT_MIN(pIoReq->ReadWrite.cbReqLeft, pIoReq->ReadWrite.cbIoBuf);
    3231         pIoReq->ReadWrite.offStart  += cbReqIo;
    3232         pIoReq->ReadWrite.cbReqLeft -= cbReqIo;
    3233 
    3234         if (   RT_FAILURE(rcReq)
    3235             || !pIoReq->ReadWrite.cbReqLeft
    3236             || (   pIoReq->enmType != PDMMEDIAEXIOREQTYPE_READ
    3237                 && pIoReq->enmType != PDMMEDIAEXIOREQTYPE_WRITE))
    3238             drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rcReq, true /* fUpNotify */);
    3239         else
    3240             drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, true /* fUpNotify */);
    3241     }
     3272    drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rcReq, true /* fUpNotify */);
    32423273}
    32433274
     
    40454076                if (   pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ
    40464077                    || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE)
    4047                     rc = drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, false /* fUpNotify */);
     4078                    rc = drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, true /* fUpNotify */);
    40484079                else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_FLUSH)
    40494080                {
     
    40664097                    AssertMsgFailed(("Invalid request type %u\n", pIoReq->enmType));
    40674098
    4068                 if (rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS)
     4099                /* The read write process will call the completion callback on its own. */
     4100                if (   rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS
     4101                    && (   pIoReq->enmType == PDMMEDIAEXIOREQTYPE_DISCARD
     4102                        || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_FLUSH))
    40694103                {
    40704104                    Assert(   (   pIoReq->enmType != PDMMEDIAEXIOREQTYPE_WRITE
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