VirtualBox

Changeset 35321 in vbox for trunk/src


Ignore:
Timestamp:
Dec 24, 2010 4:05:54 PM (14 years ago)
Author:
vboxsync
Message:

Storage: Fix possible crashes with VMDK/VHD imageswith snapshots and async I/O

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/VD.cpp

    r35188 r35321  
    274274    volatile size_t              cbTransfer;
    275275    /** Current image in the chain. */
    276     PVDIMAGE                     pImage;
     276    PVDIMAGE                     pImageCur;
     277    /** Start image to read from. pImageCur is reset to this
     278     *  value after it reached the first image in the chain. */
     279    PVDIMAGE                     pImageStart;
    277280    /** S/G buffer */
    278281    RTSGBUF                      SgBuf;
     
    903906DECLINLINE(PVDIOCTX) vdIoCtxAlloc(PVBOXHDD pDisk, VDIOCTXTXDIR enmTxDir,
    904907                                  uint64_t uOffset, size_t cbTransfer,
     908                                  PVDIMAGE pImageStart,
    905909                                  PCRTSGBUF pcSgBuf, void *pvAllocation,
    906910                                  PFNVDIOCTXTRANSFER pfnIoCtxTransfer)
     
    916920        pIoCtx->uOffset               = uOffset;
    917921        pIoCtx->cbTransfer            = cbTransfer;
     922        pIoCtx->pImageStart           = pImageStart;
     923        pIoCtx->pImageCur             = pImageStart;
    918924        pIoCtx->cDataTransfersPending = 0;
    919925        pIoCtx->cMetaTransfersPending = 0;
     
    937943DECLINLINE(PVDIOCTX) vdIoCtxRootAlloc(PVBOXHDD pDisk, VDIOCTXTXDIR enmTxDir,
    938944                                      uint64_t uOffset, size_t cbTransfer,
    939                                       PCRTSGBUF pcSgBuf,
     945                                      PVDIMAGE pImageStart, PCRTSGBUF pcSgBuf,
    940946                                      PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
    941947                                      void *pvUser1, void *pvUser2,
     
    943949                                      PFNVDIOCTXTRANSFER pfnIoCtxTransfer)
    944950{
    945     PVDIOCTX pIoCtx = vdIoCtxAlloc(pDisk, enmTxDir, uOffset, cbTransfer,
     951    PVDIOCTX pIoCtx = vdIoCtxAlloc(pDisk, enmTxDir, uOffset, cbTransfer, pImageStart,
    946952                                   pcSgBuf, pvAllocation, pfnIoCtxTransfer);
    947953
     
    960966DECLINLINE(PVDIOCTX) vdIoCtxChildAlloc(PVBOXHDD pDisk, VDIOCTXTXDIR enmTxDir,
    961967                                       uint64_t uOffset, size_t cbTransfer,
    962                                        PCRTSGBUF pcSgBuf,
     968                                       PVDIMAGE pImageStart, PCRTSGBUF pcSgBuf,
    963969                                       PVDIOCTX pIoCtxParent, size_t cbTransferParent,
    964970                                       size_t cbWriteParent, void *pvAllocation,
    965971                                       PFNVDIOCTXTRANSFER pfnIoCtxTransfer)
    966972{
    967     PVDIOCTX pIoCtx = vdIoCtxAlloc(pDisk, enmTxDir, uOffset, cbTransfer,
     973    PVDIOCTX pIoCtx = vdIoCtxAlloc(pDisk, enmTxDir, uOffset, cbTransfer, pImageStart,
    968974                                   pcSgBuf, pvAllocation, pfnIoCtxTransfer);
    969975
     
    12721278    do
    12731279    {
    1274         pCurrImage = pIoCtx->pImage;
     1280        pCurrImage = pIoCtx->pImageCur;
    12751281
    12761282        /* Search for image with allocated block. Do not attempt to read more
     
    13291335        pIoCtx->uOffset    = uOffset;
    13301336        pIoCtx->cbTransfer = cbToRead;
    1331         pIoCtx->pImage     = pCurrImage;
     1337        pIoCtx->pImageCur  = pCurrImage ? pCurrImage : pIoCtx->pImageStart;
    13321338    }
    13331339
     
    17271733}
    17281734
     1735static int vdWriteHelperOptimizedCommitAsync(PVDIOCTX pIoCtx)
     1736{
     1737    int rc = VINF_SUCCESS;
     1738    PVDIMAGE pImage = pIoCtx->pImageCur;
     1739    size_t cbPreRead      = pIoCtx->Type.Child.cbPreRead;
     1740    size_t cbPostRead     = pIoCtx->Type.Child.cbPostRead;
     1741    size_t cbThisWrite    = pIoCtx->Type.Child.cbTransferParent;
     1742
     1743    LogFlowFunc(("pIoCtx=%#p\n", pIoCtx));
     1744    rc = pImage->Backend->pfnAsyncWrite(pImage->pBackendData,
     1745                                        pIoCtx->uOffset - cbPreRead,
     1746                                        cbPreRead + cbThisWrite + cbPostRead,
     1747                                        pIoCtx, NULL, &cbPreRead, &cbPostRead, 0);
     1748    Assert(rc != VERR_VD_BLOCK_FREE);
     1749    Assert(rc == VERR_VD_NOT_ENOUGH_METADATA || cbPreRead == 0);
     1750    Assert(rc == VERR_VD_NOT_ENOUGH_METADATA || cbPostRead == 0);
     1751    if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     1752        rc = VINF_SUCCESS;
     1753    else if (rc == VERR_VD_IOCTX_HALT)
     1754    {
     1755        pIoCtx->fBlocked = true;
     1756        rc = VINF_SUCCESS;
     1757    }
     1758
     1759    LogFlowFunc(("returns rc=%Rrc\n", rc));
     1760    return rc;
     1761}
     1762
    17291763static int vdWriteHelperOptimizedCmpAndWriteAsync(PVDIOCTX pIoCtx)
    17301764{
    17311765    int rc = VINF_SUCCESS;
    1732     PVDIMAGE pImage = pIoCtx->pImage;
     1766    PVDIMAGE pImage = pIoCtx->pImageCur;
    17331767    size_t cbThisWrite    = 0;
    17341768    size_t cbPreRead      = pIoCtx->Type.Child.cbPreRead;
     
    18001834    /* Write the full block to the virtual disk. */
    18011835    RTSgBufReset(&pIoCtx->SgBuf);
    1802     rc = pImage->Backend->pfnAsyncWrite(pImage->pBackendData,
    1803                                         pIoCtx->uOffset - cbPreRead,
    1804                                         cbPreRead + cbThisWrite + cbPostRead,
    1805                                         pIoCtx, NULL, &cbPreRead, &cbPostRead, 0);
    1806     Assert(rc != VERR_VD_BLOCK_FREE);
    1807     Assert(cbPreRead == 0);
    1808     Assert(cbPostRead == 0);
    1809     if (rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
    1810         rc = VINF_SUCCESS;
    1811     else if (rc == VERR_VD_IOCTX_HALT)
    1812     {
    1813         pIoCtx->fBlocked = true;
    1814         rc = VINF_SUCCESS;
    1815     }
     1836    pIoCtx->pfnIoCtxTransferNext = vdWriteHelperOptimizedCommitAsync;
    18161837
    18171838    return rc;
     
    19011922    size_t cbWrite   = pIoCtx->cbTransfer;
    19021923    uint64_t uOffset = pIoCtx->uOffset;
    1903     PVDIMAGE pImage  = pIoCtx->pImage;
     1924    PVDIMAGE pImage  = pIoCtx->pImageCur;
    19041925    PVBOXHDD pDisk   = pIoCtx->pDisk;
    19051926    unsigned fWrite;
     
    19421963
    19431964                PVDIOCTX pIoCtxWrite = vdIoCtxChildAlloc(pDisk, VDIOCTXTXDIR_WRITE,
    1944                                                          uOffset, pSeg->cbSeg,
     1965                                                         uOffset, pSeg->cbSeg, pImage,
    19451966                                                         pTmp,
    19461967                                                         pIoCtx, cbThisWrite,
     
    19601981                             pIoCtx, pIoCtxWrite));
    19611982
    1962                 pIoCtxWrite->pImage                = pImage;
    19631983                pIoCtxWrite->Type.Child.cbPreRead  = cbPreRead;
    19641984                pIoCtxWrite->Type.Child.cbPostRead = cbPostRead;
     
    20392059    int rc = VINF_SUCCESS;
    20402060    PVBOXHDD pDisk = pIoCtx->pDisk;
    2041     PVDIMAGE pImage = pIoCtx->pImage;
     2061    PVDIMAGE pImage = pIoCtx->pImageCur;
    20422062
    20432063    rc = vdIoCtxLockDisk(pDisk, pIoCtx);
     
    80038023                            uOffset, cbRead, pDisk->cbSize),
    80048024                           rc = VERR_INVALID_PARAMETER);
     8025        AssertPtrBreakStmt(pDisk->pLast, rc = VERR_VD_NOT_OPENED);
    80058026
    80068027        pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_READ, uOffset,
    8007                                   cbRead, pcSgBuf,
     8028                                  cbRead, pDisk->pLast, pcSgBuf,
    80088029                                  pfnComplete, pvUser1, pvUser2,
    80098030                                  NULL, vdReadHelperAsync);
     
    80138034            break;
    80148035        }
    8015 
    8016         pIoCtx->pImage = pDisk->pLast;
    8017         AssertPtrBreakStmt(pIoCtx->pImage, rc = VERR_VD_NOT_OPENED);
    80188036
    80198037        rc = vdIoCtxProcess(pIoCtx);
     
    80768094                            uOffset, cbWrite, pDisk->cbSize),
    80778095                           rc = VERR_INVALID_PARAMETER);
     8096        AssertPtrBreakStmt(pDisk->pLast, rc = VERR_VD_NOT_OPENED);
    80788097
    80798098        pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_WRITE, uOffset,
    8080                                   cbWrite, pcSgBuf,
     8099                                  cbWrite, pDisk->pLast, pcSgBuf,
    80818100                                  pfnComplete, pvUser1, pvUser2,
    80828101                                  NULL, vdWriteHelperAsync);
     
    80868105            break;
    80878106        }
    8088 
    8089         PVDIMAGE pImage = pDisk->pLast;
    8090         AssertPtrBreakStmt(pImage, rc = VERR_VD_NOT_OPENED);
    8091         pIoCtx->pImage = pImage;
    80928107
    80938108        rc = vdIoCtxProcess(pIoCtx);
     
    81358150        fLockWrite = true;
    81368151
     8152        AssertPtrBreakStmt(pDisk->pLast, rc = VERR_VD_NOT_OPENED);
     8153
    81378154        pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_FLUSH, 0,
    8138                                   0, NULL,
     8155                                  0, pDisk->pLast, NULL,
    81398156                                  pfnComplete, pvUser1, pvUser2,
    81408157                                  NULL, vdFlushHelperAsync);
     
    81448161            break;
    81458162        }
    8146 
    8147         PVDIMAGE pImage = pDisk->pLast;
    8148         AssertPtrBreakStmt(pImage, rc = VERR_VD_NOT_OPENED);
    8149         pIoCtx->pImage = pImage;
    81508163
    81518164        rc = vdIoCtxProcess(pIoCtx);
Note: See TracChangeset for help on using the changeset viewer.

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