VirtualBox

Changeset 27232 in vbox for trunk/src


Ignore:
Timestamp:
Mar 9, 2010 9:05:57 PM (15 years ago)
Author:
vboxsync
Message:

Storage/VBoxHDD+DrvVD: implement framework for providing thread synchronization. Additionally some cleanup to resolve a few minor long-standing todos.

Location:
trunk/src/VBox
Files:
9 edited

Legend:

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

    r26916 r27232  
    55
    66/*
    7  * Copyright (C) 2006-2008 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    103103    /** Callback routine */
    104104    PFNVDCOMPLETED              pfnCompleted;
     105
     106    /** Pointer to the optional thread synchronization interface of the disk. */
     107    PVDINTERFACE        pInterfaceThreadSync;
     108    /** Pointer to the optional thread synchronization callbacks of the disk. */
     109    PVDINTERFACETHREADSYNC pInterfaceThreadSyncCallbacks;
    105110} DRVVDSTORAGEBACKEND, *PDRVVDSTORAGEBACKEND;
    106111
     
    263268            pvCallerUser = pvUser;
    264269
     270        /* If thread synchronization is active, then signal the end of the
     271         * this disk read/write operation. */
     272        /** @todo provide a way to determine the type of task (read/write)
     273         * which was completed, see also VBoxHDD.cpp. */
     274        if (RT_UNLIKELY(pStorageBackend->pInterfaceThreadSyncCallbacks))
     275        {
     276            int rc2 = pStorageBackend->pInterfaceThreadSyncCallbacks->pfnFinishWrite(pStorageBackend->pInterfaceThreadSync->pvUser);
     277            AssertRC(rc2);
     278        }
     279
    265280        if (rc == VINF_VD_ASYNC_IO_FINISHED)
    266281        {
     
    273288}
    274289
    275 static DECLCALLBACK(int) drvvdAsyncIOOpen(void *pvUser, const char *pszLocation, unsigned uOpenFlags,
    276                                           PFNVDCOMPLETED pfnCompleted, void **ppStorage)
     290static DECLCALLBACK(int) drvvdAsyncIOOpen(void *pvUser, const char *pszLocation,
     291                                          unsigned uOpenFlags,
     292                                          PFNVDCOMPLETED pfnCompleted,
     293                                          PVDINTERFACE pVDIfsDisk,
     294                                          void **ppStorage)
    277295{
    278296    PVBOXDISK pDrvVD = (PVBOXDISK)pvUser;
     
    284302        pStorageBackend->fSyncIoPending = false;
    285303        pStorageBackend->pfnCompleted   = pfnCompleted;
     304        pStorageBackend->pInterfaceThreadSync = NULL;
     305        pStorageBackend->pInterfaceThreadSyncCallbacks = NULL;
     306
     307        pStorageBackend->pInterfaceThreadSync = VDInterfaceGet(pVDIfsDisk, VDINTERFACETYPE_THREADSYNC);
     308        if (RT_UNLIKELY(pStorageBackend->pInterfaceThreadSync))
     309            pStorageBackend->pInterfaceThreadSyncCallbacks = VDGetInterfaceThreadSync(pStorageBackend->pInterfaceThreadSync);
    286310
    287311        rc = RTSemEventCreate(&pStorageBackend->EventSem);
     
    12651289#endif /* !VBOX_WITH_PDM_ASYNC_COMPLETION */
    12661290        }
     1291
     1292        /** @todo implement and set up the thread synchronization interface
     1293         * if enabled by some CFGM key. If this is enabled then there also
     1294         * needs to be a way for the console object to query the pDisk pointer
     1295         * (so that it can perform the merge in parallel), or alternatively
     1296         * some code needs to be added here which does the merge. The latter
     1297         * might be preferred, as a running merge must block the destruction
     1298         * of the disk, or things will go really wrong. */
    12671299
    12681300        if (RT_SUCCESS(rc))
  • trunk/src/VBox/Devices/Storage/ParallelsHDDCore.cpp

    r26291 r27232  
    66
    77/*
    8  * Copyright (C) 2006-2009 Sun Microsystems, Inc.
     8 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    162162                                                     pImage->pszFilename,
    163163                                                     uOpenFlags,
    164                                                      NULL, &pImage->pvStorage);
     164                                                     NULL,
     165                                                     pImage->pVDIfsDisk,
     166                                                     &pImage->pvStorage);
    165167#endif
    166168
  • trunk/src/VBox/Devices/Storage/RawHDDCore.cpp

    r26291 r27232  
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    141141                                                     pImage->pszFilename,
    142142                                                     uOpenFlags,
    143                                                      NULL, &pImage->pvStorage);
     143                                                     NULL,
     144                                                     pImage->pVDIfsDisk,
     145                                                     &pImage->pvStorage);
    144146#endif
    145147
     
    317319                          PCPDMMEDIAGEOMETRY pPCHSGeometry,
    318320                          PCPDMMEDIAGEOMETRY pLCHSGeometry,
    319                           PFNVMPROGRESS pfnProgress, void *pvUser,
     321                          PFNVDPROGRESS pfnProgress, void *pvUser,
    320322                          unsigned uPercentStart, unsigned uPercentSpan)
    321323{
     
    403405        if (pfnProgress)
    404406        {
    405             rc = pfnProgress(NULL /* WARNING! pVM=NULL  */,
    406                              uPercentStart + uOff * uPercentSpan * 98 / (cbSize * 100),
    407                              pvUser);
     407            rc = pfnProgress(pvUser,
     408                             uPercentStart + uOff * uPercentSpan * 98 / (cbSize * 100));
    408409            if (RT_FAILURE(rc))
    409410                goto out;
     
    413414
    414415    if (RT_SUCCESS(rc) && pfnProgress)
    415         pfnProgress(NULL /* WARNING! pVM=NULL  */,
    416                     uPercentStart + uPercentSpan * 98 / 100, pvUser);
     416        pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100);
    417417
    418418    pImage->cbSize = cbSize;
     
    422422out:
    423423    if (RT_SUCCESS(rc) && pfnProgress)
    424         pfnProgress(NULL /* WARNING! pVM=NULL  */,
    425                     uPercentStart + uPercentSpan, pvUser);
     424        pfnProgress(pvUser, uPercentStart + uPercentSpan);
    426425
    427426    if (RT_FAILURE(rc))
     
    548547    PRAWIMAGE pImage;
    549548
    550     PFNVMPROGRESS pfnProgress = NULL;
     549    PFNVDPROGRESS pfnProgress = NULL;
    551550    void *pvUser = NULL;
    552551    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation,
  • trunk/src/VBox/Devices/Storage/VBoxHDD.cpp

    r27213 r27232  
    55
    66/*
    7  * Copyright (C) 2006-2008 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    127127    /** Pointer to the common interface structure for error reporting. */
    128128    PVDINTERFACE        pInterfaceError;
    129     /** Pointer to the error interface we use if available. */
     129    /** Pointer to the error interface callbacks we use if available. */
    130130    PVDINTERFACEERROR   pInterfaceErrorCallbacks;
     131
     132    /** Pointer to the optional thread synchronization interface. */
     133    PVDINTERFACE        pInterfaceThreadSync;
     134    /** Pointer to the optional thread synchronization callbacks. */
     135    PVDINTERFACETHREADSYNC pInterfaceThreadSyncCallbacks;
    131136
    132137    /** Fallback async interface. */
     
    206211        pDisk->pInterfaceErrorCallbacks->pfnError(pDisk->pInterfaceError->pvUser, rc, RT_SRC_POS_ARGS, pszFormat, va);
    207212    va_end(va);
     213    return rc;
     214}
     215
     216/**
     217 * internal: thread synchronization, start read.
     218 */
     219DECLINLINE(int) vdThreadStartRead(PVBOXHDD pDisk)
     220{
     221    int rc = VINF_SUCCESS;
     222    if (RT_UNLIKELY(pDisk->pInterfaceThreadSyncCallbacks))
     223        rc = pDisk->pInterfaceThreadSyncCallbacks->pfnStartRead(pDisk->pInterfaceThreadSync->pvUser);
     224    return rc;
     225}
     226
     227/**
     228 * internal: thread synchronization, finish read.
     229 */
     230DECLINLINE(int) vdThreadFinishRead(PVBOXHDD pDisk)
     231{
     232    int rc = VINF_SUCCESS;
     233    if (RT_UNLIKELY(pDisk->pInterfaceThreadSyncCallbacks))
     234        rc = pDisk->pInterfaceThreadSyncCallbacks->pfnFinishRead(pDisk->pInterfaceThreadSync->pvUser);
     235    return rc;
     236}
     237
     238/**
     239 * internal: thread synchronization, start write.
     240 */
     241DECLINLINE(int) vdThreadStartWrite(PVBOXHDD pDisk)
     242{
     243    int rc = VINF_SUCCESS;
     244    if (RT_UNLIKELY(pDisk->pInterfaceThreadSyncCallbacks))
     245        rc = pDisk->pInterfaceThreadSyncCallbacks->pfnStartWrite(pDisk->pInterfaceThreadSync->pvUser);
     246    return rc;
     247}
     248
     249/**
     250 * internal: thread synchronization, finish write.
     251 */
     252DECLINLINE(int) vdThreadFinishWrite(PVBOXHDD pDisk)
     253{
     254    int rc = VINF_SUCCESS;
     255    if (RT_UNLIKELY(pDisk->pInterfaceThreadSyncCallbacks))
     256        rc = pDisk->pInterfaceThreadSyncCallbacks->pfnFinishWrite(pDisk->pInterfaceThreadSync->pvUser);
    208257    return rc;
    209258}
     
    744793 */
    745794static int vdAsyncIOOpen(void *pvUser, const char *pszLocation, unsigned uOpenFlags,
    746                          PFNVDCOMPLETED pfnCompleted, void **ppStorage)
     795                         PFNVDCOMPLETED pfnCompleted, PVDINTERFACE pVDIfsDisk,
     796                         void **ppStorage)
    747797{
    748798    PVDIASYNCIOSTORAGE pStorage = (PVDIASYNCIOSTORAGE)RTMemAllocZ(sizeof(VDIASYNCIOSTORAGE));
     
    925975
    926976
    927 
    928977/**
    929978 * Lists all HDD backends and their capabilities in a caller-provided buffer.
    930  *
    931  * @todo this code contains memory leaks, inconsistent (and probably buggy)
    932  * allocation, and it lacks documentation what the caller needs to free.
    933979 *
    934980 * @returns VBox status code.
     
    9821028/**
    9831029 * Lists the capablities of a backend indentified by its name.
    984  * Free all returned names with RTStrFree() when you no longer need them.
    9851030 *
    9861031 * @returns VBox status code.
     
    10551100            pDisk->pInterfaceError = NULL;
    10561101            pDisk->pInterfaceErrorCallbacks = NULL;
     1102            pDisk->pInterfaceThreadSync = NULL;
     1103            pDisk->pInterfaceThreadSyncCallbacks = NULL;
    10571104
    10581105            pDisk->pInterfaceError = VDInterfaceGet(pVDIfsDisk, VDINTERFACETYPE_ERROR);
    10591106            if (pDisk->pInterfaceError)
    10601107                pDisk->pInterfaceErrorCallbacks = VDGetInterfaceError(pDisk->pInterfaceError);
     1108
     1109            pDisk->pInterfaceThreadSync = VDInterfaceGet(pVDIfsDisk, VDINTERFACETYPE_THREADSYNC);
     1110            if (pDisk->pInterfaceThreadSync)
     1111                pDisk->pInterfaceThreadSyncCallbacks = VDGetInterfaceThreadSync(pDisk->pInterfaceThreadSync);
    10611112
    10621113            /* Use the fallback async I/O interface if the caller doesn't provide one. */
     
    12281279{
    12291280    int rc = VINF_SUCCESS;
     1281    int rc2;
     1282    bool fLockWrite = false;
    12301283    PVDIMAGE pImage = NULL;
    12311284
    12321285    LogFlowFunc(("pDisk=%#p pszBackend=\"%s\" pszFilename=\"%s\" uOpenFlags=%#x, pVDIfsImage=%#p\n",
    12331286                 pDisk, pszBackend, pszFilename, uOpenFlags, pVDIfsImage));
     1287
    12341288    do
    12351289    {
     
    13031357        }
    13041358
    1305         unsigned uImageFlags;
    1306         uImageFlags = pImage->Backend->pfnGetImageFlags(pImage->pvBackendData);
     1359        /* Lock disk for writing, as we modify pDisk information below. */
     1360        rc2 = vdThreadStartWrite(pDisk);
     1361        AssertRC(rc2);
     1362        fLockWrite = true;
     1363
    13071364        /* Check image type. As the image itself has only partial knowledge
    13081365         * whether it's a base image or not, this info is derived here. The
     
    13101367         * diff images. Some image formats don't distinguish between normal
    13111368         * and diff images, so this must be corrected here. */
     1369        unsigned uImageFlags;
     1370        uImageFlags = pImage->Backend->pfnGetImageFlags(pImage->pvBackendData);
    13121371        if (RT_FAILURE(rc))
    13131372            uImageFlags = VD_IMAGE_FLAGS_NONE;
     
    13411400        /** @todo optionally check UUIDs */
    13421401
    1343         int rc2;
    1344 
    13451402        /* Cache disk information. */
    13461403        pDisk->cbSize = pImage->Backend->pfnGetSize(pImage->pvBackendData);
     
    14061463        }
    14071464    } while (0);
     1465
     1466    if (RT_UNLIKELY(fLockWrite))
     1467    {
     1468        rc2 = vdThreadFinishWrite(pDisk);
     1469        AssertRC(rc2);
     1470    }
    14081471
    14091472    if (RT_FAILURE(rc))
     
    14481511{
    14491512    int rc = VINF_SUCCESS;
     1513    int rc2;
     1514    bool fLockWrite = false, fLockRead = false;
    14501515    PVDIMAGE pImage = NULL;
    14511516    RTUUID uuid;
     
    15081573                           rc = VERR_INVALID_PARAMETER);
    15091574
    1510         /* Check state. */
     1575        /* Check state. Needs a temporary read lock. Holding the write lock
     1576         * all the time would be blocking other activities for too long. */
     1577        rc2 = vdThreadStartRead(pDisk);
     1578        AssertRC(rc2);
     1579        fLockRead = true;
    15111580        AssertMsgBreakStmt(pDisk->cImages == 0,
    15121581                           ("Create base image cannot be done with other images open\n"),
    15131582                           rc = VERR_VD_INVALID_STATE);
     1583        rc2 = vdThreadFinishRead(pDisk);
     1584        AssertRC(rc2);
     1585        fLockRead = false;
    15141586
    15151587        /* Set up image descriptor. */
     
    15731645                pImage->uOpenFlags |= VD_OPEN_FLAGS_HONOR_SAME;
    15741646
     1647            /* Lock disk for writing, as we modify pDisk information below. */
     1648            rc2 = vdThreadStartWrite(pDisk);
     1649            AssertRC(rc2);
     1650            fLockWrite = true;
     1651
    15751652            /** @todo optionally check UUIDs */
    15761653
    1577             int rc2;
    1578 
     1654            /* Re-check state, as the lock wasn't held and another image
     1655             * creation call could have been done by another thread. */
     1656            AssertMsgStmt(pDisk->cImages == 0,
     1657                          ("Create base image cannot be done with other images open\n"),
     1658                          rc = VERR_VD_INVALID_STATE);
     1659        }
     1660
     1661        if (RT_SUCCESS(rc))
     1662        {
    15791663            /* Cache disk information. */
    15801664            pDisk->cbSize = pImage->Backend->pfnGetSize(pImage->pvBackendData);
     
    16121696                pDisk->LCHSGeometry.cSectors = RT_MIN(pDisk->LCHSGeometry.cSectors, 63);
    16131697            }
    1614         }
    1615 
    1616         if (RT_SUCCESS(rc))
    1617         {
     1698
    16181699            /* Image successfully opened, make it the last image. */
    16191700            vdAddImageToList(pDisk, pImage);
     
    16311712    } while (0);
    16321713
     1714    if (RT_UNLIKELY(fLockWrite))
     1715    {
     1716        rc2 = vdThreadFinishWrite(pDisk);
     1717        AssertRC(rc2);
     1718    }
     1719    else if (RT_UNLIKELY(fLockRead))
     1720    {
     1721        rc2 = vdThreadFinishRead(pDisk);
     1722        AssertRC(rc2);
     1723    }
     1724
    16331725    if (RT_FAILURE(rc))
    16341726    {
     
    16421734
    16431735    if (RT_SUCCESS(rc) && pCbProgress && pCbProgress->pfnProgress)
    1644         pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100,
    1645                                  pIfProgress->pvUser);
     1736        pCbProgress->pfnProgress(pIfProgress, 100);
    16461737
    16471738    LogFlowFunc(("returns %Rrc\n", rc));
     
    16731764{
    16741765    int rc = VINF_SUCCESS;
     1766    int rc2;
     1767    bool fLockWrite = false, fLockRead = false;
    16751768    PVDIMAGE pImage = NULL;
    16761769    RTUUID uuid;
     
    17141807                           rc = VERR_INVALID_PARAMETER);
    17151808
    1716         /* Check state. */
     1809        /* Check state. Needs a temporary read lock. Holding the write lock
     1810         * all the time would be blocking other activities for too long. */
     1811        rc2 = vdThreadStartRead(pDisk);
     1812        AssertRC(rc2);
     1813        fLockRead = true;
    17171814        AssertMsgBreakStmt(pDisk->cImages != 0,
    17181815                           ("Create diff image cannot be done without other images open\n"),
    17191816                           rc = VERR_VD_INVALID_STATE);
     1817        rc2 = vdThreadFinishRead(pDisk);
     1818        AssertRC(rc2);
     1819        fLockRead = false;
    17201820
    17211821        /* Set up image descriptor. */
     
    17701870                                        &pImage->pvBackendData);
    17711871
    1772         if (RT_SUCCESS(rc) && pDisk->cImages != 0)
     1872        if (RT_SUCCESS(rc))
    17731873        {
    17741874            pImage->uImageFlags = uImageFlags;
     1875
     1876            /* Lock disk for writing, as we modify pDisk information below. */
     1877            rc2 = vdThreadStartWrite(pDisk);
     1878            AssertRC(rc2);
     1879            fLockWrite = true;
    17751880
    17761881            /* Switch previous image to read-only mode. */
     
    17821887                rc = pDisk->pLast->Backend->pfnSetOpenFlags(pDisk->pLast->pvBackendData, uOpenFlagsPrevImg);
    17831888            }
     1889
     1890            /** @todo optionally check UUIDs */
     1891
     1892            /* Re-check state, as the lock wasn't held and another image
     1893             * creation call could have been done by another thread. */
     1894            AssertMsgStmt(pDisk->cImages != 0,
     1895                          ("Create diff image cannot be done without other images open\n"),
     1896                          rc = VERR_VD_INVALID_STATE);
    17841897        }
    17851898
     
    17881901            RTUUID Uuid;
    17891902            RTTIMESPEC ts;
    1790             int rc2;
    17911903
    17921904            if (pParentUuid && !RTUuidIsNull(pParentUuid))
     
    18171929        if (RT_SUCCESS(rc))
    18181930        {
    1819             /** @todo optionally check UUIDs */
    1820         }
    1821 
    1822         if (RT_SUCCESS(rc))
    1823         {
    18241931            /* Image successfully opened, make it the last image. */
    18251932            vdAddImageToList(pDisk, pImage);
     
    18301937        {
    18311938            /* Error detected, but image opened. Close and delete image. */
    1832             int rc2;
    18331939            rc2 = pImage->Backend->pfnClose(pImage->pvBackendData, true);
    18341940            AssertRC(rc2);
     
    18371943    } while (0);
    18381944
     1945    if (RT_UNLIKELY(fLockWrite))
     1946    {
     1947        rc2 = vdThreadFinishWrite(pDisk);
     1948        AssertRC(rc2);
     1949    }
     1950    else if (RT_UNLIKELY(fLockRead))
     1951    {
     1952        rc2 = vdThreadFinishRead(pDisk);
     1953        AssertRC(rc2);
     1954    }
     1955
    18391956    if (RT_FAILURE(rc))
    18401957    {
     
    18481965
    18491966    if (RT_SUCCESS(rc) && pCbProgress && pCbProgress->pfnProgress)
    1850         pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100,
    1851                                  pIfProgress->pvUser);
     1967        pCbProgress->pfnProgress(pIfProgress, 100);
    18521968
    18531969    LogFlowFunc(("returns %Rrc\n", rc));
     
    18731989{
    18741990    int rc = VINF_SUCCESS;
     1991    int rc2;
     1992    bool fLockWrite = false, fLockRead = false;
    18751993    void *pvBuf = NULL;
    18761994
     
    18902008        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
    18912009
     2010        rc2 = vdThreadStartRead(pDisk);
     2011        AssertRC(rc2);
     2012        fLockRead = true;
    18922013        PVDIMAGE pImageFrom = vdGetImageByNumber(pDisk, nImageFrom);
    18932014        PVDIMAGE pImageTo = vdGetImageByNumber(pDisk, nImageTo);
     
    19122033        /* Get size of destination image. */
    19132034        uint64_t cbSize = pImageTo->Backend->pfnGetSize(pImageTo->pvBackendData);
     2035        rc2 = vdThreadFinishRead(pDisk);
     2036        AssertRC(rc2);
     2037        fLockRead = false;
    19142038
    19152039        /* Allocate tmp buffer. */
     
    19232047        /* Merging is done directly on the images itself. This potentially
    19242048         * causes trouble if the disk is full in the middle of operation. */
    1925         /** @todo write alternative implementation which works with temporary
    1926          * images (which is safer, but requires even more space). Also has the
    1927          * drawback that merging into a raw disk parent simply isn't possible
    1928          * this way (but in that case disk full isn't really a problem). */
    19292049        if (nImageFrom < nImageTo)
    19302050        {
     
    19372057            {
    19382058                size_t cbThisRead = RT_MIN(VD_MERGE_BUFFER_SIZE, cbRemaining);
     2059
     2060                /* Need to hold the write lock during a read-write operation. */
     2061                rc2 = vdThreadStartWrite(pDisk);
     2062                AssertRC(rc2);
     2063                fLockWrite = true;
     2064
    19392065                rc = pImageTo->Backend->pfnRead(pImageTo->pvBackendData,
    19402066                                                uOffset, pvBuf, cbThisRead,
     
    19722098                    break;
    19732099
     2100                rc2 = vdThreadFinishWrite(pDisk);
     2101                AssertRC(rc2);
     2102                fLockWrite = false;
     2103
    19742104                uOffset += cbThisRead;
    19752105                cbRemaining -= cbThisRead;
     
    19772107                if (pCbProgress && pCbProgress->pfnProgress)
    19782108                {
    1979                     rc = pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */,
    1980                                                   uOffset * 99 / cbSize,
    1981                                                   pIfProgress->pvUser);
     2109                    rc = pCbProgress->pfnProgress(pIfProgress->pvUser,
     2110                                                  uOffset * 99 / cbSize);
    19822111                    if (RT_FAILURE(rc))
    19832112                        break;
     
    20202149                size_t cbThisRead = RT_MIN(VD_MERGE_BUFFER_SIZE, cbRemaining);
    20212150                rc = VERR_VD_BLOCK_FREE;
     2151
     2152                /* Need to hold the write lock during a read-write operation. */
     2153                rc2 = vdThreadStartWrite(pDisk);
     2154                AssertRC(rc2);
     2155                fLockWrite = true;
     2156
    20222157                /* Search for image with allocated block. Do not attempt to
    20232158                 * read more than the previous reads marked as valid. Otherwise
     
    20452180                    rc = VINF_SUCCESS;
    20462181
     2182                rc2 = vdThreadFinishWrite(pDisk);
     2183                AssertRC(rc2);
     2184                fLockWrite = true;
     2185
    20472186                uOffset += cbThisRead;
    20482187                cbRemaining -= cbThisRead;
     
    20502189                if (pCbProgress && pCbProgress->pfnProgress)
    20512190                {
    2052                     rc = pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */,
    2053                                                   uOffset * 99 / cbSize,
    2054                                                   pIfProgress->pvUser);
     2191                    rc = pCbProgress->pfnProgress(pIfProgress->pvUser,
     2192                                                  uOffset * 99 / cbSize);
    20552193                    if (RT_FAILURE(rc))
    20562194                        break;
     
    20582196            } while (uOffset < cbSize);
    20592197        }
     2198
     2199        /* Need to hold the write lock while finishing the merge. */
     2200        rc2 = vdThreadStartWrite(pDisk);
     2201        AssertRC(rc2);
     2202        fLockWrite = true;
    20602203
    20612204        /* Update parent UUID so that image chain is consistent. */
     
    21372280    } while (0);
    21382281
     2282    if (RT_UNLIKELY(fLockWrite))
     2283    {
     2284        rc2 = vdThreadFinishWrite(pDisk);
     2285        AssertRC(rc2);
     2286    }
     2287    else if (RT_UNLIKELY(fLockRead))
     2288    {
     2289        rc2 = vdThreadFinishRead(pDisk);
     2290        AssertRC(rc2);
     2291    }
     2292
    21392293    if (pvBuf)
    21402294        RTMemTmpFree(pvBuf);
    21412295
    21422296    if (RT_SUCCESS(rc) && pCbProgress && pCbProgress->pfnProgress)
    2143         pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100,
    2144                                  pIfProgress->pvUser);
     2297        pCbProgress->pfnProgress(pIfProgress->pvUser, 100);
    21452298
    21462299    LogFlowFunc(("returns %Rrc\n", rc));
     
    21852338                         PVDINTERFACE pDstVDIfsOperation)
    21862339{
    2187     int rc, rc2 = VINF_SUCCESS;
     2340    int rc = VINF_SUCCESS;
     2341    int rc2;
     2342    bool fLockReadFrom = false, fLockWriteFrom = false, fLockWriteTo = false;
    21882343    void *pvBuf = NULL;
    21892344    PVDIMAGE pImageTo = NULL;
     
    22112366                  ("u32Signature=%08x\n", pDiskFrom->u32Signature));
    22122367
     2368        rc2 = vdThreadStartRead(pDiskFrom);
     2369        AssertRC(rc2);
     2370        fLockReadFrom = true;
    22132371        PVDIMAGE pImageFrom = vdGetImageByNumber(pDiskFrom, nImage);
    22142372        AssertPtrBreakStmt(pImageFrom, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    22252383                &&  !RTStrICmp(pszBackend, pImageFrom->Backend->pszBackendName))
    22262384            {
     2385                rc2 = vdThreadFinishRead(pDiskFrom);
     2386                AssertRC(rc2);
     2387                fLockReadFrom = false;
     2388
     2389                rc2 = vdThreadStartWrite(pDiskFrom);
     2390                AssertRC(rc2);
     2391                fLockWriteFrom = true;
    22272392                rc = pImageFrom->Backend->pfnRename(pImageFrom->pvBackendData, pszFilename ? pszFilename : pImageFrom->pszFilename);
    22282393                break;
     
    22882453        uOpenFlagsFrom = pImageFrom->Backend->pfnGetOpenFlags(pImageFrom->pvBackendData);
    22892454
     2455        rc2 = vdThreadFinishRead(pDiskFrom);
     2456        AssertRC(rc2);
     2457        fLockReadFrom = false;
     2458
    22902459        if (pszFilename)
    22912460        {
     
    22962465            /** @todo replace the VDCreateDiff/VDCreateBase calls by direct
    22972466             * calls to the backend. Unifies the code and reduces the API
    2298              * dependencies. */
     2467             * dependencies. Would also make the synchronization explicit. */
    22992468            if (uImageFlags & VD_IMAGE_FLAGS_DIFF)
    23002469            {
    23012470                rc = VDCreateDiff(pDiskTo, pszBackend, pszFilename, uImageFlags,
    23022471                                  szComment, &ImageUuid, &ParentUuid, uOpenFlagsFrom & ~VD_OPEN_FLAGS_READONLY, NULL, NULL);
     2472
     2473                rc2 = vdThreadStartWrite(pDiskTo);
     2474                AssertRC(rc2);
     2475                fLockWriteTo = true;
    23032476            } else {
    2304                 /** @todo Please, review this! It's an ugly hack I think... */
     2477                /** @todo hack to force creation of a fixed image for
     2478                 * the RAW backend, which can't handle anything else. */
    23052479                if (!RTStrICmp(pszBackend, "RAW"))
    23062480                    uImageFlags |= VD_IMAGE_FLAGS_FIXED;
     
    23252499                                  &PCHSGeometryFrom, &LCHSGeometryFrom,
    23262500                                  NULL, uOpenFlagsFrom & ~VD_OPEN_FLAGS_READONLY, NULL, NULL);
     2501                   
     2502                rc2 = vdThreadStartWrite(pDiskTo);
     2503                AssertRC(rc2);
     2504                fLockWriteTo = true;
     2505
    23272506                if (RT_SUCCESS(rc) && !RTUuidIsNull(&ImageUuid))
    23282507                     pDiskTo->pLast->Backend->pfnSetUuid(pDiskTo->pLast->pvBackendData, &ImageUuid);
     
    23552534        }
    23562535
     2536        rc2 = vdThreadFinishWrite(pDiskTo);
     2537        AssertRC(rc2);
     2538        fLockWriteTo = false;
     2539
    23572540        /* Allocate tmp buffer. */
    23582541        pvBuf = RTMemTmpAlloc(VD_MERGE_BUFFER_SIZE);
     
    23702553        {
    23712554            size_t cbThisRead = RT_MIN(VD_MERGE_BUFFER_SIZE, cbRemaining);
     2555
     2556            /* Note that we don't attempt to synchronize cross-disk accesses.
     2557             * It wouldn't be very difficult to do, just the lock order would
     2558             * need to be defined somehow to prevent deadlocks. Postpone such
     2559             * magic as there is no use case for this. */
     2560
     2561            rc2 = vdThreadStartRead(pDiskFrom);
     2562            AssertRC(rc2);
     2563            fLockReadFrom = true;
    23722564
    23732565            rc = vdReadHelper(pDiskFrom, pImageFrom, NULL, uOffset, pvBuf,
     
    23762568                break;
    23772569
     2570            rc2 = vdThreadFinishRead(pDiskFrom);
     2571            AssertRC(rc2);
     2572            fLockReadFrom = false;
     2573
     2574            rc2 = vdThreadStartWrite(pDiskTo);
     2575            AssertRC(rc2);
     2576            fLockWriteTo = true;
     2577
    23782578            rc = vdWriteHelper(pDiskTo, pImageTo, NULL, uOffset, pvBuf,
    23792579                               cbThisRead);
     
    23812581                break;
    23822582
     2583            rc2 = vdThreadFinishWrite(pDiskTo);
     2584            AssertRC(rc2);
     2585            fLockWriteTo = false;
     2586
    23832587            uOffset += cbThisRead;
    23842588            cbRemaining -= cbThisRead;
     
    23862590            if (pCbProgress && pCbProgress->pfnProgress)
    23872591            {
    2388                 rc = pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */,
    2389                                               uOffset * 99 / cbSize,
    2390                                               pIfProgress->pvUser);
     2592                rc = pCbProgress->pfnProgress(pIfProgress->pvUser,
     2593                                              uOffset * 99 / cbSize);
    23912594                if (RT_FAILURE(rc))
    23922595                    break;
     
    23942597            if (pDstCbProgress && pDstCbProgress->pfnProgress)
    23952598            {
    2396                 rc = pDstCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */,
    2397                                                  uOffset * 99 / cbSize,
    2398                                                  pDstIfProgress->pvUser);
     2599                rc = pDstCbProgress->pfnProgress(pDstIfProgress->pvUser,
     2600                                                 uOffset * 99 / cbSize);
    23992601                if (RT_FAILURE(rc))
    24002602                    break;
     
    24042606        if (RT_SUCCESS(rc))
    24052607        {
     2608            rc2 = vdThreadStartWrite(pDiskTo);
     2609            AssertRC(rc2);
     2610            fLockWriteTo = true;
     2611
    24062612            /* Only set modification UUID if it is non-null, since the source
    24072613             * backend might not provide a valid modification UUID. */
     
    24182624    if (RT_FAILURE(rc) && pImageTo && pszFilename)
    24192625    {
     2626        /* Take the write lock only if it is not taken. Not worth making the
     2627         * above code even more complicated. */
     2628        if (RT_UNLIKELY(!fLockWriteTo))
     2629        {
     2630            rc2 = vdThreadStartWrite(pDiskTo);
     2631            AssertRC(rc2);
     2632            fLockWriteTo = true;
     2633        }
    24202634        /* Error detected, but new image created. Remove image from list. */
    24212635        vdRemoveImageFromList(pDiskTo, pImageTo);
     
    24332647    }
    24342648
     2649    if (RT_UNLIKELY(fLockWriteTo))
     2650    {
     2651        rc2 = vdThreadFinishWrite(pDiskTo);
     2652        AssertRC(rc2);
     2653    }
     2654    if (RT_UNLIKELY(fLockWriteFrom))
     2655    {
     2656        rc2 = vdThreadFinishWrite(pDiskFrom);
     2657        AssertRC(rc2);
     2658    }
     2659    else if (RT_UNLIKELY(fLockReadFrom))
     2660    {
     2661        rc2 = vdThreadFinishRead(pDiskFrom);
     2662        AssertRC(rc2);
     2663    }
     2664
    24352665    if (pvBuf)
    24362666        RTMemTmpFree(pvBuf);
     
    24392669    {
    24402670        if (pCbProgress && pCbProgress->pfnProgress)
    2441             pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100,
    2442                                      pIfProgress->pvUser);
     2671            pCbProgress->pfnProgress(pIfProgress->pvUser, 100);
    24432672        if (pDstCbProgress && pDstCbProgress->pfnProgress)
    2444             pDstCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100,
    2445                                         pDstIfProgress->pvUser);
     2673            pDstCbProgress->pfnProgress(pDstIfProgress->pvUser, 100);
    24462674    }
    24472675
     
    24692697                            PVDINTERFACE pVDIfsOperation)
    24702698{
    2471     int rc;
     2699    int rc = VINF_SUCCESS;
     2700    int rc2;
     2701    bool fLockRead = false, fLockWrite = false;
    24722702    void *pvBuf = NULL;
    24732703    void *pvTmp = NULL;
     
    24882718        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE,
    24892719                  ("u32Signature=%08x\n", pDisk->u32Signature));
     2720
     2721        rc2 = vdThreadStartRead(pDisk);
     2722        AssertRC(rc2);
     2723        fLockRead = true;
    24902724
    24912725        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     
    25212755        }
    25222756
     2757        rc2 = vdThreadFinishRead(pDisk);
     2758        AssertRC(rc2);
     2759        fLockRead = false;
     2760
     2761        rc2 = vdThreadStartWrite(pDisk);
     2762        AssertRC(rc2);
     2763        fLockWrite = true;
     2764
    25232765        rc = pImage->Backend->pfnCompact(pImage->pvBackendData,
    25242766                                         0, 99,
     2767                                         pDisk->pVDIfsDisk,
     2768                                         pImage->pVDIfsImage,
    25252769                                         pVDIfsOperation);
    25262770    } while (0);
     2771
     2772    if (RT_UNLIKELY(fLockWrite))
     2773    {
     2774        rc2 = vdThreadFinishWrite(pDisk);
     2775        AssertRC(rc2);
     2776    }
     2777    else if (RT_UNLIKELY(fLockRead))
     2778    {
     2779        rc2 = vdThreadFinishRead(pDisk);
     2780        AssertRC(rc2);
     2781    }
    25272782
    25282783    if (pvBuf)
     
    25342789    {
    25352790        if (pCbProgress && pCbProgress->pfnProgress)
    2536             pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100,
    2537                                      pIfProgress->pvUser);
     2791            pCbProgress->pfnProgress(pIfProgress->pvUser, 100);
    25382792    }
    25392793
     
    25442798/**
    25452799 * Closes the last opened image file in HDD container.
    2546  * If previous image file was opened in read-only mode (that is normal) and closing image
    2547  * was opened in read-write mode (the whole disk was in read-write mode) - the previous image
    2548  * will be reopened in read/write mode.
     2800 * If previous image file was opened in read-only mode (the normal case) and
     2801 * the last opened image is in read-write mode then the previous image will be
     2802 * reopened in read/write mode.
    25492803 *
    25502804 * @returns VBox status code.
     
    25562810{
    25572811    int rc = VINF_SUCCESS;
     2812    int rc2;
     2813    bool fLockWrite = false;
    25582814
    25592815    LogFlowFunc(("pDisk=%#p fDelete=%d\n", pDisk, fDelete));
     
    25632819        AssertPtrBreakStmt(pDisk, rc = VERR_INVALID_PARAMETER);
    25642820        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     2821
     2822        /* Not worth splitting this up into a read lock phase and write
     2823         * lock phase, as closing an image is a relatively fast operation
     2824         * dominated by the part which needs the write lock. */
     2825        rc2 = vdThreadStartWrite(pDisk);
     2826        AssertRC(rc2);
     2827        fLockWrite = true;
    25652828
    25662829        PVDIMAGE pImage = pDisk->pLast;
     
    25932856        }
    25942857
    2595         int rc2;
    2596 
    25972858        /* Cache disk information. */
    25982859        pDisk->cbSize = pImage->Backend->pfnGetSize(pImage->pvBackendData);
     
    26322893    } while (0);
    26332894
     2895    if (RT_UNLIKELY(fLockWrite))
     2896    {
     2897        rc2 = vdThreadFinishWrite(pDisk);
     2898        AssertRC(rc2);
     2899    }
     2900
    26342901    LogFlowFunc(("returns %Rrc\n", rc));
    26352902    return rc;
     
    26452912{
    26462913    int rc = VINF_SUCCESS;
     2914    int rc2;
     2915    bool fLockWrite = false;
    26472916
    26482917    LogFlowFunc(("pDisk=%#p\n", pDisk));
     
    26522921        AssertPtrBreakStmt(pDisk, rc = VERR_INVALID_PARAMETER);
    26532922        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     2923
     2924        /* Lock the entire operation. */
     2925        rc2 = vdThreadStartWrite(pDisk);
     2926        AssertRC(rc2);
     2927        fLockWrite = true;
    26542928
    26552929        PVDIMAGE pImage = pDisk->pLast;
     
    26712945    } while (0);
    26722946
     2947    if (RT_UNLIKELY(fLockWrite))
     2948    {
     2949        rc2 = vdThreadFinishWrite(pDisk);
     2950        AssertRC(rc2);
     2951    }
     2952
    26732953    LogFlowFunc(("returns %Rrc\n", rc));
    26742954    return rc;
     
    26882968                         size_t cbRead)
    26892969{
    2690     int rc;
     2970    int rc = VINF_SUCCESS;
     2971    int rc2;
     2972    bool fLockRead = false;
    26912973
    26922974    LogFlowFunc(("pDisk=%#p uOffset=%llu pvBuf=%p cbRead=%zu\n",
     
    27052987                           ("cbRead=%zu\n", cbRead),
    27062988                           rc = VERR_INVALID_PARAMETER);
     2989
     2990        rc2 = vdThreadStartRead(pDisk);
     2991        AssertRC(rc2);
     2992        fLockRead = true;
     2993
    27072994        AssertMsgBreakStmt(uOffset + cbRead <= pDisk->cbSize,
    27082995                           ("uOffset=%llu cbRead=%zu pDisk->cbSize=%llu\n",
     
    27153002        rc = vdReadHelper(pDisk, pImage, NULL, uOffset, pvBuf, cbRead);
    27163003    } while (0);
     3004
     3005    if (RT_UNLIKELY(fLockRead))
     3006    {
     3007        rc2 = vdThreadFinishRead(pDisk);
     3008        AssertRC(rc2);
     3009    }
    27173010
    27183011    LogFlowFunc(("returns %Rrc\n", rc));
     
    27353028{
    27363029    int rc = VINF_SUCCESS;
     3030    int rc2;
     3031    bool fLockWrite = false;
    27373032
    27383033    LogFlowFunc(("pDisk=%#p uOffset=%llu pvBuf=%p cbWrite=%zu\n",
     
    27513046                           ("cbWrite=%zu\n", cbWrite),
    27523047                           rc = VERR_INVALID_PARAMETER);
     3048
     3049        rc2 = vdThreadStartWrite(pDisk);
     3050        AssertRC(rc2);
     3051        fLockWrite = true;
     3052
    27533053        AssertMsgBreakStmt(uOffset + cbWrite <= pDisk->cbSize,
    27543054                           ("uOffset=%llu cbWrite=%zu pDisk->cbSize=%llu\n",
     
    27633063    } while (0);
    27643064
     3065    if (RT_UNLIKELY(fLockWrite))
     3066    {
     3067        rc2 = vdThreadFinishWrite(pDisk);
     3068        AssertRC(rc2);
     3069    }
     3070
    27653071    LogFlowFunc(("returns %Rrc\n", rc));
    27663072    return rc;
     
    27773083{
    27783084    int rc = VINF_SUCCESS;
     3085    int rc2;
     3086    bool fLockWrite = false;
    27793087
    27803088    LogFlowFunc(("pDisk=%#p\n", pDisk));
     
    27853093        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
    27863094
     3095        rc2 = vdThreadStartWrite(pDisk);
     3096        AssertRC(rc2);
     3097        fLockWrite = true;
     3098
    27873099        PVDIMAGE pImage = pDisk->pLast;
    27883100        AssertPtrBreakStmt(pImage, rc = VERR_VD_NOT_OPENED);
     
    27923104    } while (0);
    27933105
     3106    if (RT_UNLIKELY(fLockWrite))
     3107    {
     3108        rc2 = vdThreadFinishWrite(pDisk);
     3109        AssertRC(rc2);
     3110    }
     3111
    27943112    LogFlowFunc(("returns %Rrc\n", rc));
    27953113    return rc;
     
    28053123{
    28063124    unsigned cImages;
     3125    int rc2;
     3126    bool fLockRead = false;
    28073127
    28083128    LogFlowFunc(("pDisk=%#p\n", pDisk));
     
    28133133        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
    28143134
     3135        rc2 = vdThreadStartRead(pDisk);
     3136        AssertRC(rc2);
     3137        fLockRead = true;
     3138
    28153139        cImages = pDisk->cImages;
    28163140    } while (0);
     3141
     3142    if (RT_UNLIKELY(fLockRead))
     3143    {
     3144        rc2 = vdThreadFinishRead(pDisk);
     3145        AssertRC(rc2);
     3146    }
    28173147
    28183148    LogFlowFunc(("returns %u\n", cImages));
     
    28303160{
    28313161    bool fReadOnly;
     3162    int rc2;
     3163    bool fLockRead = false;
    28323164
    28333165    LogFlowFunc(("pDisk=%#p\n", pDisk));
     
    28373169        AssertPtrBreakStmt(pDisk, fReadOnly = false);
    28383170        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     3171
     3172        rc2 = vdThreadStartRead(pDisk);
     3173        AssertRC(rc2);
     3174        fLockRead = true;
    28393175
    28403176        PVDIMAGE pImage = pDisk->pLast;
     
    28463182    } while (0);
    28473183
     3184    if (RT_UNLIKELY(fLockRead))
     3185    {
     3186        rc2 = vdThreadFinishRead(pDisk);
     3187        AssertRC(rc2);
     3188    }
     3189
    28483190    LogFlowFunc(("returns %d\n", fReadOnly));
    28493191    return fReadOnly;
     
    28613203{
    28623204    uint64_t cbSize;
     3205    int rc2;
     3206    bool fLockRead = false;
    28633207
    28643208    LogFlowFunc(("pDisk=%#p nImage=%u\n", pDisk, nImage));
     
    28683212        AssertPtrBreakStmt(pDisk, cbSize = 0);
    28693213        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     3214
     3215        rc2 = vdThreadStartRead(pDisk);
     3216        AssertRC(rc2);
     3217        fLockRead = true;
    28703218
    28713219        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     
    28743222    } while (0);
    28753223
     3224    if (RT_UNLIKELY(fLockRead))
     3225    {
     3226        rc2 = vdThreadFinishRead(pDisk);
     3227        AssertRC(rc2);
     3228    }
     3229
    28763230    LogFlowFunc(("returns %llu\n", cbSize));
    28773231    return cbSize;
     
    28893243{
    28903244    uint64_t cbSize;
     3245    int rc2;
     3246    bool fLockRead = false;
    28913247
    28923248    LogFlowFunc(("pDisk=%#p nImage=%u\n", pDisk, nImage));
     
    28963252        AssertPtrBreakStmt(pDisk, cbSize = 0);
    28973253        AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     3254
     3255        rc2 = vdThreadStartRead(pDisk);
     3256        AssertRC(rc2);
     3257        fLockRead = true;
    28983258
    28993259        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     
    29013261        cbSize = pImage->Backend->pfnGetFileSize(pImage->pvBackendData);
    29023262    } while (0);
     3263
     3264    if (RT_UNLIKELY(fLockRead))
     3265    {
     3266        rc2 = vdThreadFinishRead(pDisk);
     3267        AssertRC(rc2);
     3268    }
    29033269
    29043270    LogFlowFunc(("returns %llu\n", cbSize));
     
    29203286{
    29213287    int rc = VINF_SUCCESS;
     3288    int rc2;
     3289    bool fLockRead = false;
    29223290
    29233291    LogFlowFunc(("pDisk=%#p nImage=%u pPCHSGeometry=%#p\n",
     
    29333301                           ("pPCHSGeometry=%#p\n", pPCHSGeometry),
    29343302                           rc = VERR_INVALID_PARAMETER);
     3303
     3304        rc2 = vdThreadStartRead(pDisk);
     3305        AssertRC(rc2);
     3306        fLockRead = true;
    29353307
    29363308        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     
    29493321                                                     pPCHSGeometry);
    29503322    } while (0);
     3323
     3324    if (RT_UNLIKELY(fLockRead))
     3325    {
     3326        rc2 = vdThreadFinishRead(pDisk);
     3327        AssertRC(rc2);
     3328    }
    29513329
    29523330    LogFlowFunc(("%s: %Rrc (PCHS=%u/%u/%u)\n", __FUNCTION__, rc,
     
    29723350{
    29733351    int rc = VINF_SUCCESS;
     3352    int rc2;
     3353    bool fLockWrite = false;
    29743354
    29753355    LogFlowFunc(("pDisk=%#p nImage=%u pPCHSGeometry=%#p PCHS=%u/%u/%u\n",
     
    29903370                            pPCHSGeometry->cSectors),
    29913371                           rc = VERR_INVALID_PARAMETER);
     3372
     3373        rc2 = vdThreadStartWrite(pDisk);
     3374        AssertRC(rc2);
     3375        fLockWrite = true;
    29923376
    29933377        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     
    30463430    } while (0);
    30473431
     3432    if (RT_UNLIKELY(fLockWrite))
     3433    {
     3434        rc2 = vdThreadFinishWrite(pDisk);
     3435        AssertRC(rc2);
     3436    }
     3437
    30483438    LogFlowFunc(("returns %Rrc\n", rc));
    30493439    return rc;
     
    30643454{
    30653455    int rc = VINF_SUCCESS;
     3456    int rc2;
     3457    bool fLockRead = false;
    30663458
    30673459    LogFlowFunc(("pDisk=%#p nImage=%u pLCHSGeometry=%#p\n",
     
    30773469                           ("pLCHSGeometry=%#p\n", pLCHSGeometry),
    30783470                           rc = VERR_INVALID_PARAMETER);
     3471
     3472        rc2 = vdThreadStartRead(pDisk);
     3473        AssertRC(rc2);
     3474        fLockRead = true;
    30793475
    30803476        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     
    30933489                                                     pLCHSGeometry);
    30943490    } while (0);
     3491
     3492    if (RT_UNLIKELY(fLockRead))
     3493    {
     3494        rc2 = vdThreadFinishRead(pDisk);
     3495        AssertRC(rc2);
     3496    }
    30953497
    30963498    LogFlowFunc((": %Rrc (LCHS=%u/%u/%u)\n", rc,
     
    31163518{
    31173519    int rc = VINF_SUCCESS;
     3520    int rc2;
     3521    bool fLockWrite = false;
    31183522
    31193523    LogFlowFunc(("pDisk=%#p nImage=%u pLCHSGeometry=%#p LCHS=%u/%u/%u\n",
     
    31343538                            pLCHSGeometry->cSectors),
    31353539                           rc = VERR_INVALID_PARAMETER);
     3540
     3541        rc2 = vdThreadStartWrite(pDisk);
     3542        AssertRC(rc2);
     3543        fLockWrite = true;
    31363544
    31373545        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     
    31903598    } while (0);
    31913599
     3600    if (RT_UNLIKELY(fLockWrite))
     3601    {
     3602        rc2 = vdThreadFinishWrite(pDisk);
     3603        AssertRC(rc2);
     3604    }
     3605
    31923606    LogFlowFunc(("returns %Rrc\n", rc));
    31933607    return rc;
     
    32073621{
    32083622    int rc = VINF_SUCCESS;
     3623    int rc2;
     3624    bool fLockRead = false;
    32093625
    32103626    LogFlowFunc(("pDisk=%#p nImage=%u puVersion=%#p\n",
     
    32213637                           rc = VERR_INVALID_PARAMETER);
    32223638
     3639        rc2 = vdThreadStartRead(pDisk);
     3640        AssertRC(rc2);
     3641        fLockRead = true;
     3642
    32233643        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    32243644        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    32263646        *puVersion = pImage->Backend->pfnGetVersion(pImage->pvBackendData);
    32273647    } while (0);
     3648
     3649    if (RT_UNLIKELY(fLockRead))
     3650    {
     3651        rc2 = vdThreadFinishRead(pDisk);
     3652        AssertRC(rc2);
     3653    }
    32283654
    32293655    LogFlowFunc(("returns %Rrc uVersion=%#x\n", rc, *puVersion));
     
    32443670{
    32453671    int rc = VINF_SUCCESS;
     3672    int rc2;
     3673    bool fLockRead = false;
    32463674
    32473675    LogFlowFunc(("pDisk=%#p nImage=%u pBackendInfo=%#p\n",
     
    32583686                           rc = VERR_INVALID_PARAMETER);
    32593687
     3688        rc2 = vdThreadStartRead(pDisk);
     3689        AssertRC(rc2);
     3690        fLockRead = true;
     3691
    32603692        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    32613693        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
    32623694
    3263         pBackendInfo->pszBackend = RTStrDup(pImage->Backend->pszBackendName);
     3695        pBackendInfo->pszBackend = pImage->Backend->pszBackendName;
    32643696        pBackendInfo->uBackendCaps = pImage->Backend->uBackendCaps;
    32653697        pBackendInfo->papszFileExtensions = pImage->Backend->papszFileExtensions;
    32663698        pBackendInfo->paConfigInfo = pImage->Backend->paConfigInfo;
    32673699    } while (0);
     3700
     3701    if (RT_UNLIKELY(fLockRead))
     3702    {
     3703        rc2 = vdThreadFinishRead(pDisk);
     3704        AssertRC(rc2);
     3705    }
    32683706
    32693707    LogFlowFunc(("returns %Rrc\n", rc));
     
    32843722{
    32853723    int rc = VINF_SUCCESS;
     3724    int rc2;
     3725    bool fLockRead = false;
    32863726
    32873727    LogFlowFunc(("pDisk=%#p nImage=%u puImageFlags=%#p\n",
     
    32983738                           rc = VERR_INVALID_PARAMETER);
    32993739
     3740        rc2 = vdThreadStartRead(pDisk);
     3741        AssertRC(rc2);
     3742        fLockRead = true;
     3743
    33003744        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    33013745        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    33033747        *puImageFlags = pImage->Backend->pfnGetImageFlags(pImage->pvBackendData);
    33043748    } while (0);
     3749
     3750    if (RT_UNLIKELY(fLockRead))
     3751    {
     3752        rc2 = vdThreadFinishRead(pDisk);
     3753        AssertRC(rc2);
     3754    }
    33053755
    33063756    LogFlowFunc(("returns %Rrc uImageFlags=%#x\n", rc, *puImageFlags));
     
    33213771{
    33223772    int rc = VINF_SUCCESS;
     3773    int rc2;
     3774    bool fLockRead = false;
    33233775
    33243776    LogFlowFunc(("pDisk=%#p nImage=%u puOpenFlags=%#p\n",
     
    33353787                           rc = VERR_INVALID_PARAMETER);
    33363788
     3789        rc2 = vdThreadStartRead(pDisk);
     3790        AssertRC(rc2);
     3791        fLockRead = true;
     3792
    33373793        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    33383794        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    33403796        *puOpenFlags = pImage->Backend->pfnGetOpenFlags(pImage->pvBackendData);
    33413797    } while (0);
     3798
     3799    if (RT_UNLIKELY(fLockRead))
     3800    {
     3801        rc2 = vdThreadFinishRead(pDisk);
     3802        AssertRC(rc2);
     3803    }
    33423804
    33433805    LogFlowFunc(("returns %Rrc uOpenFlags=%#x\n", rc, *puOpenFlags));
     
    33603822{
    33613823    int rc;
     3824    int rc2;
     3825    bool fLockWrite = false;
    33623826
    33633827    LogFlowFunc(("pDisk=%#p uOpenFlags=%#u\n", pDisk, uOpenFlags));
     
    33733837                           rc = VERR_INVALID_PARAMETER);
    33743838
     3839        rc2 = vdThreadStartWrite(pDisk);
     3840        AssertRC(rc2);
     3841        fLockWrite = true;
     3842
    33753843        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    33763844        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    33793847                                              uOpenFlags);
    33803848    } while (0);
     3849
     3850    if (RT_UNLIKELY(fLockWrite))
     3851    {
     3852        rc2 = vdThreadFinishWrite(pDisk);
     3853        AssertRC(rc2);
     3854    }
    33813855
    33823856    LogFlowFunc(("returns %Rrc\n", rc));
     
    34013875{
    34023876    int rc;
     3877    int rc2;
     3878    bool fLockRead = false;
    34033879
    34043880    LogFlowFunc(("pDisk=%#p nImage=%u pszFilename=%#p cbFilename=%u\n",
     
    34183894                           rc = VERR_INVALID_PARAMETER);
    34193895
     3896        rc2 = vdThreadStartRead(pDisk);
     3897        AssertRC(rc2);
     3898        fLockRead = true;
     3899
    34203900        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    34213901        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    34343914        }
    34353915    } while (0);
     3916
     3917    if (RT_UNLIKELY(fLockRead))
     3918    {
     3919        rc2 = vdThreadFinishRead(pDisk);
     3920        AssertRC(rc2);
     3921    }
    34363922
    34373923    LogFlowFunc(("returns %Rrc, pszFilename=\"%s\"\n", rc, pszFilename));
     
    34543940{
    34553941    int rc;
     3942    int rc2;
     3943    bool fLockRead = false;
    34563944
    34573945    LogFlowFunc(("pDisk=%#p nImage=%u pszComment=%#p cbComment=%u\n",
     
    34713959                           rc = VERR_INVALID_PARAMETER);
    34723960
     3961        rc2 = vdThreadStartRead(pDisk);
     3962        AssertRC(rc2);
     3963        fLockRead = true;
     3964
    34733965        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    34743966        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    34773969                                            cbComment);
    34783970    } while (0);
     3971
     3972    if (RT_UNLIKELY(fLockRead))
     3973    {
     3974        rc2 = vdThreadFinishRead(pDisk);
     3975        AssertRC(rc2);
     3976    }
    34793977
    34803978    LogFlowFunc(("returns %Rrc, pszComment=\"%s\"\n", rc, pszComment));
     
    34953993{
    34963994    int rc;
     3995    int rc2;
     3996    bool fLockWrite = false;
    34973997
    34983998    LogFlowFunc(("pDisk=%#p nImage=%u pszComment=%#p \"%s\"\n",
     
    35094009                           rc = VERR_INVALID_PARAMETER);
    35104010
     4011        rc2 = vdThreadStartWrite(pDisk);
     4012        AssertRC(rc2);
     4013        fLockWrite = true;
     4014
    35114015        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    35124016        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    35144018        rc = pImage->Backend->pfnSetComment(pImage->pvBackendData, pszComment);
    35154019    } while (0);
     4020
     4021    if (RT_UNLIKELY(fLockWrite))
     4022    {
     4023        rc2 = vdThreadFinishWrite(pDisk);
     4024        AssertRC(rc2);
     4025    }
    35164026
    35174027    LogFlowFunc(("returns %Rrc\n", rc));
     
    35324042{
    35334043    int rc;
     4044    int rc2;
     4045    bool fLockRead = false;
    35344046
    35354047    LogFlowFunc(("pDisk=%#p nImage=%u pUuid=%#p\n", pDisk, nImage, pUuid));
     
    35454057                           rc = VERR_INVALID_PARAMETER);
    35464058
     4059        rc2 = vdThreadStartRead(pDisk);
     4060        AssertRC(rc2);
     4061        fLockRead = true;
     4062
    35474063        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    35484064        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    35504066        rc = pImage->Backend->pfnGetUuid(pImage->pvBackendData, pUuid);
    35514067    } while (0);
     4068
     4069    if (RT_UNLIKELY(fLockRead))
     4070    {
     4071        rc2 = vdThreadFinishRead(pDisk);
     4072        AssertRC(rc2);
     4073    }
    35524074
    35534075    LogFlowFunc(("returns %Rrc, Uuid={%RTuuid}\n", rc, pUuid));
     
    35674089{
    35684090    int rc;
     4091    int rc2;
     4092    bool fLockWrite = false;
    35694093
    35704094    LogFlowFunc(("pDisk=%#p nImage=%u pUuid=%#p {%RTuuid}\n",
     
    35804104                           rc = VERR_INVALID_PARAMETER);
    35814105
     4106        rc2 = vdThreadStartWrite(pDisk);
     4107        AssertRC(rc2);
     4108        fLockWrite = true;
     4109
    35824110        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    35834111        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    35914119        rc = pImage->Backend->pfnSetUuid(pImage->pvBackendData, pUuid);
    35924120    } while (0);
     4121
     4122    if (RT_UNLIKELY(fLockWrite))
     4123    {
     4124        rc2 = vdThreadFinishWrite(pDisk);
     4125        AssertRC(rc2);
     4126    }
    35934127
    35944128    LogFlowFunc(("returns %Rrc\n", rc));
     
    36084142{
    36094143    int rc = VINF_SUCCESS;
     4144    int rc2;
     4145    bool fLockRead = false;
    36104146
    36114147    LogFlowFunc(("pDisk=%#p nImage=%u pUuid=%#p\n", pDisk, nImage, pUuid));
     
    36214157                           rc = VERR_INVALID_PARAMETER);
    36224158
     4159        rc2 = vdThreadStartRead(pDisk);
     4160        AssertRC(rc2);
     4161        fLockRead = true;
     4162
    36234163        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    36244164        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    36274167                                                     pUuid);
    36284168    } while (0);
     4169
     4170    if (RT_UNLIKELY(fLockRead))
     4171    {
     4172        rc2 = vdThreadFinishRead(pDisk);
     4173        AssertRC(rc2);
     4174    }
    36294175
    36304176    LogFlowFunc(("returns %Rrc, Uuid={%RTuuid}\n", rc, pUuid));
     
    36444190{
    36454191    int rc;
     4192    int rc2;
     4193    bool fLockWrite = false;
    36464194
    36474195    LogFlowFunc(("pDisk=%#p nImage=%u pUuid=%#p {%RTuuid}\n",
     
    36584206                           rc = VERR_INVALID_PARAMETER);
    36594207
     4208        rc2 = vdThreadStartWrite(pDisk);
     4209        AssertRC(rc2);
     4210        fLockWrite = true;
     4211
    36604212        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    36614213        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    36704222                                                     pUuid);
    36714223    } while (0);
     4224
     4225    if (RT_UNLIKELY(fLockWrite))
     4226    {
     4227        rc2 = vdThreadFinishWrite(pDisk);
     4228        AssertRC(rc2);
     4229    }
    36724230
    36734231    LogFlowFunc(("returns %Rrc\n", rc));
     
    36884246{
    36894247    int rc = VINF_SUCCESS;
     4248    int rc2;
     4249    bool fLockRead = false;
    36904250
    36914251    LogFlowFunc(("pDisk=%#p nImage=%u pUuid=%#p\n", pDisk, nImage, pUuid));
     
    37014261                           rc = VERR_INVALID_PARAMETER);
    37024262
     4263        rc2 = vdThreadStartRead(pDisk);
     4264        AssertRC(rc2);
     4265        fLockRead = true;
     4266
    37034267        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    37044268        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    37064270        rc = pImage->Backend->pfnGetParentUuid(pImage->pvBackendData, pUuid);
    37074271    } while (0);
     4272
     4273    if (RT_UNLIKELY(fLockRead))
     4274    {
     4275        rc2 = vdThreadFinishRead(pDisk);
     4276        AssertRC(rc2);
     4277    }
    37084278
    37094279    LogFlowFunc(("returns %Rrc, Uuid={%RTuuid}\n", rc, pUuid));
     
    37234293{
    37244294    int rc;
     4295    int rc2;
     4296    bool fLockWrite = false;
    37254297
    37264298    LogFlowFunc(("pDisk=%#p nImage=%u pUuid=%#p {%RTuuid}\n",
     
    37374309                           rc = VERR_INVALID_PARAMETER);
    37384310
     4311        rc2 = vdThreadStartWrite(pDisk);
     4312        AssertRC(rc2);
     4313        fLockWrite = true;
     4314
    37394315        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
    37404316        AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND);
     
    37494325    } while (0);
    37504326
     4327    if (RT_UNLIKELY(fLockWrite))
     4328    {
     4329        rc2 = vdThreadFinishWrite(pDisk);
     4330        AssertRC(rc2);
     4331    }
     4332
    37514333    LogFlowFunc(("returns %Rrc\n", rc));
    37524334    return rc;
     
    37614343VBOXDDU_DECL(void) VDDumpImages(PVBOXHDD pDisk)
    37624344{
     4345    int rc2;
     4346    bool fLockRead = false;
     4347
    37634348    do
    37644349    {
     
    37784363        }
    37794364
     4365        rc2 = vdThreadStartRead(pDisk);
     4366        AssertRC(rc2);
     4367        fLockRead = true;
     4368
    37804369        pfnMessage(pvUser, "--- Dumping VD Disk, Images=%u\n", pDisk->cImages);
    37814370        for (PVDIMAGE pImage = pDisk->pBase; pImage; pImage = pImage->pNext)
     
    37864375        }
    37874376    } while (0);
     4377
     4378    if (RT_UNLIKELY(fLockRead))
     4379    {
     4380        rc2 = vdThreadFinishRead(pDisk);
     4381        AssertRC(rc2);
     4382    }
    37884383}
    37894384
     
    38004395{
    38014396    int rc = VINF_SUCCESS;
     4397    int rc2;
     4398    bool fLockRead = false;
    38024399
    38034400    LogFlowFunc(("pDisk=%#p nImage=%u pfAIOSupported=%#p\n", pDisk, nImage, pfAIOSupported));
     
    38124409                           ("pfAIOSupported=%#p\n", pfAIOSupported),
    38134410                           rc = VERR_INVALID_PARAMETER);
     4411
     4412        rc2 = vdThreadStartRead(pDisk);
     4413        AssertRC(rc2);
     4414        fLockRead = true;
    38144415
    38154416        PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage);
     
    38214422            *pfAIOSupported = false;
    38224423    } while (0);
     4424
     4425    if (RT_UNLIKELY(fLockRead))
     4426    {
     4427        rc2 = vdThreadFinishRead(pDisk);
     4428        AssertRC(rc2);
     4429    }
    38234430
    38244431    LogFlowFunc(("returns %Rrc, fAIOSupported=%u\n", rc, *pfAIOSupported));
     
    38424449{
    38434450    int rc = VERR_VD_BLOCK_FREE;
     4451    int rc2;
     4452    bool fLockWrite = false;
    38444453
    38454454    LogFlowFunc(("pDisk=%#p uOffset=%llu paSeg=%p cSeg=%u cbRead=%zu\n",
     
    38554464                           ("cbRead=%zu\n", cbRead),
    38564465                           rc = VERR_INVALID_PARAMETER);
     4466        AssertMsgBreakStmt(VALID_PTR(paSeg),
     4467                           ("paSeg=%#p\n", paSeg),
     4468                           rc = VERR_INVALID_PARAMETER);
     4469        AssertMsgBreakStmt(cSeg,
     4470                           ("cSeg=%zu\n", cSeg),
     4471                           rc = VERR_INVALID_PARAMETER);
     4472
     4473        /** @todo handle this just like a write, as in the completion code in
     4474         * DrvVD.cpp there is no way to figure out if it is a read or write. */
     4475        rc2 = vdThreadStartWrite(pDisk);
     4476        AssertRC(rc2);
     4477        fLockWrite = true;
     4478
    38574479        AssertMsgBreakStmt(uOffset + cbRead <= pDisk->cbSize,
    38584480                           ("uOffset=%llu cbRead=%zu pDisk->cbSize=%llu\n",
    38594481                            uOffset, cbRead, pDisk->cbSize),
    38604482                           rc = VERR_INVALID_PARAMETER);
    3861         AssertMsgBreakStmt(VALID_PTR(paSeg),
    3862                            ("paSeg=%#p\n", paSeg),
    3863                            rc = VERR_INVALID_PARAMETER);
    3864         AssertMsgBreakStmt(cSeg,
    3865                            ("cSeg=%zu\n", cSeg),
    3866                            rc = VERR_INVALID_PARAMETER);
    3867 
    38684483
    38694484        PVDIMAGE pImage = pDisk->pLast;
     
    38904505            /* Request finished without the need to enqueue a async I/O request. Tell caller. */
    38914506            rc = VINF_VD_ASYNC_IO_FINISHED;
     4507
     4508            rc2 = vdThreadFinishWrite(pDisk);
     4509            AssertRC(rc2);
     4510            fLockWrite = false;
    38924511        }
    38934512
    38944513    } while (0);
     4514
     4515    if (RT_UNLIKELY(fLockWrite) && RT_FAILURE(rc))
     4516    {
     4517        rc2 = vdThreadFinishWrite(pDisk);
     4518        AssertRC(rc2);
     4519    }
    38954520
    38964521    LogFlowFunc(("returns %Rrc\n", rc));
     
    39154540{
    39164541    int rc;
     4542    int rc2;
     4543    bool fLockWrite = false;
    39174544
    39184545    LogFlowFunc(("pDisk=%#p uOffset=%llu paSeg=%p cSeg=%u cbWrite=%zu\n",
     
    39284555                           ("cbWrite=%zu\n", cbWrite),
    39294556                           rc = VERR_INVALID_PARAMETER);
     4557        AssertMsgBreakStmt(VALID_PTR(paSeg),
     4558                           ("paSeg=%#p\n", paSeg),
     4559                           rc = VERR_INVALID_PARAMETER);
     4560        AssertMsgBreakStmt(cSeg,
     4561                           ("cSeg=%zu\n", cSeg),
     4562                           rc = VERR_INVALID_PARAMETER);
     4563
     4564        rc2 = vdThreadStartWrite(pDisk);
     4565        AssertRC(rc2);
     4566        fLockWrite = true;
     4567
    39304568        AssertMsgBreakStmt(uOffset + cbWrite <= pDisk->cbSize,
    39314569                           ("uOffset=%llu cbWrite=%zu pDisk->cbSize=%llu\n",
    39324570                            uOffset, cbWrite, pDisk->cbSize),
    39334571                           rc = VERR_INVALID_PARAMETER);
    3934         AssertMsgBreakStmt(VALID_PTR(paSeg),
    3935                            ("paSeg=%#p\n", paSeg),
    3936                            rc = VERR_INVALID_PARAMETER);
    3937         AssertMsgBreakStmt(cSeg,
    3938                            ("cSeg=%zu\n", cSeg),
    3939                            rc = VERR_INVALID_PARAMETER);
    3940 
    39414572
    39424573        PVDIMAGE pImage = pDisk->pLast;
     
    39494580    } while (0);
    39504581
     4582    if (RT_UNLIKELY(fLockWrite) && RT_FAILURE(rc))
     4583    {
     4584        rc2 = vdThreadFinishWrite(pDisk);
     4585        AssertRC(rc2);
     4586    }
    39514587    LogFlowFunc(("returns %Rrc\n", rc));
    39524588    return rc;
  • trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp

    r27100 r27232  
    44
    55/*
    6  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     6 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    108108                                                     pImage->pszFilename,
    109109                                                     uOpenFlags,
    110                                                      NULL, &pImage->pvStorage);
     110                                                     NULL,
     111                                                     pImage->pVDIfsDisk,
     112                                                     &pImage->pvStorage);
    111113#endif
    112114
     
    499501                          PCPDMMEDIAGEOMETRY pPCHSGeometry,
    500502                          PCPDMMEDIAGEOMETRY pLCHSGeometry, PCRTUUID pUuid,
    501                           PFNVMPROGRESS pfnProgress, void *pvUser,
     503                          PFNVDPROGRESS pfnProgress, void *pvUser,
    502504                          unsigned uPercentStart, unsigned uPercentSpan)
    503505{
     
    676678            if (pfnProgress)
    677679            {
    678                 rc = pfnProgress(NULL /* WARNING! pVM=NULL  */,
    679                                  uPercentStart + uOff * uPercentSpan / cbFill,
    680                                  pvUser);
     680                rc = pfnProgress(pvUser,
     681                                 uPercentStart + uOff * uPercentSpan / cbFill);
    681682                if (RT_FAILURE(rc))
    682683                    goto out;
     
    688689out:
    689690    if (RT_SUCCESS(rc) && pfnProgress)
    690         pfnProgress(NULL /* WARNING! pVM=NULL  */,
    691                     uPercentStart + uPercentSpan, pvUser);
     691        pfnProgress(pvUser, uPercentStart + uPercentSpan);
    692692
    693693    if (RT_FAILURE(rc))
     
    10121012    PVDIIMAGEDESC pImage;
    10131013
    1014     PFNVMPROGRESS pfnProgress = NULL;
     1014    PFNVDPROGRESS pfnProgress = NULL;
    10151015    void *pvUser = NULL;
    10161016    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation,
     
    20062006/** @copydoc VBOXHDDBACKEND::pfnCompact */
    20072007static int vdiCompact(void *pBackendData, unsigned uPercentStart,
    2008                       unsigned uPercentSpan, PVDINTERFACE pVDIfsOperation)
     2008                      unsigned uPercentSpan, PVDINTERFACE pVDIfsDisk,
     2009                      PVDINTERFACE pVDIfsImage, PVDINTERFACE pVDIfsOperation)
    20092010{
    20102011    PVDIIMAGEDESC pImage = (PVDIIMAGEDESC)pBackendData;
     
    20262027    }
    20272028
    2028     PFNVMPROGRESS pfnProgress = NULL;
     2029    PFNVDPROGRESS pfnProgress = NULL;
    20292030    void *pvUser = NULL;
    20302031    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation,
     
    21562157            if (pCbProgress && pCbProgress->pfnProgress)
    21572158            {
    2158                 rc = pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */,
    2159                                               (uint64_t)i * uPercentSpan / (cBlocks + cBlocksToMove) + uPercentStart,
    2160                                               pIfProgress->pvUser);
     2159                rc = pCbProgress->pfnProgress(pIfProgress->pvUser,
     2160                                              (uint64_t)i * uPercentSpan / (cBlocks + cBlocksToMove) + uPercentStart);
    21612161                if (RT_FAILURE(rc))
    21622162                    break;
     
    22012201            if (pCbProgress && pCbProgress->pfnProgress)
    22022202            {
    2203                 rc = pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */,
    2204                                               (uint64_t)(cBlocks + cBlocksMoved) * uPercentSpan / (cBlocks + cBlocksToMove) + uPercentStart,
    2205                                               pIfProgress->pvUser);
     2203                rc = pCbProgress->pfnProgress(pIfProgress->pvUser,
     2204                                              (uint64_t)(cBlocks + cBlocksMoved) * uPercentSpan / (cBlocks + cBlocksToMove) + uPercentStart);
     2205                                             
    22062206                if (RT_FAILURE(rc))
    22072207                    break;
     
    22302230    if (RT_SUCCESS(rc) && pCbProgress && pCbProgress->pfnProgress)
    22312231    {
    2232         pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */,
    2233                                  uPercentStart + uPercentSpan,
    2234                                  pIfProgress->pvUser);
     2232        pCbProgress->pfnProgress(pIfProgress->pvUser,
     2233                                 uPercentStart + uPercentSpan);
    22352234    }
    22362235
  • trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp

    r26995 r27232  
    44
    55/*
    6  * Copyright (C) 2006-2008 Sun Microsystems, Inc.
     6 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    245245                                                     pImage->pszFilename,
    246246                                                     uOpenFlags,
    247                                                      NULL, &pImage->pvStorage);
     247                                                     NULL,
     248                                                     pImage->pVDIfsDisk,
     249                                                     &pImage->pvStorage);
    248250#endif
    249251
     
    18071809                          PCPDMMEDIAGEOMETRY pLCHSGeometry, PCRTUUID pUuid,
    18081810                          unsigned uOpenFlags,
    1809                           PFNVMPROGRESS pfnProgress, void *pvUser,
     1811                          PFNVDPROGRESS pfnProgress, void *pvUser,
    18101812                          unsigned uPercentStart, unsigned uPercentSpan)
    18111813{
     
    18931895        /* We are half way thourgh with creation of image, let the caller know. */
    18941896        if (pfnProgress)
    1895             pfnProgress(NULL /* WARNING! pVM=NULL  */, (uPercentStart + uPercentSpan) / 2, pvUser);
     1897            pfnProgress(pvUser, (uPercentStart + uPercentSpan) / 2);
    18961898
    18971899        rc = vhdCreateDynamicImage(pImage, cbSize);
     
    19291931
    19301932    if (pfnProgress)
    1931         pfnProgress(NULL /* WARNING! pVM=NULL  */, uPercentStart + uPercentSpan, pvUser);
     1933        pfnProgress(pvUser, uPercentStart + uPercentSpan);
    19321934
    19331935out:
     
    19471949    PVHDIMAGE pImage;
    19481950
    1949     PFNVMPROGRESS pfnProgress = NULL;
     1951    PFNVDPROGRESS pfnProgress = NULL;
    19501952    void *pvUser = NULL;
    19511953    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation,
  • trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp

    r26986 r27232  
    55
    66/*
    7  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    587587                                                           : 0,
    588588                                                         NULL,
     589                                                         pImage->pVDIfsDisk,
    589590                                                         &pVmdkFile->pStorage);
    590591        pVmdkFile->fAsyncIO = true;
     
    34873488static int vmdkCreateRegularImage(PVMDKIMAGE pImage, uint64_t cbSize,
    34883489                                  unsigned uImageFlags,
    3489                                   PFNVMPROGRESS pfnProgress, void *pvUser,
     3490                                  PFNVDPROGRESS pfnProgress, void *pvUser,
    34903491                                  unsigned uPercentStart, unsigned uPercentSpan)
    34913492{
     
    36263627                if (pfnProgress)
    36273628                {
    3628                     rc = pfnProgress(NULL /* WARNING! pVM=NULL */,
    3629                                      uPercentStart + uOff * uPercentSpan / cbExtent,
    3630                                      pvUser);
     3629                    rc = pfnProgress(pvUser,
     3630                                     uPercentStart + uOff * uPercentSpan / cbExtent);
    36313631                    if (RT_FAILURE(rc))
    36323632                    {
     
    36953695
    36963696        if (RT_SUCCESS(rc) && pfnProgress)
    3697             pfnProgress(NULL /* WARNING! pVM=NULL */,
    3698                         uPercentStart + i * uPercentSpan / cExtents,
    3699                         pvUser);
     3697            pfnProgress(pvUser, uPercentStart + i * uPercentSpan / cExtents);
    37003698
    37013699        cbRemaining -= cbExtent;
     
    37463744                           PCPDMMEDIAGEOMETRY pPCHSGeometry,
    37473745                           PCPDMMEDIAGEOMETRY pLCHSGeometry, PCRTUUID pUuid,
    3748                            PFNVMPROGRESS pfnProgress, void *pvUser,
     3746                           PFNVDPROGRESS pfnProgress, void *pvUser,
    37493747                           unsigned uPercentStart, unsigned uPercentSpan)
    37503748{
     
    37933791
    37943792    if (RT_SUCCESS(rc) && pfnProgress)
    3795         pfnProgress(NULL /* WARNING! pVM=NULL */,
    3796                     uPercentStart + uPercentSpan * 98 / 100, pvUser);
     3793        pfnProgress(pvUser, uPercentStart + uPercentSpan * 98 / 100);
    37973794
    37983795    pImage->cbSize = cbSize;
     
    38803877
    38813878    if (RT_SUCCESS(rc) && pfnProgress)
    3882         pfnProgress(NULL /* WARNING! pVM=NULL */,
    3883                     uPercentStart + uPercentSpan * 99 / 100, pvUser);
     3879        pfnProgress(pvUser, uPercentStart + uPercentSpan * 99 / 100);
    38843880
    38853881    rc = vmdkFlushImage(pImage);
     
    38873883out:
    38883884    if (RT_SUCCESS(rc) && pfnProgress)
    3889         pfnProgress(NULL /* WARNING! pVM=NULL */,
    3890                     uPercentStart + uPercentSpan, pvUser);
     3885        pfnProgress(pvUser, uPercentStart + uPercentSpan);
    38913886
    38923887    if (RT_FAILURE(rc))
     
    45154510    PVMDKIMAGE pImage;
    45164511
    4517     PFNVMPROGRESS pfnProgress = NULL;
     4512    PFNVDPROGRESS pfnProgress = NULL;
    45184513    void *pvUser = NULL;
    45194514    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation,
  • trunk/src/VBox/Main/MediumImpl.cpp

    r27200 r27232  
    47854785
    47864786/**
    4787  * PFNVMPROGRESS callback handler for Task operations.
    4788  *
     4787 * PFNVDPROGRESS callback handler for Task operations.
     4788 *
     4789 * @param pvUser      Pointer to the Progress instance.
    47894790 * @param uPercent    Completetion precentage (0-100).
    4790  * @param pvUser      Pointer to the Progress instance.
    47914791 */
    47924792/*static*/
    4793 DECLCALLBACK(int) Medium::vdProgressCall(PVM /* pVM */, unsigned uPercent,
    4794                                          void *pvUser)
     4793DECLCALLBACK(int) Medium::vdProgressCall(void *pvUser, unsigned uPercent)
    47954794{
    47964795    Progress *that = static_cast<Progress *>(pvUser);
  • trunk/src/VBox/Main/include/MediumImpl.h

    r26984 r27232  
    2727
    2828class Progress;
    29 struct VM;
    3029
    3130namespace settings
     
    295294                                          const char *pszFormat, va_list va);
    296295
    297     static DECLCALLBACK(int) vdProgressCall(VM* /* pVM */, unsigned uPercent,
    298                                             void *pvUser);
     296    static DECLCALLBACK(int) vdProgressCall(void *pvUser, unsigned uPercent);
    299297
    300298    static DECLCALLBACK(bool) vdConfigAreKeysValid(void *pvUser,
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