VirtualBox

Changeset 30313 in vbox


Ignore:
Timestamp:
Jun 18, 2010 1:20:34 PM (14 years ago)
Author:
vboxsync
Message:

Storage/VBoxHDD: optimize image cloning, at the moment only for newly created target images without parents

File:
1 edited

Legend:

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

    r30044 r30313  
    534534 */
    535535static int vdReadHelper(PVBOXHDD pDisk, PVDIMAGE pImage, PVDIMAGE pImageParentOverride,
    536                         uint64_t uOffset, void *pvBuf, size_t cbRead)
     536                        uint64_t uOffset, void *pvBuf, size_t cbRead, bool fHandleFreeBlocks)
    537537{
    538538    int rc;
    539539    size_t cbThisRead;
     540    bool fAllFree = true;
     541    size_t cbBufClear = 0;
    540542
    541543    /* Loop until all read. */
     
    570572        if (rc == VERR_VD_BLOCK_FREE)
    571573        {
    572             memset(pvBuf, '\0', cbThisRead);
     574            /* Fill the free space with 0 if we are told to do so. */
     575            if (fHandleFreeBlocks)
     576                memset(pvBuf, '\0', cbThisRead);
     577            else
     578                cbBufClear += cbThisRead;
     579
    573580            rc = VINF_SUCCESS;
     581        }
     582        else if (RT_SUCCESS(rc))
     583        {
     584            /* First not free block, fill the space before with 0. */
     585            if (!fHandleFreeBlocks)
     586            {
     587                memset((char *)pvBuf - cbBufClear, '\0', cbBufClear);
     588                cbBufClear = 0;
     589                fAllFree = false;
     590            }
    574591        }
    575592
     
    579596    } while (cbRead != 0 && RT_SUCCESS(rc));
    580597
    581     return rc;
     598    return (!fHandleFreeBlocks && fAllFree) ? VERR_VD_BLOCK_FREE : rc;
    582599}
    583600
     
    891908    PVDPARENTSTATEDESC pParentState = (PVDPARENTSTATEDESC)pvUser;
    892909    return vdReadHelper(pParentState->pDisk, pParentState->pImage, NULL, uOffset,
    893                         pvBuf, cbRead);
     910                        pvBuf, cbRead, true);
    894911}
    895912
     
    952969    {
    953970        rc = vdReadHelper(pDisk, pImage, pImageParentOverride,
    954                           uOffset - cbPreRead, pvTmp, cbPreRead);
     971                          uOffset - cbPreRead, pvTmp, cbPreRead, true);
    955972        if (RT_FAILURE(rc))
    956973            return rc;
     
    9891006                              uOffset + cbThisWrite + cbWriteCopy,
    9901007                              (char *)pvTmp + cbPreRead + cbThisWrite + cbWriteCopy,
    991                               cbReadImage);
     1008                              cbReadImage, true);
    9921009        if (RT_FAILURE(rc))
    9931010            return rc;
     
    10491066     * be modified by the write or not. */
    10501067    rc = vdReadHelper(pDisk, pImage, pImageParentOverride, uOffset - cbPreRead, pvTmp,
    1051                       cbPreRead + cbThisWrite + cbPostRead - cbFill);
     1068                      cbPreRead + cbThisWrite + cbPostRead - cbFill, true);
    10521069    if (RT_FAILURE(rc))
    10531070        return rc;
     
    40764093        }
    40774094
     4095        /* Whether we can take the optimized copy path (false) or not.
     4096         * Don't optimize if the image existed or if it is a child image. */
     4097        bool fRegularRead = (pszFilename == NULL) || (cImagesTo > 0);
     4098
    40784099        /* Copy the data. */
    40794100        uint64_t uOffset = 0;
     
    40944115
    40954116            rc = vdReadHelper(pDiskFrom, pImageFrom, NULL, uOffset, pvBuf,
    4096                               cbThisRead);
    4097             if (RT_FAILURE(rc))
     4117                              cbThisRead, fRegularRead);
     4118            if (RT_FAILURE(rc) && rc != VERR_VD_BLOCK_FREE)
    40984119                break;
    40994120
     
    41024123            fLockReadFrom = false;
    41034124
    4104             rc2 = vdThreadStartWrite(pDiskTo);
    4105             AssertRC(rc2);
    4106             fLockWriteTo = true;
    4107 
    4108             rc = vdWriteHelper(pDiskTo, pImageTo, NULL, uOffset, pvBuf,
    4109                                cbThisRead);
    4110             if (RT_FAILURE(rc))
    4111                 break;
    4112 
    4113             rc2 = vdThreadFinishWrite(pDiskTo);
    4114             AssertRC(rc2);
    4115             fLockWriteTo = false;
     4125            if (rc != VERR_VD_BLOCK_FREE)
     4126            {
     4127                rc2 = vdThreadStartWrite(pDiskTo);
     4128                AssertRC(rc2);
     4129                fLockWriteTo = true;
     4130
     4131                rc = vdWriteHelper(pDiskTo, pImageTo, NULL, uOffset, pvBuf,
     4132                                   cbThisRead);
     4133                if (RT_FAILURE(rc))
     4134                    break;
     4135
     4136                rc2 = vdThreadFinishWrite(pDiskTo);
     4137                AssertRC(rc2);
     4138                fLockWriteTo = false;
     4139            }
    41164140
    41174141            uOffset += cbThisRead;
     
    45314555        AssertPtrBreakStmt(pImage, rc = VERR_VD_NOT_OPENED);
    45324556
    4533         rc = vdReadHelper(pDisk, pImage, NULL, uOffset, pvBuf, cbRead);
     4557        rc = vdReadHelper(pDisk, pImage, NULL, uOffset, pvBuf, cbRead, true);
    45344558    } while (0);
    45354559
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