VirtualBox

Ignore:
Timestamp:
Apr 15, 2008 8:13:06 PM (17 years ago)
Author:
vboxsync
Message:

VMDK: Fix a really nasty and indirect bug when creating split sparse VMDK files. Triggered a crash later after the header inconsistency spread (though the image became never actually invalid). Also creating fixed non-split images is fixed now and fixed images are completely written to disk (no sparse file use, see VDI).

File:
1 edited

Legend:

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

    r7981 r8015  
    19841984    if (pExtent->pRGD)
    19851985    {
     1986        Assert(pExtent->uSectorRGD);
    19861987        Header.rgdOffset = RT_H2LE_U64(pExtent->uSectorRGD);
    19871988        Header.gdOffset = RT_H2LE_U64(pExtent->uSectorGD);
     
    27762777            RTStrFree(pszTmp);
    27772778            pExtent->pszBasename = pszBasename;
    2778             cbExtent = RT_MIN(cbRemaining, VMDK_2G_SPLIT_SIZE);
     2779            if (uImageFlags & VD_VMDK_IMAGE_FLAGS_SPLIT_2G)
     2780                cbExtent = RT_MIN(cbRemaining, VMDK_2G_SPLIT_SIZE);
    27792781        }
    27802782        char *pszBasedirectory = RTStrDup(pImage->pszFilename);
     
    27982800            if (VBOX_FAILURE(rc))
    27992801                return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not set size of new file '%s'"), pExtent->pszFullname);
     2802
     2803            /* Fill image with zeroes. We do this for every fixed-size image since on some systems
     2804             * (for example Windows Vista), it takes ages to write a block near the end of a sparse
     2805             * file and the guest could complain about an ATA timeout. */
     2806
     2807            /** @todo Starting with Linux 2.6.23, there is an fallocate() system call.
     2808             *        Currently supported file systems are ext4 and ocfs2. */
     2809
     2810            /* Allocate a temporary zero-filled buffer. Use a bigger block size to optimize writing */
     2811            const size_t cbBuf = 128 * _1K;
     2812            void *pvBuf = RTMemTmpAllocZ(cbBuf);
     2813            if (!pvBuf)
     2814                return VERR_NO_MEMORY;
     2815
     2816            uint64_t uOff = 0;
     2817            /* Write data to all image blocks. */
     2818            while (uOff < cbExtent)
     2819            {
     2820                unsigned cbChunk = (unsigned)RT_MIN(cbExtent, cbBuf);
     2821
     2822                rc = RTFileWriteAt(pExtent->File, uOff, pvBuf, cbChunk, NULL);
     2823                if (VBOX_FAILURE(rc))
     2824                {
     2825                    RTMemFree(pvBuf);
     2826                    return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: writing block failed for '%s'"), pImage->pszFilename);
     2827                }
     2828
     2829                uOff += cbChunk;
     2830
     2831                if (pfnProgress)
     2832                {
     2833                    rc = pfnProgress(NULL /* WARNING! pVM=NULL  */,
     2834                                     uPercentStart + uOff * uPercentSpan / cbExtent,
     2835                                     pvUser);
     2836                    if (VBOX_FAILURE(rc))
     2837                    {
     2838                        RTMemFree(pvBuf);
     2839                        return rc;
     2840                    }
     2841                }
     2842            }
     2843            RTMemTmpFree(pvBuf);
    28002844        }
    28012845
     
    28342878        {
    28352879            rc = vmdkCreateGrainDirectory(pExtent,
    2836                                             pExtent->uDescriptorSector
    2837                                           + pExtent->cDescriptorSectors,
     2880                                          RT_MAX(  pExtent->uDescriptorSector
     2881                                                 + pExtent->cDescriptorSectors,
     2882                                                 1),
    28382883                                          true);
    28392884            if (VBOX_FAILURE(rc))
     
    32703315        return VERR_OUT_OF_RANGE;
    32713316    uGTSector = pExtent->pGD[uGDIndex];
    3272     uRGTSector = pExtent->pRGD[uGDIndex];
     3317    if (pExtent->pRGD)
     3318        uRGTSector = pExtent->pRGD[uGDIndex];
    32733319    if (!uGTSector)
    32743320    {
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