VirtualBox

Changeset 34509 in vbox for trunk/src


Ignore:
Timestamp:
Nov 30, 2010 1:20:00 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
68297
Message:

Storage/VD: adjust LCHS geometry in a smart way when cloning the image

File:
1 edited

Legend:

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

    r34406 r34509  
    34703470}
    34713471
     3472
     3473/**
     3474 * internal: adjust PCHS geometry
     3475 */
     3476static void vdFixupPCHSGeometry(PVDGEOMETRY pPCHS, uint64_t cbSize)
     3477{
     3478    /* Fix broken PCHS geometry. Can happen for two reasons: either the backend
     3479     * mixes up PCHS and LCHS, or the application used to create the source
     3480     * image has put garbage in it. Additionally, if the PCHS geometry covers
     3481     * more than the image size, set it back to the default. */
     3482    if (   pPCHS->cHeads > 16
     3483        || pPCHS->cSectors > 63
     3484        || pPCHS->cCylinders == 0
     3485        || (uint64_t)pPCHS->cHeads * pPCHS->cSectors * pPCHS->cCylinders * 512 > cbSize)
     3486    {
     3487        Assert(!(RT_MIN(cbSize / 512 / 16 / 63, 16383) - (uint32_t)RT_MIN(cbSize / 512 / 16 / 63, 16383)));
     3488        pPCHS->cCylinders = (uint32_t)RT_MIN(cbSize / 512 / 16 / 63, 16383);
     3489        pPCHS->cHeads = 16;
     3490        pPCHS->cSectors = 63;
     3491    }
     3492}
     3493
     3494/**
     3495 * internal: adjust PCHS geometry
     3496 */
     3497static void vdFixupLCHSGeometry(PVDGEOMETRY pLCHS, uint64_t cbSize)
     3498{
     3499    /* Fix broken LCHS geometry. Can happen for two reasons: either the backend
     3500     * mixes up PCHS and LCHS, or the application used to create the source
     3501     * image has put garbage in it. The fix in this case is to clear the LCHS
     3502     * geometry to trigger autodetection when it is used next. If the geometry
     3503     * already says "please autodetect" (cylinders=0) keep it. */
     3504    if (   (   pLCHS->cHeads > 255
     3505            || pLCHS->cHeads == 0
     3506            || pLCHS->cSectors > 63
     3507            || pLCHS->cSectors == 0)
     3508        && pLCHS->cCylinders != 0)
     3509    {
     3510        pLCHS->cCylinders = 0;
     3511        pLCHS->cHeads = 0;
     3512        pLCHS->cSectors = 0;
     3513    }
     3514    /* Always recompute the number of cylinders stored in the LCHS
     3515     * geometry if it isn't set to "autotedetect" at the moment.
     3516     * This is very useful if the destination image size is
     3517     * larger or smaller than the source image size. Do not modify
     3518     * the number of heads and sectors. Windows guests hate it. */
     3519    if (   pLCHS->cCylinders != 0
     3520        && pLCHS->cHeads != 0 /* paranoia */
     3521        && pLCHS->cSectors != 0 /* paranoia */)
     3522    {
     3523        Assert(!(RT_MIN(cbSize / 512 / pLCHS->cHeads / pLCHS->cSectors, 1024) - (uint32_t)RT_MIN(cbSize / 512 / pLCHS->cHeads / pLCHS->cSectors, 1024)));
     3524        pLCHS->cCylinders = (uint32_t)RT_MIN(cbSize / 512 / pLCHS->cHeads / pLCHS->cSectors, 1024);
     3525    }
     3526}
    34723527
    34733528/**
     
    57365791                    uImageFlags |= VD_IMAGE_FLAGS_FIXED;
    57375792
    5738                 /* Fix broken PCHS geometry. Can happen for two reasons: either
    5739                  * the backend mixes up PCHS and LCHS, or the application used
    5740                  * to create the source image has put garbage in it. */
    5741                 /** @todo double-check if the VHD backend correctly handles
    5742                  * PCHS and LCHS geometry. also reconsider our current paranoia
    5743                  * level when it comes to geometry settings here and in the
    5744                  * backends. */
    5745                 if (PCHSGeometryFrom.cHeads > 16 || PCHSGeometryFrom.cSectors > 63)
    5746                 {
    5747                     Assert(RT_MIN(cbSize / 512 / 16 / 63, 16383) - (uint32_t)RT_MIN(cbSize / 512 / 16 / 63, 16383));
    5748                     PCHSGeometryFrom.cCylinders = (uint32_t)RT_MIN(cbSize / 512 / 16 / 63, 16383);
    5749                     PCHSGeometryFrom.cHeads = 16;
    5750                     PCHSGeometryFrom.cSectors = 63;
    5751                 }
     5793                vdFixupPCHSGeometry(&PCHSGeometryFrom, cbSize);
     5794                vdFixupLCHSGeometry(&LCHSGeometryFrom, cbSize);
    57525795
    57535796                rc = VDCreateBase(pDiskTo, pszBackend, pszFilename, cbSize,
     
    57875830            if (cbSize == 0)
    57885831                cbSize = RT_MIN(cbSizeFrom, cbSizeTo);
     5832
     5833            vdFixupPCHSGeometry(&PCHSGeometryFrom, cbSize);
     5834            vdFixupLCHSGeometry(&LCHSGeometryFrom, cbSize);
     5835
     5836            /* Update the geometry in the destination image. */
     5837            pImageTo->Backend->pfnSetPCHSGeometry(pImageTo->pBackendData, &PCHSGeometryFrom);
     5838            pImageTo->Backend->pfnSetLCHSGeometry(pImageTo->pBackendData, &LCHSGeometryFrom);
    57895839        }
    57905840
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