Changeset 59539 in vbox for trunk/src/VBox/Devices/Storage
- Timestamp:
- Feb 1, 2016 11:52:58 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DrvVD.cpp
r59538 r59539 26 26 #include <VBox/vmm/pdmasynccompletion.h> 27 27 #include <VBox/vmm/pdmblkcache.h> 28 #include <VBox/vmm/ssm.h> 28 29 #include <iprt/asm.h> 29 30 #include <iprt/alloc.h> … … 99 100 #define PDMIMEDIAASYNC_2_VBOXDISK(pInterface) \ 100 101 ( (PVBOXDISK)((uintptr_t)pInterface - RT_OFFSETOF(VBOXDISK, IMediaAsync)) ) 102 103 /** Saved state version of an I/O request .*/ 104 #define DRVVD_IOREQ_SAVED_STATE_VERSION UINT32_C(1) 101 105 102 106 /** Forward declaration for the dis kcontainer. */ … … 3239 3243 /* 3240 3244 * We might have to try canceling the request multiple times if it transitioned from 3241 * ALLOCATED to ACTIVE between reading the state and trying to change it.3245 * ALLOCATED to ACTIVE or to SUSPENDED between reading the state and trying to change it. 3242 3246 */ 3243 3247 while ( ( enmStateOld == VDIOREQSTATE_ALLOCATED 3244 || enmStateOld == VDIOREQSTATE_ACTIVE) 3248 || enmStateOld == VDIOREQSTATE_ACTIVE 3249 || enmStateOld == VDIOREQSTATE_SUSPENDED) 3245 3250 && !fXchg) 3246 3251 { … … 3490 3495 3491 3496 return VINF_SUCCESS; 3497 } 3498 3499 /** 3500 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqSuspendedSave} 3501 */ 3502 static DECLCALLBACK(int) drvvdIoReqSuspendedSave(PPDMIMEDIAEX pInterface, PSSMHANDLE pSSM, PDMMEDIAEXIOREQ hIoReq) 3503 { 3504 PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMediaEx); 3505 PPDMMEDIAEXIOREQINT pIoReq = hIoReq; 3506 3507 AssertReturn(!drvvdMediaExIoReqIsVmRunning(pThis), VERR_INVALID_STATE); 3508 AssertPtrReturn(pIoReq, VERR_INVALID_HANDLE); 3509 AssertReturn(pIoReq->enmState == VDIOREQSTATE_SUSPENDED, VERR_INVALID_STATE); 3510 3511 SSMR3PutU32(pSSM, DRVVD_IOREQ_SAVED_STATE_VERSION); 3512 SSMR3PutU32(pSSM, (uint32_t)pIoReq->enmType); 3513 SSMR3PutU32(pSSM, pIoReq->uIoReqId); 3514 SSMR3PutU32(pSSM, pIoReq->fFlags); 3515 if ( pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ 3516 || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE) 3517 { 3518 SSMR3PutU64(pSSM, pIoReq->ReadWrite.offStart); 3519 SSMR3PutU64(pSSM, pIoReq->ReadWrite.cbReq); 3520 SSMR3PutU64(pSSM, pIoReq->ReadWrite.cbReqLeft); 3521 } 3522 else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_DISCARD) 3523 { 3524 SSMR3PutU32(pSSM, pIoReq->Discard.cRanges); 3525 for (unsigned i = 0; i < pIoReq->Discard.cRanges; i++) 3526 { 3527 SSMR3PutU64(pSSM, pIoReq->Discard.paRanges[i].offStart); 3528 SSMR3PutU64(pSSM, pIoReq->Discard.paRanges[i].cbRange); 3529 } 3530 } 3531 3532 return SSMR3PutU32(pSSM, UINT32_MAX); /* sanity/terminator */ 3533 } 3534 3535 /** 3536 * @interface_method_impl{PDMIMEDIAEX,pfnIoReqSuspendedLoad} 3537 */ 3538 static DECLCALLBACK(int) drvvdIoReqSuspendedLoad(PPDMIMEDIAEX pInterface, PSSMHANDLE pSSM, PDMMEDIAEXIOREQ hIoReq) 3539 { 3540 PVBOXDISK pThis = RT_FROM_MEMBER(pInterface, VBOXDISK, IMediaEx); 3541 PPDMMEDIAEXIOREQINT pIoReq = hIoReq; 3542 3543 AssertReturn(!drvvdMediaExIoReqIsVmRunning(pThis), VERR_INVALID_STATE); 3544 AssertPtrReturn(pIoReq, VERR_INVALID_HANDLE); 3545 AssertReturn(pIoReq->enmState == VDIOREQSTATE_ALLOCATED, VERR_INVALID_STATE); 3546 3547 uint32_t u32; 3548 uint64_t u64; 3549 int rc = VINF_SUCCESS; 3550 bool fPlaceOnRedoList = true; 3551 3552 SSMR3GetU32(pSSM, &u32); 3553 if (u32 <= DRVVD_IOREQ_SAVED_STATE_VERSION) 3554 { 3555 SSMR3GetU32(pSSM, &u32); 3556 AssertReturn( u32 == PDMMEDIAEXIOREQTYPE_WRITE 3557 || u32 == PDMMEDIAEXIOREQTYPE_READ 3558 || u32 == PDMMEDIAEXIOREQTYPE_DISCARD 3559 || u32 == PDMMEDIAEXIOREQTYPE_FLUSH, 3560 VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 3561 pIoReq->enmType = (PDMMEDIAEXIOREQTYPE)u32; 3562 3563 SSMR3GetU32(pSSM, &u32); 3564 AssertReturn(u32 == pIoReq->uIoReqId, VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 3565 3566 SSMR3GetU32(pSSM, &u32); 3567 AssertReturn(u32 == pIoReq->fFlags, VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 3568 3569 if ( pIoReq->enmType == PDMMEDIAEXIOREQTYPE_READ 3570 || pIoReq->enmType == PDMMEDIAEXIOREQTYPE_WRITE) 3571 { 3572 SSMR3GetU64(pSSM, &pIoReq->ReadWrite.offStart); 3573 SSMR3GetU64(pSSM, &u64); 3574 pIoReq->ReadWrite.cbReq = (size_t)u64; 3575 SSMR3GetU64(pSSM, &u64); 3576 pIoReq->ReadWrite.cbReqLeft = (size_t)u64; 3577 3578 /* 3579 * Try to allocate enough I/O buffer, if this fails for some reason put it onto the 3580 * waitign list instead of the redo list. 3581 */ 3582 pIoReq->ReadWrite.cbIoBuf = 0; 3583 rc = IOBUFMgrAllocBuf(pThis->hIoBufMgr, &pIoReq->ReadWrite.IoBuf, pIoReq->ReadWrite.cbReqLeft, 3584 &pIoReq->ReadWrite.cbIoBuf); 3585 if (rc == VERR_NO_MEMORY) 3586 { 3587 pIoReq->enmState = VDIOREQSTATE_ALLOCATED; 3588 ASMAtomicIncU32(&pThis->cIoReqsWaiting); 3589 RTListAppend(&pThis->LstIoReqIoBufWait, &pIoReq->NdLstWait); 3590 fPlaceOnRedoList = false; 3591 rc = VINF_SUCCESS; 3592 } 3593 } 3594 else if (pIoReq->enmType == PDMMEDIAEXIOREQTYPE_DISCARD) 3595 { 3596 rc = SSMR3GetU32(pSSM, &pIoReq->Discard.cRanges); 3597 if (RT_SUCCESS(rc)) 3598 { 3599 pIoReq->Discard.paRanges = (PRTRANGE)RTMemAllocZ(pIoReq->Discard.cRanges * sizeof(RTRANGE)); 3600 if (RT_LIKELY(pIoReq->Discard.paRanges)) 3601 { 3602 for (unsigned i = 0; i < pIoReq->Discard.cRanges; i++) 3603 { 3604 SSMR3GetU64(pSSM, &pIoReq->Discard.paRanges[i].offStart); 3605 SSMR3GetU64(pSSM, &u64); 3606 pIoReq->Discard.paRanges[i].cbRange = (size_t)u64; 3607 } 3608 } 3609 else 3610 rc = VERR_NO_MEMORY; 3611 } 3612 } 3613 3614 if (RT_SUCCESS(rc)) 3615 rc = SSMR3GetU32(pSSM, &u32); /* sanity/terminator */ 3616 if (RT_SUCCESS(rc)) 3617 AssertReturn(u32 == UINT32_MAX, VERR_SSM_DATA_UNIT_FORMAT_CHANGED); 3618 if ( RT_SUCCESS(rc) 3619 && fPlaceOnRedoList) 3620 { 3621 /* Mark as suspended */ 3622 pIoReq->enmState = VDIOREQSTATE_SUSPENDED; 3623 3624 /* Link into suspended list so it gets kicked off again when we resume. */ 3625 RTCritSectEnter(&pThis->CritSectIoReqRedo); 3626 RTListAppend(&pThis->LstIoReqRedo, &pIoReq->NdLstWait); 3627 RTCritSectLeave(&pThis->CritSectIoReqRedo); 3628 } 3629 } 3630 3631 return rc; 3492 3632 } 3493 3633 … … 4038 4178 pThis->IMediaEx.pfnIoReqQuerySuspendedStart = drvvdIoReqQuerySuspendedStart; 4039 4179 pThis->IMediaEx.pfnIoReqQuerySuspendedNext = drvvdIoReqQuerySuspendedNext; 4180 pThis->IMediaEx.pfnIoReqSuspendedSave = drvvdIoReqSuspendedSave; 4181 pThis->IMediaEx.pfnIoReqSuspendedLoad = drvvdIoReqSuspendedLoad; 4040 4182 4041 4183 /* Initialize supported VD interfaces. */
Note:
See TracChangeset
for help on using the changeset viewer.