Changeset 31810 in vbox
- Timestamp:
- Aug 20, 2010 10:31:26 AM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 65004
- Location:
- trunk/src/VBox/Devices/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/VDICore.h
r31804 r31810 373 373 { 374 374 case 0: return; 375 case 1: ph->u.v1.offData = offData; 375 case 1: ph->u.v1.offData = offData; return; 376 376 } 377 377 AssertFailed(); -
trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
r31804 r31810 2547 2547 else if (cbSize > getImageDiskSize(&pImage->Header)) 2548 2548 { 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)) 2553 2552 cBlocksNew++; 2554 uint32_t cbAdditionalBlockspace = cBlocksNew * sizeof(VDIIMAGEBLOCKPOINTER); 2555 uint 64_t cbBlockspace = getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER) + cbAdditionalBlockspace;2556 2557 uint64_t off ImageDataNew = RT_ALIGN_32(pImage->offStartBlocks + cbBlockspace, VDI_GEOMETRY_SECTOR_SIZE);2558 2559 if ( pImage->offStartData != off ImageDataNew2553 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 2560 2559 && getImageBlocksAllocated(&pImage->Header) > 0) 2561 2560 { 2562 2561 /* Calculate how many sectors nee to be relocated. */ 2563 uint64_t cbOverlapping = off ImageDataNew - pImage->offStartData;2562 uint64_t cbOverlapping = offStartDataNew - pImage->offStartData; 2564 2563 unsigned cBlocksReloc = cbOverlapping / getImageBlockSize(&pImage->Header); 2565 2564 if (cbOverlapping % getImageBlockSize(&pImage->Header)) 2566 2565 cBlocksReloc++; 2566 2567 cBlocksReloc = RT_MIN(cBlocksReloc, cBlocksAllocated); 2568 offStartDataNew = pImage->offStartData; 2567 2569 2568 2570 /* Do the relocation. */ … … 2576 2578 do 2577 2579 { 2578 uint64_t offBlockCur = pImage->offStartData;2579 2580 VDIIMAGEBLOCKPOINTER uBlock = 0; 2580 2581 … … 2598 2599 { 2599 2600 /* Search the index in the block table. */ 2600 for (unsigned idxBlock = 0; idxBlock < cBlocks Allocated; idxBlock++)2601 for (unsigned idxBlock = 0; idxBlock < cBlocksOld; idxBlock++) 2601 2602 { 2602 2603 if (pImage->paBlocks[idxBlock] == uBlock) 2603 2604 { 2604 2605 /* Read data and append to the end of the image. */ 2605 rc = vdiFileReadSync(pImage, off BlockCur, pvBuf, pImage->cbTotalBlockData, NULL);2606 rc = vdiFileReadSync(pImage, offStartDataNew, pvBuf, pImage->cbTotalBlockData, NULL); 2606 2607 if (RT_FAILURE(rc)) 2607 2608 break; … … 2617 2618 2618 2619 /* Zero out the old block area. */ 2619 rc = vdiFileWriteSync(pImage, off BlockCur, pvZero, pImage->cbTotalBlockData, NULL);2620 rc = vdiFileWriteSync(pImage, offStartDataNew, pvZero, pImage->cbTotalBlockData, NULL); 2620 2621 if (RT_FAILURE(rc)) 2621 2622 break; 2622 2623 2623 2624 /* Update block counter. */ 2624 pImage->paBlocks[idxBlock] = cBlocksAllocated ;2625 pImage->paBlocks[idxBlock] = cBlocksAllocated - 1; 2625 2626 2626 2627 /* … … 2628 2629 * They were moved one block to the front. 2629 2630 * Doing it as a separate step iterating over the array again 2630 * because an error while relocating the oneblock might end up2631 * because an error while relocating the block might end up 2631 2632 * in a corrupted image otherwise. 2632 2633 */ 2633 for (unsigned idxBlock2 = 0; idxBlock2 < cBlocks Allocated; idxBlock2++)2634 for (unsigned idxBlock2 = 0; idxBlock2 < cBlocksOld; idxBlock2++) 2634 2635 { 2635 2636 if ( idxBlock2 != idxBlock … … 2637 2638 pImage->paBlocks[idxBlock2]--; 2638 2639 } 2640 2641 /* Continue with the next block. */ 2642 break; 2639 2643 } 2640 2644 } … … 2644 2648 2645 2649 uBlock++; 2646 off BlockCur+= pImage->cbTotalBlockData;2650 offStartDataNew += pImage->cbTotalBlockData; 2647 2651 } 2648 2652 } while (0); … … 2653 2657 RTMemFree(pvZero); 2654 2658 } 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); 2655 2666 2656 2667 /* … … 2660 2671 if (RT_SUCCESS(rc)) 2661 2672 { 2662 PVDIIMAGEBLOCKPOINTER paBlocksNew = (PVDIIMAGEBLOCKPOINTER)RTMemRealloc(pImage->paBlocks, getImageBlocks(&pImage->Header) + cBlocksNew);2673 PVDIIMAGEBLOCKPOINTER paBlocksNew = (PVDIIMAGEBLOCKPOINTER)RTMemRealloc(pImage->paBlocks, cbBlockspaceNew); 2663 2674 if (paBlocksNew) 2664 2675 { 2676 pImage->paBlocks = paBlocksNew; 2677 2665 2678 /* 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++) 2667 2680 pImage->paBlocks[idxBlock] = VDI_IMAGE_BLOCK_FREE; 2668 2681 } … … 2672 2685 /* Write the block array before updating the rest. */ 2673 2686 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)) 2688 2690 { 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 } 2693 2705 } 2694 2706 } 2695 2696 /*2697 * We need to update the new offsets for the image data in the out of memory2698 * case too because we relocated the blocks already.2699 */2700 pImage->offStartData = offImageDataNew;2701 setImageDataOffset(&pImage->Header, offImageDataNew);2702 2707 2703 2708 /* Update header information in base image file. */
Note:
See TracChangeset
for help on using the changeset viewer.