VirtualBox

Changeset 31810 in vbox


Ignore:
Timestamp:
Aug 20, 2010 10:31:26 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
65004
Message:

VDI/Resize: Bug fixes, cleanups

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VDICore.h

    r31804 r31810  
    373373    {
    374374        case 0: return;
    375         case 1: ph->u.v1.offData = offData;
     375        case 1: ph->u.v1.offData = offData; return;
    376376    }
    377377    AssertFailed();
  • trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp

    r31804 r31810  
    25472547    else if (cbSize > getImageDiskSize(&pImage->Header))
    25482548    {
    2549         unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header);
    2550         uint64_t cbNew  = cbSize - getImageDiskSize(&pImage->Header);
    2551         uint32_t cBlocksNew = cbNew / getImageBlockSize(&pImage->Header);
    2552         if (cbNew % getImageBlockSize(&pImage->Header))
     2549        unsigned cBlocksAllocated = getImageBlocksAllocated(&pImage->Header); /** < Blocks currently allocated, doesn't change during resize */
     2550        uint32_t cBlocksNew = cbSize / getImageBlockSize(&pImage->Header);    /** < New number of blocks in the image after the resize */
     2551        if (cbSize % getImageBlockSize(&pImage->Header))
    25532552            cBlocksNew++;
    2554         uint32_t cbAdditionalBlockspace = cBlocksNew * sizeof(VDIIMAGEBLOCKPOINTER);
    2555         uint64_t cbBlockspace = getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER) + cbAdditionalBlockspace;
    2556 
    2557         uint64_t offImageDataNew = RT_ALIGN_32(pImage->offStartBlocks + cbBlockspace, VDI_GEOMETRY_SECTOR_SIZE);
    2558 
    2559         if (   pImage->offStartData != offImageDataNew
     2553
     2554        uint32_t cBlocksOld      = getImageBlocks(&pImage->Header);           /** < Number of blocks before the resize. */
     2555        uint64_t cbBlockspaceNew = cBlocksNew * sizeof(VDIIMAGEBLOCKPOINTER); /** < Required space for the block array after the resize. */
     2556        uint64_t offStartDataNew = RT_ALIGN_32(pImage->offStartBlocks + cbBlockspaceNew, VDI_GEOMETRY_SECTOR_SIZE); /** < New start offset for block data after the resize */
     2557
     2558        if (   pImage->offStartData != offStartDataNew
    25602559            && getImageBlocksAllocated(&pImage->Header) > 0)
    25612560        {
    25622561            /* Calculate how many sectors nee to be relocated. */
    2563             uint64_t cbOverlapping = offImageDataNew - pImage->offStartData;
     2562            uint64_t cbOverlapping = offStartDataNew - pImage->offStartData;
    25642563            unsigned cBlocksReloc = cbOverlapping / getImageBlockSize(&pImage->Header);
    25652564            if (cbOverlapping % getImageBlockSize(&pImage->Header))
    25662565                cBlocksReloc++;
     2566
     2567            cBlocksReloc = RT_MIN(cBlocksReloc, cBlocksAllocated);
     2568            offStartDataNew = pImage->offStartData;
    25672569
    25682570            /* Do the relocation. */
     
    25762578            do
    25772579            {
    2578                 uint64_t offBlockCur = pImage->offStartData;
    25792580                VDIIMAGEBLOCKPOINTER uBlock = 0;
    25802581
     
    25982599                {
    25992600                    /* Search the index in the block table. */
    2600                     for (unsigned idxBlock = 0; idxBlock < cBlocksAllocated; idxBlock++)
     2601                    for (unsigned idxBlock = 0; idxBlock < cBlocksOld; idxBlock++)
    26012602                    {
    26022603                        if (pImage->paBlocks[idxBlock] == uBlock)
    26032604                        {
    26042605                            /* Read data and append to the end of the image. */
    2605                             rc = vdiFileReadSync(pImage, offBlockCur, pvBuf, pImage->cbTotalBlockData, NULL);
     2606                            rc = vdiFileReadSync(pImage, offStartDataNew, pvBuf, pImage->cbTotalBlockData, NULL);
    26062607                            if (RT_FAILURE(rc))
    26072608                                break;
     
    26172618
    26182619                            /* Zero out the old block area. */
    2619                             rc = vdiFileWriteSync(pImage, offBlockCur, pvZero, pImage->cbTotalBlockData, NULL);
     2620                            rc = vdiFileWriteSync(pImage, offStartDataNew, pvZero, pImage->cbTotalBlockData, NULL);
    26202621                            if (RT_FAILURE(rc))
    26212622                                break;
    26222623
    26232624                            /* Update block counter. */
    2624                             pImage->paBlocks[idxBlock] = cBlocksAllocated;
     2625                            pImage->paBlocks[idxBlock] = cBlocksAllocated - 1;
    26252626
    26262627                            /*
     
    26282629                             * They were moved one block to the front.
    26292630                             * Doing it as a separate step iterating over the array again
    2630                              * because an error while relocating the one block might end up
     2631                             * because an error while relocating the block might end up
    26312632                             * in a corrupted image otherwise.
    26322633                             */
    2633                             for (unsigned idxBlock2 = 0; idxBlock2 < cBlocksAllocated; idxBlock2++)
     2634                            for (unsigned idxBlock2 = 0; idxBlock2 < cBlocksOld; idxBlock2++)
    26342635                            {
    26352636                                if (   idxBlock2 != idxBlock
     
    26372638                                    pImage->paBlocks[idxBlock2]--;
    26382639                            }
     2640
     2641                            /* Continue with the next block. */
     2642                            break;
    26392643                        }
    26402644                    }
     
    26442648
    26452649                    uBlock++;
    2646                     offBlockCur += pImage->cbTotalBlockData;
     2650                    offStartDataNew += pImage->cbTotalBlockData;
    26472651                }
    26482652            } while (0);
     
    26532657                RTMemFree(pvZero);
    26542658        }
     2659
     2660        /*
     2661         * We need to update the new offsets for the image data in the out of memory
     2662         * case too because we relocated the blocks already.
     2663         */
     2664        pImage->offStartData = offStartDataNew;
     2665        setImageDataOffset(&pImage->Header, offStartDataNew);
    26552666
    26562667        /*
     
    26602671        if (RT_SUCCESS(rc))
    26612672        {
    2662             PVDIIMAGEBLOCKPOINTER paBlocksNew = (PVDIIMAGEBLOCKPOINTER)RTMemRealloc(pImage->paBlocks, getImageBlocks(&pImage->Header) + cBlocksNew);
     2673            PVDIIMAGEBLOCKPOINTER paBlocksNew = (PVDIIMAGEBLOCKPOINTER)RTMemRealloc(pImage->paBlocks, cbBlockspaceNew);
    26632674            if (paBlocksNew)
    26642675            {
     2676                pImage->paBlocks = paBlocksNew;
     2677
    26652678                /* Mark the new blocks as unallocated. */
    2666                 for (unsigned idxBlock = getImageBlocks(&pImage->Header); idxBlock < getImageBlocks(&pImage->Header) + cBlocksNew; idxBlock++)
     2679                for (unsigned idxBlock = cBlocksOld; idxBlock < cBlocksNew; idxBlock++)
    26672680                    pImage->paBlocks[idxBlock] = VDI_IMAGE_BLOCK_FREE;
    26682681            }
     
    26722685            /* Write the block array before updating the rest. */
    26732686            rc = vdiFileWriteSync(pImage, pImage->offStartBlocks, pImage->paBlocks,
    2674                                   sizeof(VDIIMAGEBLOCKPOINTER) * (getImageBlocks(&pImage->Header) + cBlocksNew),
    2675                                   NULL);
    2676         }
    2677 
    2678         if (RT_SUCCESS(rc))
    2679         {
    2680             /* Update size and new block count. */
    2681             setImageDiskSize(&pImage->Header, cbSize);
    2682             setImageBlocks(&pImage->Header, getImageBlocks(&pImage->Header) + cBlocksNew);
    2683             /* Update geometry. */
    2684             pImage->PCHSGeometry = *pPCHSGeometry;
    2685 
    2686             PVDIDISKGEOMETRY pGeometry = getImageLCHSGeometry(&pImage->Header);
    2687             if (pGeometry)
     2687                                  cbBlockspaceNew, NULL);
     2688
     2689            if (RT_SUCCESS(rc))
    26882690            {
    2689                 pGeometry->cCylinders = pLCHSGeometry->cCylinders;
    2690                 pGeometry->cHeads = pLCHSGeometry->cHeads;
    2691                 pGeometry->cSectors = pLCHSGeometry->cSectors;
    2692                 pGeometry->cbSector = VDI_GEOMETRY_SECTOR_SIZE;
     2691                /* Update size and new block count. */
     2692                setImageDiskSize(&pImage->Header, cbSize);
     2693                setImageBlocks(&pImage->Header, cBlocksNew);
     2694                /* Update geometry. */
     2695                pImage->PCHSGeometry = *pPCHSGeometry;
     2696
     2697                PVDIDISKGEOMETRY pGeometry = getImageLCHSGeometry(&pImage->Header);
     2698                if (pGeometry)
     2699                {
     2700                    pGeometry->cCylinders = pLCHSGeometry->cCylinders;
     2701                    pGeometry->cHeads = pLCHSGeometry->cHeads;
     2702                    pGeometry->cSectors = pLCHSGeometry->cSectors;
     2703                    pGeometry->cbSector = VDI_GEOMETRY_SECTOR_SIZE;
     2704                }
    26932705            }
    26942706        }
    2695 
    2696         /*
    2697          * We need to update the new offsets for the image data in the out of memory
    2698          * case too because we relocated the blocks already.
    2699          */
    2700         pImage->offStartData = offImageDataNew;
    2701         setImageDataOffset(&pImage->Header, offImageDataNew);
    27022707
    27032708        /* Update header information in base image file. */
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