VirtualBox

Changeset 51750 in vbox for trunk/src/VBox/Storage


Ignore:
Timestamp:
Jun 27, 2014 8:44:58 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
94562
Message:

Storage: Fix concurrency issue with filters configured which can result in corrupt data being transfered, the filters must be applied under the lock to avoid multiple threads accessing the same filter at the same time

File:
1 edited

Legend:

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

    r51623 r51750  
    480480 * it was alloacted elsewhere (stack, ...). */
    481481#define VDIOCTX_FLAGS_DONT_FREE              RT_BIT_32(4)
    482 /* Don't set the modified flag for this I/O context when writing. */
     482/** Don't set the modified flag for this I/O context when writing. */
    483483#define VDIOCTX_FLAGS_DONT_SET_MODIFIED_FLAG RT_BIT_32(5)
     484/** The write filter was applied already and shouldn't be applied a second time.
     485 * Used at the beginning of vdWriteHelperAsync() because it might be called
     486 * multiple times.
     487 */
     488#define VDIOCTX_FLAGS_WRITE_FILTER_APPLIED   RT_BIT_32(6)
    484489
    485490/** NIL I/O context pointer value. */
     
    967972    int rc = VINF_SUCCESS;
    968973
     974    VD_IS_LOCKED(pDisk);
     975
    969976    if (pDisk->pFilterHead)
    970977    {
     
    9981005{
    9991006    int rc = VINF_SUCCESS;
     1007
     1008    VD_IS_LOCKED(pDisk);
    10001009
    10011010    if (pDisk->pFilterHead)
     
    17411750        if (pTmp == pIoCtxRc)
    17421751        {
     1752            if (   rcTmp == VINF_VD_ASYNC_IO_FINISHED
     1753                && RT_SUCCESS(pTmp->rcReq)
     1754                && pTmp->enmTxDir == VDIOCTXTXDIR_READ)
     1755            {
     1756                   int rc2 = vdFilterChainApplyRead(pDisk, pTmp->Req.Io.uOffsetXferOrig,
     1757                                                    pTmp->Req.Io.cbXferOrig, pTmp);
     1758                    if (RT_FAILURE(rc2))
     1759                        rcTmp = rc2;
     1760            }
     1761
    17431762            /* The given I/O context was processed, pass the return code to the caller. */
    17441763            if (   rcTmp == VINF_VD_ASYNC_IO_FINISHED
     
    22092228    IoCtx.Type.Root.pvUser2     = hEventComplete;
    22102229    rc = vdIoCtxProcessSync(&IoCtx, hEventComplete);
    2211     if (RT_SUCCESS(rc))
    2212         rc = vdFilterChainApplyRead(pDisk, uOffset, cbRead, &IoCtx);
    2213 
    22142230    RTSemEventDestroy(hEventComplete);
    22152231    return rc;
     
    23082324    IoCtx.Type.Root.pvUser1     = pDisk;
    23092325    IoCtx.Type.Root.pvUser2     = hEventComplete;
    2310     /* Apply write filter chain here. */
    2311     rc = vdFilterChainApplyWrite(pDisk, uOffset, cbWrite, &IoCtx);
    23122326    if (RT_SUCCESS(rc))
    23132327        rc = vdIoCtxProcessSync(&IoCtx, hEventComplete);
     
    29212935    size_t cbThisWrite;
    29222936    size_t cbPreRead, cbPostRead;
     2937
     2938    /* Apply write filter chain here if it was not done already. */
     2939    if (!(pIoCtx->fFlags & VDIOCTX_FLAGS_WRITE_FILTER_APPLIED))
     2940    {
     2941        rc = vdFilterChainApplyWrite(pDisk, uOffset, cbWrite, pIoCtx);
     2942        if (RT_FAILURE(rc))
     2943            return rc;
     2944        pIoCtx->fFlags |= VDIOCTX_FLAGS_WRITE_FILTER_APPLIED;
     2945    }
    29232946
    29242947    if (!(pIoCtx->fFlags & VDIOCTX_FLAGS_DONT_SET_MODIFIED_FLAG))
     
    1005110074        {
    1005210075            if (ASMAtomicCmpXchgBool(&pIoCtx->fComplete, true, false))
    10053             {
    10054                 rc2 = vdFilterChainApplyRead(pDisk, pIoCtx->Req.Io.uOffsetXferOrig,
    10055                                              pIoCtx->Req.Io.cbXferOrig, pIoCtx);
    10056                 if (RT_FAILURE(rc2))
    10057                     rc = rc2;
    1005810076                vdIoCtxFree(pDisk, pIoCtx);
    10059             }
    1006010077            else
    1006110078                rc = VERR_VD_ASYNC_IO_IN_PROGRESS; /* Let the other handler complete the request. */
     
    1012210139        {
    1012310140            rc = VERR_NO_MEMORY;
    10124             break;
    10125         }
    10126 
    10127         /* Apply write filter chain here. */
    10128         rc = vdFilterChainApplyWrite(pDisk, uOffset, cbWrite, pIoCtx);
    10129         if (RT_FAILURE(rc))
    10130         {
    10131             vdIoCtxFree(pDisk, pIoCtx);
    1013210141            break;
    1013310142        }
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