VirtualBox

Changeset 40936 in vbox


Ignore:
Timestamp:
Apr 16, 2012 9:28:45 AM (12 years ago)
Author:
vboxsync
Message:

Storage/VDI: Commit again after fixing the uuid corruption issue

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

Legend:

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

    r40935 r40936  
    3232
    3333#define VDI_IMAGE_DEFAULT_BLOCK_SIZE _1M
     34
     35/** Macros for endianess conversion. */
     36#define SET_ENDIAN_U32(conv, u32) (conv == VDIECONV_H2F ? RT_H2LE_U32(u32) : RT_LE2H_U32(u32))
     37#define SET_ENDIAN_U64(conv, u64) (conv == VDIECONV_H2F ? RT_H2LE_U64(u64) : RT_LE2H_U64(u64))
    3438
    3539/*******************************************************************************
     
    6266
    6367/**
     68 * Internal: Convert the PreHeader fields to the appropriate endianess.
     69 * @param   enmConv     Direction of the conversion.
     70 * @param   pPreHdrConv Where to store the converted pre header.
     71 * @param   pPreHdr     PreHeader pointer.
     72 */
     73static void vdiConvPreHeaderEndianess(VDIECONV enmConv, PVDIPREHEADER pPreHdrConv,
     74                                      PVDIPREHEADER pPreHdr)
     75{
     76    pPreHdrConv->u32Signature = SET_ENDIAN_U32(enmConv, pPreHdr->u32Signature);
     77    pPreHdrConv->u32Version   = SET_ENDIAN_U32(enmConv, pPreHdr->u32Version);
     78}
     79
     80/**
     81 * Internal: Convert the VDIDISKGEOMETRY fields to the appropriate endianess.
     82 * @param   enmConv      Direction of the conversion.
     83 * @param   pDiskGeoConv Where to store the converted geometry.
     84 * @param   pDiskGeo     Pointer to the disk geometry to convert.
     85 */
     86static void vdiConvGeometryEndianess(VDIECONV enmConv, PVDIDISKGEOMETRY pDiskGeoConv,
     87                                     PVDIDISKGEOMETRY pDiskGeo)
     88{
     89    pDiskGeoConv->cCylinders = SET_ENDIAN_U32(enmConv, pDiskGeo->cCylinders);
     90    pDiskGeoConv->cHeads     = SET_ENDIAN_U32(enmConv, pDiskGeo->cHeads);
     91    pDiskGeoConv->cSectors   = SET_ENDIAN_U32(enmConv, pDiskGeo->cSectors);
     92    pDiskGeoConv->cbSector   = SET_ENDIAN_U32(enmConv, pDiskGeo->cbSector);
     93}
     94
     95/**
     96 * Internal: Convert the Header - version 0 fields to the appropriate endianess.
     97 * @param   enmConv      Direction of the conversion.
     98 * @param   pHdrConv     Where to store the converted header.
     99 * @param   pHdr         Pointer to the version 0 header.
     100 */
     101static void vdiConvHeaderEndianessV0(VDIECONV enmConv, PVDIHEADER0 pHdrConv,
     102                                     PVDIHEADER0 pHdr)
     103{
     104    pHdrConv->u32Type          = SET_ENDIAN_U32(enmConv, pHdr->u32Type);
     105    pHdrConv->fFlags           = SET_ENDIAN_U32(enmConv, pHdr->fFlags);
     106    vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry);
     107    pHdrConv->cbDisk           = SET_ENDIAN_U64(enmConv, pHdr->cbDisk);
     108    pHdrConv->cbBlock          = SET_ENDIAN_U32(enmConv, pHdr->cbBlock);
     109    pHdrConv->cBlocks          = SET_ENDIAN_U32(enmConv, pHdr->cBlocks);
     110    pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated);
     111    /* Don't convert the RTUUID fields. */
     112    pHdrConv->uuidCreate       = pHdr->uuidCreate;
     113    pHdrConv->uuidModify       = pHdr->uuidModify;
     114    pHdrConv->uuidLinkage      = pHdr->uuidLinkage;
     115}
     116
     117/**
     118 * Internal: Set the Header - version 1 fields to the appropriate endianess.
     119 * @param   enmConv      Direction of the conversion.
     120 * @param   pHdrConv     Where to store the converted header.
     121 * @param   pHdr         Version 1 Header pointer.
     122 */
     123static void vdiConvHeaderEndianessV1(VDIECONV enmConv, PVDIHEADER1 pHdrConv,
     124                                     PVDIHEADER1 pHdr)
     125{
     126    pHdrConv->cbHeader         = SET_ENDIAN_U32(enmConv, pHdr->cbHeader);
     127    pHdrConv->u32Type          = SET_ENDIAN_U32(enmConv, pHdr->u32Type);
     128    pHdrConv->fFlags           = SET_ENDIAN_U32(enmConv, pHdr->fFlags);
     129    pHdrConv->offBlocks        = SET_ENDIAN_U32(enmConv, pHdr->offBlocks);
     130    pHdrConv->offData          = SET_ENDIAN_U32(enmConv, pHdr->offData);
     131    vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry);
     132    pHdrConv->u32Dummy         = SET_ENDIAN_U32(enmConv, pHdr->u32Dummy);
     133    pHdrConv->cbDisk           = SET_ENDIAN_U64(enmConv, pHdr->cbDisk);
     134    pHdrConv->cbBlock          = SET_ENDIAN_U32(enmConv, pHdr->cbBlock);
     135    pHdrConv->cbBlockExtra     = SET_ENDIAN_U32(enmConv, pHdr->cbBlockExtra);
     136    pHdrConv->cBlocks          = SET_ENDIAN_U32(enmConv, pHdr->cBlocks);
     137    pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated);
     138    /* Don't convert the RTUUID fields. */
     139    pHdrConv->uuidCreate       = pHdr->uuidCreate;
     140    pHdrConv->uuidModify       = pHdr->uuidModify;
     141    pHdrConv->uuidLinkage      = pHdr->uuidLinkage;
     142    pHdrConv->uuidParentModify = pHdr->uuidParentModify;
     143}
     144
     145/**
     146 * Internal: Set the Header - version 1plus fields to the appropriate endianess.
     147 * @param   enmConv      Direction of the conversion.
     148 * @param   pHdrConv     Where to store the converted header.
     149 * @param   pHdr         Version 1+ Header pointer.
     150 */
     151static void vdiConvHeaderEndianessV1p(VDIECONV enmConv, PVDIHEADER1PLUS pHdrConv,
     152                                      PVDIHEADER1PLUS pHdr)
     153{
     154    pHdrConv->cbHeader         = SET_ENDIAN_U32(enmConv, pHdr->cbHeader);
     155    pHdrConv->u32Type          = SET_ENDIAN_U32(enmConv, pHdr->u32Type);
     156    pHdrConv->fFlags           = SET_ENDIAN_U32(enmConv, pHdr->fFlags);
     157    pHdrConv->offBlocks        = SET_ENDIAN_U32(enmConv, pHdr->offBlocks);
     158    pHdrConv->offData          = SET_ENDIAN_U32(enmConv, pHdr->offData);
     159    vdiConvGeometryEndianess(enmConv, &pHdrConv->LegacyGeometry, &pHdr->LegacyGeometry);
     160    pHdrConv->u32Dummy         = SET_ENDIAN_U32(enmConv, pHdr->u32Dummy);
     161    pHdrConv->cbDisk           = SET_ENDIAN_U64(enmConv, pHdr->cbDisk);
     162    pHdrConv->cbBlock          = SET_ENDIAN_U32(enmConv, pHdr->cbBlock);
     163    pHdrConv->cbBlockExtra     = SET_ENDIAN_U32(enmConv, pHdr->cbBlockExtra);
     164    pHdrConv->cBlocks          = SET_ENDIAN_U32(enmConv, pHdr->cBlocks);
     165    pHdrConv->cBlocksAllocated = SET_ENDIAN_U32(enmConv, pHdr->cBlocksAllocated);
     166    /* Don't convert the RTUUID fields. */
     167    pHdrConv->uuidCreate       = pHdr->uuidCreate;
     168    pHdrConv->uuidModify       = pHdr->uuidModify;
     169    pHdrConv->uuidLinkage      = pHdr->uuidLinkage;
     170    pHdrConv->uuidParentModify = pHdr->uuidParentModify;
     171    vdiConvGeometryEndianess(enmConv, &pHdrConv->LCHSGeometry, &pHdr->LCHSGeometry);
     172}
     173
     174/**
     175 * Internal: Set the appropriate endianess on all the Blocks pointed.
     176 * @param   enmConv      Direction of the conversion.
     177 * @param   paBlocks     Pointer to the block array.
     178 * @param   cEntries     Number of entries in the block array.
     179 *
     180 * @note Unlike the other conversion functions this method does an in place conversion
     181 *       to avoid temporary memory allocations when writing the block array.
     182 */
     183static void vdiConvBlocksEndianess(VDIECONV enmConv, PVDIIMAGEBLOCKPOINTER paBlocks,
     184                                   unsigned cEntries)
     185{
     186    for (unsigned i = 0; i < cEntries; i++)
     187        paBlocks[i] = SET_ENDIAN_U32(enmConv, paBlocks[i]);
     188}
     189
     190/**
    64191 * Internal: Flush the image file to disk.
    65192 */
     
    509636
    510637    /* Write pre-header. */
     638    VDIPREHEADER PreHeader;
     639    vdiConvPreHeaderEndianess(VDIECONV_H2F, &PreHeader, &pImage->PreHeader);
    511640    rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, 0,
    512                                 &pImage->PreHeader, sizeof(pImage->PreHeader), NULL);
     641                                &PreHeader, sizeof(PreHeader), NULL);
    513642    if (RT_FAILURE(rc))
    514643    {
     
    519648
    520649    /* Write header. */
     650    VDIHEADER1PLUS Hdr;
     651    vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus);
    521652    rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(pImage->PreHeader),
    522                                 &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus), NULL);
     653                                &Hdr, sizeof(Hdr), NULL);
    523654    if (RT_FAILURE(rc))
    524655    {
     
    528659    }
    529660
     661    vdiConvBlocksEndianess(VDIECONV_H2F, pImage->paBlocks, getImageBlocks(&pImage->Header));
    530662    rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, pImage->offStartBlocks, pImage->paBlocks,
    531663                                getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),
    532664                                NULL);
     665    vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, getImageBlocks(&pImage->Header));
    533666    if (RT_FAILURE(rc))
    534667    {
     
    631764
    632765    /* Read pre-header. */
     766    VDIPREHEADER PreHeader;
    633767    rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0,
    634                                &pImage->PreHeader, sizeof(pImage->PreHeader), NULL);
     768                               &PreHeader, sizeof(PreHeader), NULL);
    635769    if (RT_FAILURE(rc))
    636770    {
     
    639773        goto out;
    640774    }
     775    vdiConvPreHeaderEndianess(VDIECONV_F2H, &pImage->PreHeader, &PreHeader);
    641776    rc = vdiValidatePreHeader(&pImage->PreHeader);
    642777    if (RT_FAILURE(rc))
     
    659794                goto out;
    660795            }
     796            vdiConvHeaderEndianessV0(VDIECONV_F2H, &pImage->Header.u.v0, &pImage->Header.u.v0);
    661797            break;
    662798        case 1:
     
    669805                goto out;
    670806            }
     807            vdiConvHeaderEndianessV1(VDIECONV_F2H, &pImage->Header.u.v1, &pImage->Header.u.v1);
    671808            /* Convert VDI 1.1 images to VDI 1.1+ on open in read/write mode.
    672809             * Conversion is harmless, as any VirtualBox version supporting VDI
     
    694831                    goto out;
    695832                }
     833                vdiConvHeaderEndianessV1p(VDIECONV_F2H, &pImage->Header.u.v1plus, &pImage->Header.u.v1plus);
    696834            }
    697835            break;
     
    723861                               getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER),
    724862                               NULL);
     863    if (RT_FAILURE(rc))
     864    {
     865        rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS, N_("VDI: Error reading the block table in '%s'"), pImage->pszFilename);
     866        goto out;
     867    }
     868    vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, getImageBlocks(&pImage->Header));
    725869
    726870    if (uOpenFlags & VD_OPEN_FLAGS_DISCARD)
     
    782926    {
    783927        case 0:
     928        {
     929            VDIHEADER0 Hdr;
     930            vdiConvHeaderEndianessV0(VDIECONV_H2F, &Hdr, &pImage->Header.u.v0);
    784931            rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER),
    785                                         &pImage->Header.u.v0, sizeof(pImage->Header.u.v0),
    786                                         NULL);
     932                                        &Hdr, sizeof(Hdr), NULL);
    787933            break;
     934        }
    788935        case 1:
    789936            if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus))
     937            {
     938                VDIHEADER1 Hdr;
     939                vdiConvHeaderEndianessV1(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1);
    790940                rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER),
    791                                             &pImage->Header.u.v1, sizeof(pImage->Header.u.v1),
    792                                             NULL);
     941                                            &Hdr, sizeof(Hdr), NULL);
     942            }
    793943            else
     944            {
     945                VDIHEADER1PLUS Hdr;
     946                vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus);
    794947                rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, sizeof(VDIPREHEADER),
    795                                             &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus),
    796                                             NULL);
     948                                            &Hdr, sizeof(Hdr), NULL);
     949            }
    797950            break;
    798951        default:
     
    813966    {
    814967        case 0:
     968        {
     969            VDIHEADER0 Hdr;
     970            vdiConvHeaderEndianessV0(VDIECONV_H2F, &Hdr, &pImage->Header.u.v0);
    815971            rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage,
    816                                              sizeof(VDIPREHEADER), &pImage->Header.u.v0,
    817                                              sizeof(pImage->Header.u.v0),
     972                                             sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr),
    818973                                             pIoCtx, NULL, NULL);
    819974            break;
     975        }
    820976        case 1:
    821977            if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus))
     978            {
     979                VDIHEADER1 Hdr;
     980                vdiConvHeaderEndianessV1(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1);
    822981                rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage,
    823                                                  sizeof(VDIPREHEADER), &pImage->Header.u.v1,
    824                                                  sizeof(pImage->Header.u.v1),
     982                                                 sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr),
    825983                                                 pIoCtx, NULL, NULL);
     984            }
    826985            else
     986            {
     987                VDIHEADER1PLUS Hdr;
     988                vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus);
    827989                rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage,
    828                                                  sizeof(VDIPREHEADER), &pImage->Header.u.v1plus,
    829                                                  sizeof(pImage->Header.u.v1plus),
     990                                                 sizeof(VDIPREHEADER), &Hdr, sizeof(Hdr),
    830991                                                 pIoCtx, NULL, NULL);
     992            }
    831993            break;
    832994        default:
     
    8491011    {
    8501012        /* write only one block pointer. */
     1013        VDIIMAGEBLOCKPOINTER ptrBlock = RT_H2LE_U32(pImage->paBlocks[uBlock]);
    8511014        rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage,
    8521015                                    pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER),
    853                                     &pImage->paBlocks[uBlock], sizeof(VDIIMAGEBLOCKPOINTER),
     1016                                    &ptrBlock, sizeof(VDIIMAGEBLOCKPOINTER),
    8541017                                    NULL);
    8551018        AssertMsgRC(rc, ("vdiUpdateBlockInfo failed to update block=%u, filename=\"%s\", rc=%Rrc\n",
     
    8741037    {
    8751038        /* write only one block pointer. */
     1039        VDIIMAGEBLOCKPOINTER ptrBlock = RT_H2LE_U32(pImage->paBlocks[uBlock]);
    8761040        rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage,
    8771041                                         pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER),
    878                                          &pImage->paBlocks[uBlock],
    879                                          sizeof(VDIIMAGEBLOCKPOINTER),
     1042                                         &ptrBlock, sizeof(VDIIMAGEBLOCKPOINTER),
    8801043                                         pIoCtx, NULL, NULL);
    8811044        AssertMsg(RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS,
     
    28803043
    28813044            /* Write the block array before updating the rest. */
     3045            vdiConvBlocksEndianess(VDIECONV_H2F, pImage->paBlocks, cBlocksNew);
    28823046            rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, pImage->offStartBlocks,
    28833047                                        pImage->paBlocks, cbBlockspaceNew, NULL);
     3048            vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, cBlocksNew);
    28843049
    28853050            if (RT_SUCCESS(rc))
     
    32323397            break;
    32333398        }
     3399        vdiConvPreHeaderEndianess(VDIECONV_F2H, &PreHdr, &PreHdr);
    32343400        rc = vdiValidatePreHeader(&PreHdr);
    32353401        if (RT_FAILURE(rc))
     
    32413407
    32423408        /* Read header. */
    3243         Hdr.uVersion = RT_H2LE_U32(PreHdr.u32Version);
     3409        Hdr.uVersion = PreHdr.u32Version;
    32443410        switch (GET_MAJOR_HEADER_VERSION(&Hdr))
    32453411        {
     
    32513417                    rc = vdIfError(pIfError, rc, RT_SRC_POS, N_("VDI: error reading v0 header in '%s'"),
    32523418                                   pszFilename);
     3419                vdiConvHeaderEndianessV0(VDIECONV_F2H, &Hdr.u.v0, &Hdr.u.v0);
    32533420                break;
    32543421            case 1:
     
    32603427                                   pszFilename);
    32613428                }
     3429                vdiConvHeaderEndianessV1(VDIECONV_F2H, &Hdr.u.v1, &Hdr.u.v1);
    32623430                if (Hdr.u.v1.cbHeader >= sizeof(Hdr.u.v1plus))
    32633431                {
     
    32693437                        rc = vdIfError(pIfError, rc, RT_SRC_POS, N_("VDI: error reading v1.1+ header in '%s'"),
    32703438                                       pszFilename);
     3439                    vdiConvHeaderEndianessV1p(VDIECONV_F2H, &Hdr.u.v1plus, &Hdr.u.v1plus);
    32713440                }
    32723441                break;
     
    33173486            break;
    33183487        }
    3319 
    3320         for (uint32_t i = 0; i < getImageBlocks(&Hdr); i++)
    3321             paBlocks[i] = RT_LE2H_U32(paBlocks[i]);
     3488        vdiConvBlocksEndianess(VDIECONV_F2H, paBlocks, getImageBlocks(&Hdr));
    33223489
    33233490        pu32BlockBitmap = (uint32_t *)RTMemAllocZ(RT_ALIGN_Z(getImageBlocks(&Hdr) / 8, 4));
     
    33623529        else if (!(fFlags & VD_REPAIR_DRY_RUN))
    33633530        {
    3364             for (uint32_t i = 0; i < getImageBlocks(&Hdr); i++)
    3365                 paBlocks[i] = RT_H2LE_U32(paBlocks[i]);
    3366 
    33673531            vdIfErrorMessage(pIfError, "Writing repaired block allocation table...\n");
    33683532
     3533            vdiConvBlocksEndianess(VDIECONV_H2F, paBlocks, getImageBlocks(&Hdr));
    33693534            rc = vdIfIoIntFileWriteSync(pIfIo, pStorage, offStartBlocks, paBlocks,
    33703535                                        getImageBlocks(&Hdr) * sizeof(VDIIMAGEBLOCKPOINTER),
  • trunk/src/VBox/Storage/VDICore.h

    r40935 r40936  
    605605} VDIASYNCBLOCKALLOC, *PVDIASYNCBLOCKALLOC;
    606606
     607/**
     608 * Endianess conversion direction.
     609 */
     610typedef enum VDIECONV
     611{
     612    /** Host to file endianess. */
     613    VDIECONV_H2F = 0,
     614    /** File to host endianess. */
     615    VDIECONV_F2H
     616} VDIECONV;
     617
    607618#endif
    608619
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