VirtualBox

Changeset 28383 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 15, 2010 6:07:21 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
60144
Message:

async I/O: Add async flush method

Location:
trunk/src/VBox/Devices/Storage
Files:
5 edited

Legend:

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

    r28065 r28383  
    326326}
    327327
     328
     329/** @copydoc PDMIBLOCKASYNC::pfnStartFLush */
     330static DECLCALLBACK(int) drvblockAsyncFlushStart(PPDMIBLOCKASYNC pInterface, void *pvUser)
     331{
     332    PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
     333
     334    /*
     335     * Check the state.
     336     */
     337    if (!pThis->pDrvMediaAsync)
     338    {
     339        AssertMsgFailed(("Invalid state! Not mounted!\n"));
     340        return VERR_PDM_MEDIA_NOT_MOUNTED;
     341    }
     342
     343    int rc = pThis->pDrvMediaAsync->pfnStartFlush(pThis->pDrvMediaAsync, pvUser);
     344
     345    return rc;
     346}
     347
    328348/* -=-=-=-=- IMediaAsyncPort -=-=-=-=- */
    329349
     
    774794    pThis->IBlockAsync.pfnStartRead         = drvblockAsyncReadStart;
    775795    pThis->IBlockAsync.pfnStartWrite        = drvblockAsyncWriteStart;
     796    pThis->IBlockAsync.pfnStartFlush        = drvblockAsyncFlushStart;
    776797
    777798    /* IMediaAsyncPort. */
  • trunk/src/VBox/Devices/Storage/DrvSCSI.cpp

    r28258 r28383  
    223223    if (pThis->pDrvBlockAsync)
    224224    {
    225         /* asnyc I/O path. */
     225        /* async I/O path. */
    226226        VSCSIIOREQTXDIR enmTxDir;
    227227
     
    234234            case VSCSIIOREQTXDIR_FLUSH:
    235235            {
    236                 /** @todo Flush callback for the async I/O interface. */
    237                 ASMAtomicDecU32(&pThis->StatIoDepth);
    238                 VSCSIIoReqCompleted(hVScsiIoReq, VINF_SUCCESS);
     236                rc = pThis->pDrvBlockAsync->pfnStartFlush(pThis->pDrvBlockAsync, hVScsiIoReq);
     237                if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
     238                    AssertMsgFailed(("%s: Failed to flush data %Rrc\n", __FUNCTION__, rc));
    239239                break;
    240240            }
     
    273273                }
    274274
    275                 if (rc == VINF_VD_ASYNC_IO_FINISHED)
    276                 {
    277                     if (enmTxDir == VSCSIIOREQTXDIR_READ)
    278                         pThis->pLed->Actual.s.fReading = 0;
    279                     else if (enmTxDir == VSCSIIOREQTXDIR_WRITE)
    280                         pThis->pLed->Actual.s.fWriting = 0;
    281                     else
    282                         AssertMsgFailed(("Invalid transfer direction %u\n", enmTxDir));
    283                     ASMAtomicDecU32(&pThis->StatIoDepth);
    284                     VSCSIIoReqCompleted(hVScsiIoReq, VINF_SUCCESS);
    285                 }
    286                 else if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    287                     rc = VINF_SUCCESS;
    288                 else if (RT_FAILURE(rc))
    289                 {
    290                     if (enmTxDir == VSCSIIOREQTXDIR_READ)
    291                         pThis->pLed->Actual.s.fReading = 0;
    292                     else if (enmTxDir == VSCSIIOREQTXDIR_WRITE)
    293                         pThis->pLed->Actual.s.fWriting = 0;
    294                     else
    295                         AssertMsgFailed(("Invalid transfer direction %u\n", enmTxDir));
    296                     ASMAtomicDecU32(&pThis->StatIoDepth);
    297                     VSCSIIoReqCompleted(hVScsiIoReq, rc);
    298                 }
    299                 else
    300                     AssertMsgFailed(("Invalid return coe rc=%Rrc\n", rc));
    301 
    302275                break;
    303276            }
     
    305278                AssertMsgFailed(("Invalid transfer direction %u\n", enmTxDir));
    306279        }
     280
     281        if (rc == VINF_VD_ASYNC_IO_FINISHED)
     282        {
     283            if (enmTxDir == VSCSIIOREQTXDIR_READ)
     284                pThis->pLed->Actual.s.fReading = 0;
     285            else if (enmTxDir == VSCSIIOREQTXDIR_WRITE)
     286                pThis->pLed->Actual.s.fWriting = 0;
     287            else
     288                AssertMsg(enmTxDir == VSCSIIOREQTXDIR_FLUSH, ("Invalid transfer direction %u\n", enmTxDir));
     289
     290            ASMAtomicDecU32(&pThis->StatIoDepth);
     291            VSCSIIoReqCompleted(hVScsiIoReq, VINF_SUCCESS);
     292        }
     293        else if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     294            rc = VINF_SUCCESS;
     295        else if (RT_FAILURE(rc))
     296        {
     297            if (enmTxDir == VSCSIIOREQTXDIR_READ)
     298                pThis->pLed->Actual.s.fReading = 0;
     299            else if (enmTxDir == VSCSIIOREQTXDIR_WRITE)
     300                pThis->pLed->Actual.s.fWriting = 0;
     301            else
     302                AssertMsg(enmTxDir == VSCSIIOREQTXDIR_FLUSH, ("Invalid transfer direction %u\n", enmTxDir));
     303
     304            ASMAtomicDecU32(&pThis->StatIoDepth);
     305            VSCSIIoReqCompleted(hVScsiIoReq, rc);
     306        }
     307        else
     308            AssertMsgFailed(("Invalid return code rc=%Rrc\n", rc));
    307309    }
    308310    else
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r28258 r28383  
    10171017                                         size_t cbWrite, void *pvUser)
    10181018{
    1019      LogFlow(("%s: uOffset=%#llx paSeg=%#p cSeg=%u cbWrite=%d\n pvUser=%#p", __FUNCTION__,
     1019     LogFlow(("%s: uOffset=%#llx paSeg=%#p cSeg=%u cbWrite=%d pvUser=%#p\n", __FUNCTION__,
    10201020             uOffset, paSeg, cSeg, cbWrite, pvUser));
    10211021    PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
    10221022    int rc = VDAsyncWrite(pThis->pDisk, uOffset, cbWrite, paSeg, cSeg,
    10231023                          drvvdAsyncReqComplete, pThis, pvUser);
     1024    LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
     1025    return rc;
     1026}
     1027
     1028static DECLCALLBACK(int) drvvdStartFlush(PPDMIMEDIAASYNC pInterface, void *pvUser)
     1029{
     1030     LogFlow(("%s: pvUser=%#p\n", __FUNCTION__, pvUser));
     1031    PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
     1032    int rc = VDAsyncFlush(pThis->pDisk, drvvdAsyncReqComplete, pThis, pvUser);
    10241033    LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
    10251034    return rc;
     
    12401249    pThis->IMediaAsync.pfnStartRead       = drvvdStartRead;
    12411250    pThis->IMediaAsync.pfnStartWrite      = drvvdStartWrite;
     1251    pThis->IMediaAsync.pfnStartFlush      = drvvdStartFlush;
    12421252
    12431253    /* Initialize supported VD interfaces. */
  • trunk/src/VBox/Devices/Storage/VBoxHDD.cpp

    r28226 r28383  
    18731873                          PVDIOCTX pIoCtx)
    18741874{
    1875     return VERR_NOT_IMPLEMENTED;
     1875    PVBOXHDD pDisk = (PVBOXHDD)pvUser;
     1876    int rc = VINF_SUCCESS;
     1877    PVDIOTASK pIoTask;
     1878    void *pvTask = NULL;
     1879
     1880    pIoTask = vdIoTaskMetaAlloc(pDisk, pIoCtx, VDIOCTXTXDIR_FLUSH,
     1881                                NULL, NULL);
     1882    if (!pIoTask)
     1883        return VERR_NO_MEMORY;
     1884
     1885    ASMAtomicIncU32(&pIoCtx->cMetaTransfersPending);
     1886
     1887    int rc2 = pDisk->pInterfaceAsyncIOCallbacks->pfnFlushAsync(pDisk->pInterfaceAsyncIO->pvUser,
     1888                                                               pIoStorage->u.pStorage,
     1889                                                               pIoTask,
     1890                                                               &pvTask);
     1891    if (rc2 == VINF_SUCCESS)
     1892    {
     1893        ASMAtomicDecU32(&pIoCtx->cMetaTransfersPending);
     1894        vdIoTaskFree(pDisk, pIoTask);
     1895    }
     1896    else if (rc2 == VERR_VD_ASYNC_IO_IN_PROGRESS)
     1897        rc = VINF_SUCCESS;
     1898    else if (RT_FAILURE(rc2))
     1899        rc = rc2;
     1900
     1901    return rc;
    18761902}
    18771903
     
    57055731    LogFlowFunc(("returns %Rrc\n", rc));
    57065732    return rc;
    5707 
     5733}
     5734
     5735
     5736VBOXDDU_DECL(int) VDAsyncFlush(PVBOXHDD pDisk, PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
     5737                               void *pvUser1, void *pvUser2)
     5738{
     5739    int rc;
     5740    int rc2;
     5741    bool fLockWrite = false;
     5742    PVDIOCTX pIoCtx = NULL;
     5743
     5744    LogFlowFunc(("pDisk=%#p\n", pDisk));
     5745
     5746    do
     5747    {
     5748        /* sanity check */
     5749        AssertPtrBreakStmt(pDisk, rc = VERR_INVALID_PARAMETER);
     5750        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     5751
     5752        rc2 = vdThreadStartWrite(pDisk);
     5753        AssertRC(rc2);
     5754        fLockWrite = true;
     5755
     5756        pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_FLUSH, 0,
     5757                                  0, NULL, 0,
     5758                                  pfnComplete, pvUser1, pvUser2,
     5759                                  NULL);
     5760        if (!pIoCtx)
     5761        {
     5762            rc = VERR_NO_MEMORY;
     5763            break;
     5764        }
     5765
     5766        PVDIMAGE pImage = pDisk->pLast;
     5767        AssertPtrBreakStmt(pImage, rc = VERR_VD_NOT_OPENED);
     5768
     5769        vdResetModifiedFlag(pDisk);
     5770        rc = pImage->Backend->pfnAsyncFlush(pImage->pvBackendData, pIoCtx);
     5771    } while (0);
     5772
     5773    if (RT_UNLIKELY(fLockWrite) && RT_FAILURE(rc))
     5774    {
     5775        rc2 = vdThreadFinishWrite(pDisk);
     5776        AssertRC(rc2);
     5777    }
     5778
     5779    if (RT_SUCCESS(rc))
     5780    {
     5781        if (   !pIoCtx->cbTransferLeft
     5782            && !pIoCtx->cMetaTransfersPending
     5783            && ASMAtomicCmpXchgBool(&pIoCtx->fComplete, true, false))
     5784        {
     5785            vdIoCtxFree(pDisk, pIoCtx);
     5786            rc = VINF_VD_ASYNC_IO_FINISHED;
     5787        }
     5788        else
     5789        {
     5790            LogFlow(("cbTransferLeft=%u cMetaTransfersPending=%u fComplete=%RTbool\n",
     5791                     pIoCtx->cbTransferLeft, pIoCtx->cMetaTransfersPending,
     5792                     pIoCtx->fComplete));
     5793            rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     5794        }
     5795    }
     5796
     5797    LogFlowFunc(("returns %Rrc\n", rc));
     5798    return rc;
    57085799}
    57095800
  • trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp

    r28154 r28383  
    234234    return pImage->pStorage != NULL;
    235235#endif
     236}
     237
     238static int vdiFileFlushAsync(PVDIIMAGEDESC pImage, PVDIOCTX pIoCtx)
     239{
     240    return pImage->pInterfaceIOCallbacks->pfnFlushAsync(pImage->pInterfaceIO->pvUser,
     241                                                        pImage->pStorage, pIoCtx);
    236242}
    237243
     
    951957
    952958/**
     959 * Internal: Flush the image file to disk - async version.
     960 */
     961static void vdiFlushImageAsync(PVDIIMAGEDESC pImage, PVDIOCTX pIoCtx)
     962{
     963    if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
     964    {
     965        /* Save header. */
     966        int rc = vdiUpdateHeaderAsync(pImage, pIoCtx);
     967        AssertMsgRC(rc, ("vdiUpdateHeaderAsync() failed, filename=\"%s\", rc=%Rrc\n",
     968                         pImage->pszFilename, rc));
     969        rc = vdiFileFlushAsync(pImage, pIoCtx);
     970        AssertMsgRC(rc, ("Flushing data to disk failed rc=%Rrc\n", rc));
     971    }
     972}
     973
     974/**
    953975 * Internal: Free all allocated space for representing an image, and optionally
    954976 * delete the image from disk.
     
    22292251static int vdiAsyncFlush(void *pvBackendData, PVDIOCTX pIoCtx)
    22302252{
    2231     int rc = VERR_NOT_IMPLEMENTED;
     2253    LogFlowFunc(("pBackendData=%#p\n", pvBackendData));
     2254    PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)pvBackendData;
     2255    int rc = VINF_SUCCESS;
     2256
     2257    Assert(pImage);
     2258
     2259    vdiFlushImageAsync(pImage, pIoCtx);
    22322260    LogFlowFunc(("returns %Rrc\n", rc));
    22332261    return rc;
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