Changeset 63919 in vbox
- Timestamp:
- Sep 21, 2016 10:35:33 AM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 110801
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r63917 r63919 1821 1821 * 1822 1822 * @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 */ 1826 static int drvvdKeyCheckPrereqs(PVBOXDISK pThis, bool fSetError) 1826 1827 { 1827 1828 if ( pThis->pCfgCrypto … … 1831 1832 pThis->pIfSecKeyHlp->pfnKeyMissingNotify(pThis->pIfSecKeyHlp); 1832 1833 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 } 1836 1840 return VERR_VD_DEK_MISSING; 1837 1841 } … … 1863 1867 } 1864 1868 1865 rc = drvvdKeyCheckPrereqs(pThis );1869 rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */); 1866 1870 if (RT_FAILURE(rc)) 1867 1871 return rc; … … 1994 1998 PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_STORAGE); 1995 1999 1996 int rc = drvvdKeyCheckPrereqs(pThis );2000 int rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */); 1997 2001 if (RT_FAILURE(rc)) 1998 2002 return rc; … … 2531 2535 } 2532 2536 2533 rc = drvvdKeyCheckPrereqs(pThis );2537 rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */); 2534 2538 if (RT_FAILURE(rc)) 2535 2539 return rc; … … 2573 2577 } 2574 2578 2575 rc = drvvdKeyCheckPrereqs(pThis );2579 rc = drvvdKeyCheckPrereqs(pThis, true /* fSetError */); 2576 2580 if (RT_FAILURE(rc)) 2577 2581 return rc; … … 2762 2766 } 2763 2767 2768 static 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 2764 2776 /** 2765 2777 * Checks whether a given status code indicates a recoverable error … … 2796 2808 { 2797 2809 /* Error message already set. */ 2798 ASMAtomicCmpXchgBool(&pThis->fRedo, true, false); 2810 if (ASMAtomicCmpXchgBool(&pThis->fRedo, true, false)) 2811 drvvdMediaExIoReqWarningDekMissing(pThis->pDrvIns); 2799 2812 return true; 2800 2813 } … … 2901 2914 2902 2915 /** 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. 2904 2918 * 2905 2919 * @returns VBox status code. … … 2909 2923 * @param fUpNotify Flag whether to notify the driver/device above us about the completion. 2910 2924 */ 2911 static int drvvdMediaExIoReqCompleteWorker(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, int rcReq, bool fUpNotify)2925 static void drvvdMediaExIoReqRetire(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, int rcReq, bool fUpNotify) 2912 2926 { 2913 2927 int rc; … … 2995 3009 AssertRC(rc); 2996 3010 } 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 */ 3022 static 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 } 2997 3075 2998 3076 return rcReq; … … 3039 3117 3040 3118 Assert(pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE); 3119 3120 rc = drvvdKeyCheckPrereqs(pThis, false /* fSetError */); 3041 3121 3042 3122 while ( pIoReq->ReadWrite.cbReqLeft … … 3190 3270 PPDMMEDIAEXIOREQINT pIoReq = (PPDMMEDIAEXIOREQINT)pvUser2; 3191 3271 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 */); 3242 3273 } 3243 3274 … … 4045 4076 if ( pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ 4046 4077 || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE) 4047 rc = drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, false /* fUpNotify */);4078 rc = drvvdMediaExIoReqReadWriteProcess(pThis, pIoReq, true /* fUpNotify */); 4048 4079 else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_FLUSH) 4049 4080 { … … 4066 4097 AssertMsgFailed(("Invalid request type %u\n", pIoReq->enmType)); 4067 4098 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)) 4069 4103 { 4070 4104 Assert( ( pIoReq->enmType != PDMMEDIAEXIOREQTYPE_WRITE
Note:
See TracChangeset
for help on using the changeset viewer.