VirtualBox

Changeset 27920 in vbox


Ignore:
Timestamp:
Mar 31, 2010 7:02:48 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
59612
Message:

AsyncCompletion: Return error code for completed requests

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pdmasynccompletion.h

    r27738 r27920  
    6464 * @param   pDevIns     The device instance.
    6565 * @param   pvUser      User argument.
    66  */
    67 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDEV(PPDMDEVINS pDevIns, void *pvUser);
     66 * @param   rc          The status code of the completed request.
     67 */
     68typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDEV(PPDMDEVINS pDevIns, void *pvUser, int rc);
    6869/** Pointer to a FNPDMASYNCCOMPLETEDEV(). */
    6970typedef FNPDMASYNCCOMPLETEDEV *PFNPDMASYNCCOMPLETEDEV;
     
    7677 * @param   pvTemplateUser User argument given when creating the template.
    7778 * @param   pvUser         User argument given during request initiation.
    78  */
    79 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDRV(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser);
     79 * @param   rc          The status code of the completed request.
     80 */
     81typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDRV(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser, int rc);
    8082/** Pointer to a FNPDMASYNCCOMPLETEDRV(). */
    8183typedef FNPDMASYNCCOMPLETEDRV *PFNPDMASYNCCOMPLETEDRV;
     
    8789 * @param   pUsbIns     The USB device instance.
    8890 * @param   pvUser      User argument.
    89  */
    90 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEUSB(PPDMUSBINS pUsbIns, void *pvUser);
     91 * @param   rc          The status code of the completed request.
     92 */
     93typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEUSB(PPDMUSBINS pUsbIns, void *pvUser, int rc);
    9194/** Pointer to a FNPDMASYNCCOMPLETEUSB(). */
    9295typedef FNPDMASYNCCOMPLETEUSB *PFNPDMASYNCCOMPLETEUSB;
     
    99102 * @param   pvUser      User argument for the task.
    100103 * @param   pvUser2     User argument for the template.
    101  */
    102 typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEINT(PVM pVM, void *pvUser, void *pvUser2);
     104 * @param   rc          The status code of the completed request.
     105 */
     106typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEINT(PVM pVM, void *pvUser, void *pvUser2, int rc);
    103107/** Pointer to a FNPDMASYNCCOMPLETEINT(). */
    104108typedef FNPDMASYNCCOMPLETEINT *PFNPDMASYNCCOMPLETEINT;
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r27810 r27920  
    285285#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
    286286
    287 static DECLCALLBACK(void) drvvdAsyncTaskCompleted(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser)
     287static DECLCALLBACK(void) drvvdAsyncTaskCompleted(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser, int rcReq)
    288288{
    289289    PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
  • trunk/src/VBox/VMM/PDMAsyncCompletion.cpp

    r27883 r27920  
    545545}
    546546
    547 void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, bool fCallCompletionHandler)
     547void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, int rc, bool fCallCompletionHandler)
    548548{
    549549    LogFlow(("%s: pTask=%#p fCallCompletionHandler=%RTbool\n", __FUNCTION__, pTask, fCallCompletionHandler));
     
    557557            case PDMASYNCCOMPLETIONTEMPLATETYPE_DEV:
    558558            {
    559                 pTemplate->u.Dev.pfnCompleted(pTemplate->u.Dev.pDevIns, pTask->pvUser);
     559                pTemplate->u.Dev.pfnCompleted(pTemplate->u.Dev.pDevIns, pTask->pvUser, rc);
    560560                break;
    561561            }
    562562            case PDMASYNCCOMPLETIONTEMPLATETYPE_DRV:
    563563            {
    564                 pTemplate->u.Drv.pfnCompleted(pTemplate->u.Drv.pDrvIns, pTemplate->u.Drv.pvTemplateUser, pTask->pvUser);
     564                pTemplate->u.Drv.pfnCompleted(pTemplate->u.Drv.pDrvIns, pTemplate->u.Drv.pvTemplateUser, pTask->pvUser, rc);
    565565                break;
    566566            }
    567567            case PDMASYNCCOMPLETIONTEMPLATETYPE_USB:
    568568            {
    569                 pTemplate->u.Usb.pfnCompleted(pTemplate->u.Usb.pUsbIns, pTask->pvUser);
     569                pTemplate->u.Usb.pfnCompleted(pTemplate->u.Usb.pUsbIns, pTask->pvUser, rc);
    570570                break;
    571571            }
    572572            case PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL:
    573573            {
    574                 pTemplate->u.Int.pfnCompleted(pTemplate->pVM, pTask->pvUser, pTemplate->u.Int.pvUser);
     574                pTemplate->u.Int.pfnCompleted(pTemplate->pVM, pTask->pvUser, pTemplate->u.Int.pvUser, rc);
    575575                break;
    576576            }
  • trunk/src/VBox/VMM/PDMAsyncCompletionFile.cpp

    r27738 r27920  
    315315}
    316316
    317 void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser)
     317void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc)
    318318{
    319319    PPDMASYNCCOMPLETIONTASKFILE pTaskFile = (PPDMASYNCCOMPLETIONTASKFILE)pvUser;
     
    321321    if (pTask->enmTransferType == PDMACTASKFILETRANSFER_FLUSH)
    322322    {
    323         pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, true);
     323        pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, rc, true);
    324324    }
    325325    else
     
    328328        uint32_t uOld = ASMAtomicSubS32(&pTaskFile->cbTransferLeft, (int32_t)pTask->DataSeg.cbSeg);
    329329
     330        /* The first error will be returned. */
     331        if (RT_FAILURE(rc))
     332            ASMAtomicCmpXchgS32(&pTaskFile->rc, rc, VINF_SUCCESS);
     333
    330334        if (!(uOld - pTask->DataSeg.cbSeg)
    331335            && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true))
    332             pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, true);
     336            pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true);
    333337    }
    334338}
     
    350354    ASMAtomicWriteS32(&pTaskFile->cbTransferLeft, (int32_t)cbTransfer);
    351355    ASMAtomicWriteBool(&pTaskFile->fCompleted, false);
     356    ASMAtomicWriteS32(&pTaskFile->rc, VINF_SUCCESS);
    352357
    353358    for (unsigned i = 0; i < cSegments; i++)
     
    374379    if (ASMAtomicReadS32(&pTaskFile->cbTransferLeft) == 0
    375380        && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true))
    376         pdmR3AsyncCompletionCompleteTask(pTask, false);
     381        pdmR3AsyncCompletionCompleteTask(pTask, pTaskFile->rc, false);
    377382    else
    378383        rc = VINF_AIO_TASK_PENDING;
     
    10801085
    10811086    pTaskFile->cbTransferLeft = 0;
     1087    pTaskFile->rc             = VINF_SUCCESS;
    10821088
    10831089    if (pEpFile->fCaching)
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp

    r27563 r27920  
    8585*   Internal Functions                                                         *
    8686*******************************************************************************/
    87 static void pdmacFileCacheTaskCompleted(PPDMACTASKFILE pTask, void *pvUser);
     87static void pdmacFileCacheTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc);
    8888
    8989/**
     
    760760 * @param   pEndpointCache    The endpoint cache.
    761761 * @param   pTaskSeg          Task segment to complete.
    762  */
    763 static PPDMACFILETASKSEG pdmacFileCacheTaskComplete(PPDMACFILEENDPOINTCACHE pEndpointCache, PPDMACFILETASKSEG pTaskSeg)
     762 * @param   rc                Status code to set.
     763 */
     764static PPDMACFILETASKSEG pdmacFileCacheTaskComplete(PPDMACFILEENDPOINTCACHE pEndpointCache, PPDMACFILETASKSEG pTaskSeg, int rc)
    764765{
    765766    PPDMACFILETASKSEG pNext = pTaskSeg->pNext;
    766 
    767     uint32_t uOld = ASMAtomicSubS32(&pTaskSeg->pTask->cbTransferLeft, pTaskSeg->cbTransfer);
     767    PPDMASYNCCOMPLETIONTASKFILE pTaskFile = pTaskSeg->pTask;
     768
     769    if (RT_FAILURE(rc))
     770        ASMAtomicCmpXchgS32(&pTaskFile->rc, rc, VINF_SUCCESS);
     771
     772    uint32_t uOld = ASMAtomicSubS32(&pTaskFile->cbTransferLeft, pTaskSeg->cbTransfer);
    768773    AssertMsg(uOld >= pTaskSeg->cbTransfer, ("New value would overflow\n"));
    769774    if (!(uOld - pTaskSeg->cbTransfer)
    770         && !ASMAtomicXchgBool(&pTaskSeg->pTask->fCompleted, true))
    771         pdmR3AsyncCompletionCompleteTask(&pTaskSeg->pTask->Core, true);
     775        && !ASMAtomicXchgBool(&pTaskFile->fCompleted, true))
     776        pdmR3AsyncCompletionCompleteTask(&pTaskFile->Core, pTaskFile->rc, true);
    772777
    773778    RTMemFree(pTaskSeg);
     
    782787 * @param    pTask     The completed task.
    783788 * @param    pvUser    Opaque user data.
    784  */
    785 static void pdmacFileCacheTaskCompleted(PPDMACTASKFILE pTask, void *pvUser)
     789 * @param    rc        Status code of the completed request.
     790 */
     791static void pdmacFileCacheTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc)
    786792{
    787793    PPDMACFILECACHEENTRY pEntry = (PPDMACFILECACHEENTRY)pvUser;
     
    811817        ASMAtomicDecU32(&pEndpointCache->cWritesOutstanding);
    812818
    813         pEntry->fFlags &= ~PDMACFILECACHE_ENTRY_IS_DIRTY;
    814 
    815         while (pCurr)
     819        /*
     820         * An error here is difficult to handle as the original request completed already.
     821         * The error is logged for now and the VM is paused.
     822         * If the user continues the entry is written again in the hope
     823         * the user fixed the problem and the next write succeeds.
     824         */
     825        /** @todo r=aeichner: This solution doesn't work
     826         * The user will get the message but the VM will hang afterwards
     827         * VMR3Suspend() returns when the VM is suspended but suspending
     828         * the VM will reopen the images readonly in DrvVD. They are closed first
     829         * which will close the endpoints. This will block EMT while the
     830         * I/O manager processes the close request but the IO manager is stuck
     831         * in the VMR3Suspend call and can't process the request.
     832         * Another problem is that closing the VM means flushing the cache
     833         * but the entry failed and will probably fail again.
     834         * No idea so far how to solve this problem... but the user gets informed
     835         * at least.
     836         */
     837        if (RT_FAILURE(rc))
    816838        {
    817             AssertMsg(pCurr->fWrite, ("Completed write entries should never have read tasks attached\n"));
    818 
    819             memcpy(pEntry->pbData + pCurr->uBufOffset, pCurr->pvBuf, pCurr->cbTransfer);
    820             fDirty = true;
    821 
    822             pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr);
     839            LogRel(("I/O cache: Error while writing entry at offset %RTfoff (%u bytes) to file \"%s\"\n",
     840                    pEntry->Core.Key, pEntry->cbData, pEndpoint->Core.pszUri));
     841
     842            rc = VMSetRuntimeError(pEndpoint->Core.pEpClass->pVM, 0, "CACHE_IOERR",
     843                                   N_("The I/O cache encountered an error while updating data in file \"%s\" (rc=%Rrc). Make sure there is enough free space on the disk and that the disk is working properly. Operation can be resumed afterwards."), pEndpoint->Core.pszUri, rc);
     844            AssertRC(rc);
     845            rc = VMR3Suspend(pEndpoint->Core.pEpClass->pVM);
     846        }
     847        else
     848        {
     849            pEntry->fFlags &= ~PDMACFILECACHE_ENTRY_IS_DIRTY;
     850
     851            while (pCurr)
     852            {
     853                AssertMsg(pCurr->fWrite, ("Completed write entries should never have read tasks attached\n"));
     854
     855                memcpy(pEntry->pbData + pCurr->uBufOffset, pCurr->pvBuf, pCurr->cbTransfer);
     856                fDirty = true;
     857
     858                pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr, VINF_SUCCESS);
     859            }
    823860        }
    824861    }
     
    839876                memcpy(pCurr->pvBuf, pEntry->pbData + pCurr->uBufOffset, pCurr->cbTransfer);
    840877
    841             pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr);
     878            pCurr = pdmacFileCacheTaskComplete(pEndpointCache, pCurr, rc);
    842879        }
    843880    }
     
    852889        PPDMASYNCCOMPLETIONTASKFILE pTaskFlush = (PPDMASYNCCOMPLETIONTASKFILE)ASMAtomicXchgPtr((void * volatile *)&pEndpointCache->pTaskFlush, NULL);
    853890        if (pTaskFlush)
    854             pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core, true);
     891            pdmR3AsyncCompletionCompleteTask(&pTaskFlush->Core, VINF_SUCCESS, true);
    855892    }
    856893
     
    18861923    if (ASMAtomicReadS32(&pTask->cbTransferLeft) == 0
    18871924        && !ASMAtomicXchgBool(&pTask->fCompleted, true))
    1888         pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);
     1925        pdmR3AsyncCompletionCompleteTask(&pTask->Core, VINF_SUCCESS, false);
    18891926    else
    18901927        rc = VINF_AIO_TASK_PENDING;
     
    21432180    if (ASMAtomicReadS32(&pTask->cbTransferLeft) == 0
    21442181        && !ASMAtomicXchgBool(&pTask->fCompleted, true))
    2145         pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);
     2182        pdmR3AsyncCompletionCompleteTask(&pTask->Core, VINF_SUCCESS, false);
    21462183    else
    21472184        rc = VINF_AIO_TASK_PENDING;
     
    21712208        }
    21722209        else
    2173             pdmR3AsyncCompletionCompleteTask(&pTask->Core, false);
     2210            pdmR3AsyncCompletionCompleteTask(&pTask->Core, VINF_SUCCESS, false);
    21742211    }
    21752212
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileFailsafe.cpp

    r27299 r27920  
    7575        }
    7676
    77         AssertRC(rc);
    78 
    79         pCurr->pfnCompleted(pCurr, pCurr->pvUser);
     77        pCurr->pfnCompleted(pCurr, pCurr->pvUser, rc);
    8078        pdmacFileTaskFree(pEndpoint, pCurr);
    8179    }
    8280
    83     return rc;
     81    return VINF_SUCCESS;
    8482}
    8583
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h

    r27563 r27920  
    605605
    606606/** Request completion function */
    607 typedef DECLCALLBACK(void)   FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser);
     607typedef DECLCALLBACK(void)   FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser, int rc);
    608608/** Pointer to a request completion function. */
    609609typedef FNPDMACTASKCOMPLETED *PFNPDMACTASKCOMPLETED;
     
    667667    /** Flag whether the task completed. */
    668668    volatile bool         fCompleted;
     669    /** Return code. */
     670    volatile int          rc;
    669671} PDMASYNCCOMPLETIONTASKFILE;
    670672
     
    686688int pdmacFileEpAddTask(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask);
    687689
    688 void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser);
     690void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser, int rc);
    689691
    690692bool pdmacFileBwMgrIsTransferAllowed(PPDMACFILEBWMGR pBwMgr, uint32_t cbTransfer);
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp

    r27336 r27920  
    817817                if (!pEndpoint->AioMgr.cRequestsActive)
    818818                {
    819                     pCurr->pfnCompleted(pCurr, pCurr->pvUser);
     819                    pCurr->pfnCompleted(pCurr, pCurr->pvUser, VINF_SUCCESS);
    820820                    pdmacFileTaskFree(pEndpoint, pCurr);
    821821                }
     
    11631163    else
    11641164    {
    1165         AssertMsg((   (cbTransfered == pTask->DataSeg.cbSeg)
    1166                     || (pTask->fBounceBuffer && (cbTransfered >= pTask->DataSeg.cbSeg))),
    1167                     ("Task didn't completed successfully (rc=%Rrc) or was incomplete (cbTransfered=%u)\n", rcReq, cbTransfered));
     1165        AssertMsg(   RT_FAILURE(rcReq)
     1166                  || (   (cbTransfered == pTask->DataSeg.cbSeg)
     1167                      || (pTask->fBounceBuffer && (cbTransfered >= pTask->DataSeg.cbSeg))),
     1168                  ("Task didn't completed successfully (rc=%Rrc) or was incomplete (cbTransfered=%u)\n", rcReq, cbTransfered));
    11681169
    11691170        if (pTask->fPrefetch)
     
    11961197        else
    11971198        {
    1198             if (pTask->fBounceBuffer)
     1199            if (RT_SUCCESS(rc) && pTask->fBounceBuffer)
    11991200            {
    12001201                if (pTask->enmTransferType == PDMACTASKFILETRANSFER_READ)
     
    12181219
    12191220            /* Call completion callback */
    1220             pTask->pfnCompleted(pTask, pTask->pvUser);
     1221            pTask->pfnCompleted(pTask, pTask->pvUser, rcReq);
    12211222            pdmacFileTaskFree(pEndpoint, pTask);
    12221223
     
    12341235                AssertMsg(pTask->pEndpoint == pEndpoint, ("Endpoint of the flush request does not match assigned one\n"));
    12351236
    1236                 pTask->pfnCompleted(pTask, pTask->pvUser);
     1237                pTask->pfnCompleted(pTask, pTask->pvUser, VINF_SUCCESS);
    12371238                pdmacFileTaskFree(pEndpoint, pTask);
    12381239            }
  • trunk/src/VBox/VMM/PDMAsyncCompletionInternal.h

    r27884 r27920  
    263263 * @returns nothing
    264264 * @param   pTask                     Pointer to the finished task.
     265 * @param   rc                        Status code of the completed request.
    265266 * @param   fCallCompletionHandler    Flag whether the completion handler should be called to
    266267 *                                    inform the owner of the task that it has completed.
    267268 */
    268 void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, bool fCallCompletionHandler);
     269void pdmR3AsyncCompletionCompleteTask(PPDMASYNCCOMPLETIONTASK pTask, int rc, bool fCallCompletionHandler);
    269270
    270271RT_C_DECLS_END
  • trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp

    r27797 r27920  
    6363RTSEMEVENT              g_FinishedEventSem;
    6464
    65 void pfnAsyncTaskCompleted(PVM pVM, void *pvUser, void *pvUser2)
     65void pfnAsyncTaskCompleted(PVM pVM, void *pvUser, void *pvUser2, int rc)
    6666{
    6767    LogFlow((TESTCASE ": %s: pVM=%p pvUser=%p pvUser2=%p\n", __FUNCTION__, pVM, pvUser, pvUser2));
  • trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp

    r26338 r27920  
    160160PDMACTESTFILE g_aTestFiles[NR_OPEN_ENDPOINTS];
    161161
    162 static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2);
     162static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2, int rcReq);
    163163
    164164static void tstPDMACStressTestFileVerify(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
     
    364364                    rc = tstPDMACStressTestFileRead(pTestFile, pTask);
    365365
    366                 AssertRC(rc);
    367 
    368366                if (rc != VINF_AIO_TASK_PENDING)
    369                     tstPDMACStressTestFileTaskCompleted(pVM, pTask, pTestFile);
     367                    tstPDMACStressTestFileTaskCompleted(pVM, pTask, pTestFile, rc);
    370368
    371369                cTasksStarted++;
     
    394392}
    395393
    396 static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2)
     394static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2, int rcReq)
    397395{
    398396    PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pvUser2;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette