Changeset 59536 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Feb 1, 2016 9:03:33 AM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 105329
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r59476 r59536 153 153 /** The request was allocated and is in use. */ 154 154 VDIOREQSTATE_ACTIVE, 155 /** The request was suspended and is not actively processed. */ 156 VDIOREQSTATE_SUSPENDED, 155 157 /** The request is in the last step of completion and syncs memory. */ 156 158 VDIOREQSTATE_COMPLETING, … … 171 173 /** List node for the list of allocated requests. */ 172 174 RTLISTNODE NdAllocatedList; 173 /** List for requests waiting for I/O memory . */174 RTLISTNODE NdLst IoBufWait;175 /** List for requests waiting for I/O memory or on the redo list. */ 176 RTLISTNODE NdLstWait; 175 177 /** I/O request type. */ 176 178 PDMMEDIAEXIOREQTYPE enmType; … … 183 185 /** Flags. */ 184 186 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 }; 195 213 /** Allocator specific memory - variable size. */ 196 214 uint8_t abAlloc[1]; … … 357 375 /** Bins for allocated requests. */ 358 376 VDLSTIOREQALLOC aIoReqAllocBins[DRVVD_VDIOREQ_ALLOC_BINS]; 359 /** List of requests for I/O memory to be available - VDIOREQ::NdLst IoBufWait. */377 /** List of requests for I/O memory to be available - VDIOREQ::NdLstWait. */ 360 378 RTLISTANCHOR LstIoReqIoBufWait; 361 379 /** Critical section protecting the list of requests waiting for I/O memory. */ … … 363 381 /** Number of requests waiting for a I/O buffer. */ 364 382 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; 365 391 /** @} */ 366 392 } VBOXDISK; … … 2690 2716 *********************************************************************************************************************************/ 2691 2717 2718 static 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 2727 static 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 2736 static 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 */ 2754 bool 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 2692 2786 /** 2693 2787 * Syncs the memory buffers between the I/O request allocator and the internal buffer. … … 2704 2798 int rc = VINF_SUCCESS; 2705 2799 2800 Assert(pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE); 2801 2706 2802 /* Make sure the buffer is reset. */ 2707 RTSgBufReset(&pIoReq-> IoBuf.SgBuf);2803 RTSgBufReset(&pIoReq->ReadWrite.IoBuf.SgBuf); 2708 2804 2709 2805 if (fToIoBuf) 2710 2806 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)); 2713 2810 else 2714 2811 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); 2719 2817 return rc; 2720 2818 } … … 2829 2927 DECLINLINE(int) drvvdMediaExIoReqBufAlloc(PVBOXDISK pThis, PPDMMEDIAEXIOREQINT pIoReq, size_t cb) 2830 2928 { 2831 int rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReq-> IoBuf, cb, &pIoReq->cbIoBuf);2929 int rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReq->ReadWrite.IoBuf, cb, &pIoReq->ReadWrite.cbIoBuf); 2832 2930 if (rc == VERR_NO_MEMORY) 2833 2931 { 2834 2932 RTCritSectEnter(&pThis->CritSectIoReqsIoBufWait); 2835 RTListAppend(&pThis->LstIoReqIoBufWait, &pIoReq->NdLst IoBufWait);2933 RTListAppend(&pThis->LstIoReqIoBufWait, &pIoReq->NdLstWait); 2836 2934 RTCritSectLeave(&pThis->CritSectIoReqsIoBufWait); 2837 2935 ASMAtomicIncU32(&pThis->cIoReqsWaiting); … … 2857 2955 Assert(pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE); 2858 2956 2859 while ( pIoReq-> cbReqLeft2957 while ( pIoReq->ReadWrite.cbReqLeft 2860 2958 && rc == VINF_SUCCESS) 2861 2959 { 2862 size_t cbReqIo = RT_MIN(pIoReq-> cbReqLeft, pIoReq->cbIoBuf);2960 size_t cbReqIo = RT_MIN(pIoReq->ReadWrite.cbReqLeft, pIoReq->ReadWrite.cbIoBuf); 2863 2961 2864 2962 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, 2866 2964 drvvdMediaExIoReqComplete, pThis, pIoReq); 2867 2965 else … … 2871 2969 if (RT_SUCCESS(rc)) 2872 2970 { 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, 2874 2973 drvvdMediaExIoReqComplete, pThis, pIoReq); 2875 2974 } … … 2884 2983 else 2885 2984 rc = VINF_SUCCESS; 2886 pIoReq-> offStart += cbReqIo;2887 pIoReq-> cbReqLeft -= cbReqIo;2985 pIoReq->ReadWrite.offStart += cbReqIo; 2986 pIoReq->ReadWrite.cbReqLeft -= cbReqIo; 2888 2987 } 2889 2988 } … … 2891 2990 if (rc != VINF_PDM_MEDIAEX_IOREQ_IN_PROGRESS) 2892 2991 { 2893 Assert(!pIoReq-> cbReqLeft || RT_FAILURE(rc));2992 Assert(!pIoReq->ReadWrite.cbReqLeft || RT_FAILURE(rc)); 2894 2993 rc = drvvdMediaExIoReqCompleteWorker(pThis, pIoReq, rc, fUpNotify); 2895 2994 } … … 2911 3010 || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE) 2912 3011 { 2913 IOBUFMgrFreeBuf(&pIoReq-> IoBuf);3012 IOBUFMgrFreeBuf(&pIoReq->ReadWrite.IoBuf); 2914 3013 2915 3014 if (ASMAtomicReadU32(&pThis->cIoReqsWaiting) > 0) … … 2919 3018 PPDMMEDIAEXIOREQINT pIoReqCur, pIoReqNext; 2920 3019 2921 RTListForEachSafe(&pThis->LstIoReqIoBufWait, pIoReqCur, pIoReqNext, PDMMEDIAEXIOREQINT, NdLst IoBufWait)3020 RTListForEachSafe(&pThis->LstIoReqIoBufWait, pIoReqCur, pIoReqNext, PDMMEDIAEXIOREQINT, NdLstWait) 2922 3021 { 2923 3022 /* 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); 2925 3025 if (rc == VINF_SUCCESS) 2926 3026 { 2927 3027 ASMAtomicDecU32(&pThis->cIoReqsWaiting); 2928 RTListNodeRemove(&pIoReqCur->NdLst IoBufWait);3028 RTListNodeRemove(&pIoReqCur->NdLstWait); 2929 3029 2930 3030 bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReqCur->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_ALLOCATED); … … 2966 3066 rcReq = drvvdMediaExIoReqBufSync(pThis, pIoReq, false /* fToIoBuf */); 2967 3067 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 */ 2973 3073 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 } 2978 3096 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 } 2980 3111 } 2981 3112 … … 3002 3133 { 3003 3134 PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMediaEx); 3135 3136 AssertReturn(!(fFlags & ~PDMIMEDIAEX_F_VALID), VERR_INVALID_PARAMETER); 3137 3004 3138 PPDMMEDIAEXIOREQINT pIoReq = (PPDMMEDIAEXIOREQINT)RTMemCacheAlloc(pThis->hIoReqCache); 3005 3139 … … 3012 3146 pIoReq->enmState = VDIOREQSTATE_ALLOCATED; 3013 3147 pIoReq->enmType = PDMMEDIAEXIOREQTYPE_INVALID; 3014 pIoReq->cbIoBuf = 0;3015 3148 3016 3149 int rc = drvvdMediaExIoReqInsert(pThis, pIoReq); … … 3045 3178 /* Free any associated I/O memory. */ 3046 3179 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 } 3047 3188 3048 3189 pIoReq->enmState = VDIOREQSTATE_FREE; … … 3115 3256 return VERR_PDM_MEDIAEX_IOREQ_INVALID_STATE; 3116 3257 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; 3121 3262 /* Allocate a suitable I/O buffer for this request. */ 3122 3263 int rc = drvvdMediaExIoReqBufAlloc(pThis, pIoReq, cbRead); … … 3153 3294 return VERR_PDM_MEDIAEX_IOREQ_INVALID_STATE; 3154 3295 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; 3159 3300 /* Allocate a suitable I/O buffer for this request. */ 3160 3301 int rc = drvvdMediaExIoReqBufAlloc(pThis, pIoReq, cbWrite); … … 3192 3333 3193 3334 pIoReq->enmType = PDMMEDIAEXIOREQTYPE_FLUSH; 3194 pIoReq->offStart = 0;3195 pIoReq->cbReq = 0;3196 3335 bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_ALLOCATED); 3197 3336 if (RT_UNLIKELY(!fXchg)) … … 3230 3369 return VERR_PDM_MEDIAEX_IOREQ_INVALID_STATE; 3231 3370 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; 3235 3376 3236 3377 bool fXchg = ASMAtomicCmpXchgU32((volatile uint32_t *)&pIoReq->enmState, VDIOREQSTATE_ACTIVE, VDIOREQSTATE_ALLOCATED); … … 3545 3686 AssertRC(rc); 3546 3687 } 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 } 3547 3747 } 3548 3748 … … 3654 3854 if (RTCritSectIsInitialized(&pThis->CritSectIoReqsIoBufWait)) 3655 3855 RTCritSectDelete(&pThis->CritSectIoReqsIoBufWait); 3856 if (RTCritSectIsInitialized(&pThis->CritSectIoReqRedo)) 3857 RTCritSectDelete(&pThis->CritSectIoReqRedo); 3656 3858 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aIoReqAllocBins); i++) 3657 3859 { … … 3787 3989 rc = RTCritSectInit(&pThis->CritSectIoReqsIoBufWait); 3788 3990 3991 if (RT_SUCCESS(rc)) 3992 rc = RTCritSectInit(&pThis->CritSectIoReqRedo); 3993 3789 3994 if (RT_FAILURE(rc)) 3790 3995 return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Creating Mutex failed")); 3791 3996 3792 3997 RTListInit(&pThis->LstIoReqIoBufWait); 3998 RTListInit(&pThis->LstIoReqRedo); 3793 3999 } 3794 4000
Note:
See TracChangeset
for help on using the changeset viewer.