VirtualBox

Changeset 34347 in vbox for trunk


Ignore:
Timestamp:
Nov 24, 2010 10:34:21 PM (14 years ago)
Author:
vboxsync
Message:

BlkCache: Suspend the VM if an error occurs during a write

Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PDM.cpp

    r34219 r34347  
    16251625
    16261626    /*
     1627     * Resume the block cache.
     1628     */
     1629    if (RT_SUCCESS(rc))
     1630        pdmR3BlkCacheResume(pVM);
     1631
     1632    /*
    16271633     * On failure, clean up via PDMR3Suspend.
    16281634     */
  • trunk/src/VBox/VMM/PDMBlkCache.cpp

    r34340 r34347  
    724724 * @returns Flag whether the amount of dirty bytes in the cache exceeds the threshold
    725725 * @param   pBlkCache    The endpoint cache the entry belongs to.
    726  * @param   pEntry            The entry to add.
     726 * @param   pEntry       The entry to add.
    727727 */
    728728static bool pdmBlkCacheAddDirtyEntry(PPDMBLKCACHE pBlkCache, PPDMBLKCACHEENTRY pEntry)
     
    748748        uint32_t cbDirty = ASMAtomicAddU32(&pCache->cbDirty, pEntry->cbData);
    749749
    750         fDirtyBytesExceeded = (cbDirty >= pCache->cbCommitDirtyThreshold);
     750        /* Prevent committing if the VM was suspended. */
     751        if (RT_LIKELY(!ASMAtomicReadBool(&pCache->fIoErrorVmSuspended)))
     752            fDirtyBytesExceeded = (cbDirty >= pCache->cbCommitDirtyThreshold);
    751753    }
    752754
     
    763765    LogFlowFunc(("Commit interval expired, commiting dirty entries\n"));
    764766
    765     if (ASMAtomicReadU32(&pCache->cbDirty) > 0)
     767    if (   ASMAtomicReadU32(&pCache->cbDirty) > 0
     768        && !ASMAtomicReadBool(&pCache->fIoErrorVmSuspended))
    766769        pdmBlkCacheCommitDirtyEntries(pCache);
    767770
     
    946949}
    947950
     951int pdmR3BlkCacheResume(PVM pVM)
     952{
     953    PPDMBLKCACHEGLOBAL pBlkCacheGlobal = pVM->pUVM->pdm.s.pBlkCacheGlobal;
     954
     955    LogFlowFunc(("pVM=%#p\n", pVM));
     956
     957    if (   pBlkCacheGlobal
     958        && ASMAtomicXchgBool(&pBlkCacheGlobal->fIoErrorVmSuspended, false))
     959    {
     960        /* The VM was suspended because of an I/O error, commit all dirty entries. */
     961        pdmBlkCacheCommitDirtyEntries(pBlkCacheGlobal);
     962    }
     963
     964    return VINF_SUCCESS;
     965}
     966
    948967static int pdmR3BlkCacheRetain(PVM pVM, PPPDMBLKCACHE ppBlkCache, const char *pcszId)
    949968{
     
    22702289                    pEntry->Core.Key, pEntry->cbData, pBlkCache->pszId));
    22712290
    2272             int rc = VMSetRuntimeError(pCache->pVM, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "BLKCACHE_IOERR",
    2273                                        N_("The I/O cache encountered an error while updating data in medium \"%s\" (rc=%Rrc)."
    2274                                           "Make sure there is enough free space on the disk and that the disk is working properly."
    2275                                           "Operation can be resumed afterwards."),
    2276                                        pBlkCache->pszId, rcIoXfer);
    2277             AssertRC(rc);
     2291            if (!ASMAtomicXchgBool(&pCache->fIoErrorVmSuspended, true))
     2292            {
     2293                int rc = VMSetRuntimeError(pCache->pVM, VMSETRTERR_FLAGS_SUSPEND | VMSETRTERR_FLAGS_NO_WAIT, "BLKCACHE_IOERR",
     2294                                           N_("The I/O cache encountered an error while updating data in medium \"%s\" (rc=%Rrc). "
     2295                                              "Make sure there is enough free space on the disk and that the disk is working properly. "
     2296                                              "Operation can be resumed afterwards"),
     2297                                           pBlkCache->pszId, rcIoXfer);
     2298                AssertRC(rc);
     2299            }
     2300
     2301            /*
     2302             * The entry is still marked as dirty which prevents eviction.
     2303             * Add the waiters to the list again.
     2304             */
     2305            fDirty = true;
     2306
     2307            if (pComplete)
     2308            {
     2309                pEntry->pWaitingHead = pComplete;
     2310                while (pComplete->pNext)
     2311                    pComplete = pComplete->pNext;
     2312                pEntry->pWaitingTail = pComplete;
     2313                pComplete = NULL;
     2314            }
    22782315        }
    22792316        else
  • trunk/src/VBox/VMM/PDMBlkCacheInternal.h

    r34221 r34347  
    154154    STAMCOUNTER       StatBuffersReused;
    155155#endif
     156    /** Flag whether the VM was suspended becaus of an I/O error. */
     157    volatile bool     fIoErrorVmSuspended;
    156158} PDMBLKCACHEGLOBAL;
    157159#ifdef VBOX_WITH_STATISTICS
  • trunk/src/VBox/VMM/PDMInternal.h

    r34241 r34347  
    11781178int         pdmR3BlkCacheInit(PVM pVM);
    11791179void        pdmR3BlkCacheTerm(PVM pVM);
     1180int         pdmR3BlkCacheResume(PVM pVM);
    11801181
    11811182#endif /* IN_RING3 */
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