VirtualBox

Changeset 75349 in vbox


Ignore:
Timestamp:
Nov 9, 2018 10:36:54 AM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126479
Message:

Storage/VD: Fix error during merge if the target is bigger than the source image

Location:
trunk/src/VBox/Storage
Files:
2 edited

Legend:

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

    r73097 r75349  
    595595{
    596596    uint64_t cbImage = 0;
    597     PCVDREGIONLIST pRegionList = NULL;
    598     int rc = pImage->Backend->pfnQueryRegions(pImage->pBackendData, &pRegionList);
    599     if (RT_SUCCESS(rc))
    600     {
    601         if (pRegionList->fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS)
    602         {
    603             PVDREGIONLIST pRegionListConv = NULL;
    604             rc = vdRegionListConv(pRegionList, 0, &pRegionListConv);
    605             if (RT_SUCCESS(rc))
     597
     598    if (pImage->cbImage == VD_IMAGE_SIZE_UNINITIALIZED)
     599    {
     600        PCVDREGIONLIST pRegionList = NULL;
     601        int rc = pImage->Backend->pfnQueryRegions(pImage->pBackendData, &pRegionList);
     602        if (RT_SUCCESS(rc))
     603        {
     604            if (pRegionList->fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS)
    606605            {
    607                 for (uint32_t i = 0; i < pRegionListConv->cRegions; i++)
    608                     cbImage += pRegionListConv->aRegions[i].cRegionBlocksOrBytes;
    609 
    610                 VDRegionListFree(pRegionListConv);
     606                PVDREGIONLIST pRegionListConv = NULL;
     607                rc = vdRegionListConv(pRegionList, 0, &pRegionListConv);
     608                if (RT_SUCCESS(rc))
     609                {
     610                    for (uint32_t i = 0; i < pRegionListConv->cRegions; i++)
     611                        cbImage += pRegionListConv->aRegions[i].cRegionBlocksOrBytes;
     612
     613                    VDRegionListFree(pRegionListConv);
     614                }
    611615            }
    612         }
    613         else
    614             for (uint32_t i = 0; i < pRegionList->cRegions; i++)
    615                 cbImage += pRegionList->aRegions[i].cRegionBlocksOrBytes;
    616 
    617         AssertPtr(pImage->Backend->pfnRegionListRelease);
    618         pImage->Backend->pfnRegionListRelease(pImage->pBackendData, pRegionList);
    619     }
     616            else
     617                for (uint32_t i = 0; i < pRegionList->cRegions; i++)
     618                    cbImage += pRegionList->aRegions[i].cRegionBlocksOrBytes;
     619
     620            AssertPtr(pImage->Backend->pfnRegionListRelease);
     621            pImage->Backend->pfnRegionListRelease(pImage->pBackendData, pRegionList);
     622            pImage->cbImage = cbImage; /* Cache the value. */
     623        }
     624    }
     625    else
     626        cbImage = pImage->cbImage;
    620627
    621628    return cbImage;
     
    33123319{
    33133320    RT_NOREF8(pvUser, pStorage, uOffset, paSegments, cSegments, cbRead, pvCompletion, ppTask);
     3321    AssertFailed();
    33143322    return VERR_NOT_IMPLEMENTED;
    33153323}
     
    33243332{
    33253333    RT_NOREF8(pvUser, pStorage, uOffset, paSegments, cSegments, cbWrite, pvCompletion, ppTask);
     3334    AssertFailed();
    33263335    return VERR_NOT_IMPLEMENTED;
    33273336}
     
    33343343{
    33353344    RT_NOREF4(pvUser, pStorage, pvCompletion, ppTask);
     3345    AssertFailed();
    33363346    return VERR_NOT_IMPLEMENTED;
    33373347}
     
    56275637        }
    56285638
     5639        pImage->cbImage     = VD_IMAGE_SIZE_UNINITIALIZED;
    56295640        pImage->VDIo.pDisk  = pDisk;
    56305641        pImage->pVDIfsImage = pVDIfsImage;
     
    62746285            break;
    62756286        }
     6287        pImage->cbImage     = VD_IMAGE_SIZE_UNINITIALIZED;
    62766288        pImage->VDIo.pDisk  = pDisk;
    62776289        pImage->pVDIfsImage = pVDIfsImage;
     
    65776589        }
    65786590
     6591        pImage->cbImage     = VD_IMAGE_SIZE_UNINITIALIZED;
    65796592        pImage->VDIo.pDisk  = pDisk;
    65806593        pImage->pVDIfsImage = pVDIfsImage;
     
    70647077                         pCurrImage = pCurrImage->pPrev)
    70657078                    {
    7066                         rc = pCurrImage->Backend->pfnRead(pCurrImage->pBackendData,
    7067                                                           uOffset, cbThisRead,
    7068                                                           &IoCtx, &cbThisRead);
     7079                        /*
     7080                         * Skip reading when offset exceeds image size which can happen when the target is
     7081                         * bigger than the source.
     7082                         */
     7083                        if (uOffset < pCurrImage->cbImage)
     7084                        {
     7085                            cbThisRead = RT_MIN(cbThisRead, pCurrImage->cbImage - uOffset);
     7086                            rc = pCurrImage->Backend->pfnRead(pCurrImage->pBackendData,
     7087                                                              uOffset, cbThisRead,
     7088                                                              &IoCtx, &cbThisRead);
     7089                        }
     7090                        else
     7091                            rc = VERR_VD_BLOCK_FREE;
    70697092                    }
    70707093
     
    71917214                     pCurrImage = pCurrImage->pPrev)
    71927215                {
    7193                     rc = pCurrImage->Backend->pfnRead(pCurrImage->pBackendData,
    7194                                                            uOffset, cbThisRead,
    7195                                                            &IoCtx, &cbThisRead);
     7216                    /*
     7217                     * Skip reading when offset exceeds image size which can happen when the target is
     7218                     * bigger than the source.
     7219                     */
     7220                    if (uOffset < pCurrImage->cbImage)
     7221                    {
     7222                        cbThisRead = RT_MIN(cbThisRead, pCurrImage->cbImage - uOffset);
     7223                        rc = pCurrImage->Backend->pfnRead(pCurrImage->pBackendData,
     7224                                                          uOffset, cbThisRead,
     7225                                                          &IoCtx, &cbThisRead);
     7226                    }
     7227                    else
     7228                        rc = VERR_VD_BLOCK_FREE;
    71967229                }
    71977230
     
    79808013                                            pImage->pVDIfsImage,
    79818014                                            pVDIfsOperation);
     8015        /* Mark the image size as uninitialized so it gets recalculated the next time. */
     8016        if (RT_SUCCESS(rc))
     8017            pImage->cbImage = VD_IMAGE_SIZE_UNINITIALIZED;
    79828018    } while (0);
    79838019
  • trunk/src/VBox/Storage/VDInternal.h

    r66486 r75349  
    7474    /** Link to child image descriptor, if any. */
    7575    struct VDIMAGE     *pNext;
     76    /** Cached image size. */
     77    uint64_t           cbImage;
    7678    /** Container base filename. (UTF-8) */
    7779    char               *pszFilename;
     
    9193    VDIO                VDIo;
    9294} VDIMAGE, *PVDIMAGE;
     95
     96/** The special uninitialized size value for he image. */
     97#define VD_IMAGE_SIZE_UNINITIALIZED UINT64_C(0)
    9398
    9499/**
Note: See TracChangeset for help on using the changeset viewer.

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