Changeset 40936 in vbox
- Timestamp:
- Apr 16, 2012 9:28:45 AM (12 years ago)
- Location:
- trunk/src/VBox/Storage
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Storage/VDI.cpp
r40935 r40936 32 32 33 33 #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)) 34 38 35 39 /******************************************************************************* … … 62 66 63 67 /** 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 */ 73 static 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 */ 86 static 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 */ 101 static 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 */ 123 static 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 */ 151 static 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 */ 183 static 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 /** 64 191 * Internal: Flush the image file to disk. 65 192 */ … … 509 636 510 637 /* Write pre-header. */ 638 VDIPREHEADER PreHeader; 639 vdiConvPreHeaderEndianess(VDIECONV_H2F, &PreHeader, &pImage->PreHeader); 511 640 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, 0, 512 & pImage->PreHeader, sizeof(pImage->PreHeader), NULL);641 &PreHeader, sizeof(PreHeader), NULL); 513 642 if (RT_FAILURE(rc)) 514 643 { … … 519 648 520 649 /* Write header. */ 650 VDIHEADER1PLUS Hdr; 651 vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus); 521 652 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); 523 654 if (RT_FAILURE(rc)) 524 655 { … … 528 659 } 529 660 661 vdiConvBlocksEndianess(VDIECONV_H2F, pImage->paBlocks, getImageBlocks(&pImage->Header)); 530 662 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, pImage->offStartBlocks, pImage->paBlocks, 531 663 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER), 532 664 NULL); 665 vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, getImageBlocks(&pImage->Header)); 533 666 if (RT_FAILURE(rc)) 534 667 { … … 631 764 632 765 /* Read pre-header. */ 766 VDIPREHEADER PreHeader; 633 767 rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, 0, 634 & pImage->PreHeader, sizeof(pImage->PreHeader), NULL);768 &PreHeader, sizeof(PreHeader), NULL); 635 769 if (RT_FAILURE(rc)) 636 770 { … … 639 773 goto out; 640 774 } 775 vdiConvPreHeaderEndianess(VDIECONV_F2H, &pImage->PreHeader, &PreHeader); 641 776 rc = vdiValidatePreHeader(&pImage->PreHeader); 642 777 if (RT_FAILURE(rc)) … … 659 794 goto out; 660 795 } 796 vdiConvHeaderEndianessV0(VDIECONV_F2H, &pImage->Header.u.v0, &pImage->Header.u.v0); 661 797 break; 662 798 case 1: … … 669 805 goto out; 670 806 } 807 vdiConvHeaderEndianessV1(VDIECONV_F2H, &pImage->Header.u.v1, &pImage->Header.u.v1); 671 808 /* Convert VDI 1.1 images to VDI 1.1+ on open in read/write mode. 672 809 * Conversion is harmless, as any VirtualBox version supporting VDI … … 694 831 goto out; 695 832 } 833 vdiConvHeaderEndianessV1p(VDIECONV_F2H, &pImage->Header.u.v1plus, &pImage->Header.u.v1plus); 696 834 } 697 835 break; … … 723 861 getImageBlocks(&pImage->Header) * sizeof(VDIIMAGEBLOCKPOINTER), 724 862 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)); 725 869 726 870 if (uOpenFlags & VD_OPEN_FLAGS_DISCARD) … … 782 926 { 783 927 case 0: 928 { 929 VDIHEADER0 Hdr; 930 vdiConvHeaderEndianessV0(VDIECONV_H2F, &Hdr, &pImage->Header.u.v0); 784 931 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); 787 933 break; 934 } 788 935 case 1: 789 936 if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus)) 937 { 938 VDIHEADER1 Hdr; 939 vdiConvHeaderEndianessV1(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1); 790 940 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 } 793 943 else 944 { 945 VDIHEADER1PLUS Hdr; 946 vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus); 794 947 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 } 797 950 break; 798 951 default: … … 813 966 { 814 967 case 0: 968 { 969 VDIHEADER0 Hdr; 970 vdiConvHeaderEndianessV0(VDIECONV_H2F, &Hdr, &pImage->Header.u.v0); 815 971 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), 818 973 pIoCtx, NULL, NULL); 819 974 break; 975 } 820 976 case 1: 821 977 if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus)) 978 { 979 VDIHEADER1 Hdr; 980 vdiConvHeaderEndianessV1(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1); 822 981 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), 825 983 pIoCtx, NULL, NULL); 984 } 826 985 else 986 { 987 VDIHEADER1PLUS Hdr; 988 vdiConvHeaderEndianessV1p(VDIECONV_H2F, &Hdr, &pImage->Header.u.v1plus); 827 989 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), 830 991 pIoCtx, NULL, NULL); 992 } 831 993 break; 832 994 default: … … 849 1011 { 850 1012 /* write only one block pointer. */ 1013 VDIIMAGEBLOCKPOINTER ptrBlock = RT_H2LE_U32(pImage->paBlocks[uBlock]); 851 1014 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, 852 1015 pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER), 853 &p Image->paBlocks[uBlock], sizeof(VDIIMAGEBLOCKPOINTER),1016 &ptrBlock, sizeof(VDIIMAGEBLOCKPOINTER), 854 1017 NULL); 855 1018 AssertMsgRC(rc, ("vdiUpdateBlockInfo failed to update block=%u, filename=\"%s\", rc=%Rrc\n", … … 874 1037 { 875 1038 /* write only one block pointer. */ 1039 VDIIMAGEBLOCKPOINTER ptrBlock = RT_H2LE_U32(pImage->paBlocks[uBlock]); 876 1040 rc = vdIfIoIntFileWriteMetaAsync(pImage->pIfIo, pImage->pStorage, 877 1041 pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER), 878 &pImage->paBlocks[uBlock], 879 sizeof(VDIIMAGEBLOCKPOINTER), 1042 &ptrBlock, sizeof(VDIIMAGEBLOCKPOINTER), 880 1043 pIoCtx, NULL, NULL); 881 1044 AssertMsg(RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS, … … 2880 3043 2881 3044 /* Write the block array before updating the rest. */ 3045 vdiConvBlocksEndianess(VDIECONV_H2F, pImage->paBlocks, cBlocksNew); 2882 3046 rc = vdIfIoIntFileWriteSync(pImage->pIfIo, pImage->pStorage, pImage->offStartBlocks, 2883 3047 pImage->paBlocks, cbBlockspaceNew, NULL); 3048 vdiConvBlocksEndianess(VDIECONV_F2H, pImage->paBlocks, cBlocksNew); 2884 3049 2885 3050 if (RT_SUCCESS(rc)) … … 3232 3397 break; 3233 3398 } 3399 vdiConvPreHeaderEndianess(VDIECONV_F2H, &PreHdr, &PreHdr); 3234 3400 rc = vdiValidatePreHeader(&PreHdr); 3235 3401 if (RT_FAILURE(rc)) … … 3241 3407 3242 3408 /* Read header. */ 3243 Hdr.uVersion = RT_H2LE_U32(PreHdr.u32Version);3409 Hdr.uVersion = PreHdr.u32Version; 3244 3410 switch (GET_MAJOR_HEADER_VERSION(&Hdr)) 3245 3411 { … … 3251 3417 rc = vdIfError(pIfError, rc, RT_SRC_POS, N_("VDI: error reading v0 header in '%s'"), 3252 3418 pszFilename); 3419 vdiConvHeaderEndianessV0(VDIECONV_F2H, &Hdr.u.v0, &Hdr.u.v0); 3253 3420 break; 3254 3421 case 1: … … 3260 3427 pszFilename); 3261 3428 } 3429 vdiConvHeaderEndianessV1(VDIECONV_F2H, &Hdr.u.v1, &Hdr.u.v1); 3262 3430 if (Hdr.u.v1.cbHeader >= sizeof(Hdr.u.v1plus)) 3263 3431 { … … 3269 3437 rc = vdIfError(pIfError, rc, RT_SRC_POS, N_("VDI: error reading v1.1+ header in '%s'"), 3270 3438 pszFilename); 3439 vdiConvHeaderEndianessV1p(VDIECONV_F2H, &Hdr.u.v1plus, &Hdr.u.v1plus); 3271 3440 } 3272 3441 break; … … 3317 3486 break; 3318 3487 } 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)); 3322 3489 3323 3490 pu32BlockBitmap = (uint32_t *)RTMemAllocZ(RT_ALIGN_Z(getImageBlocks(&Hdr) / 8, 4)); … … 3362 3529 else if (!(fFlags & VD_REPAIR_DRY_RUN)) 3363 3530 { 3364 for (uint32_t i = 0; i < getImageBlocks(&Hdr); i++)3365 paBlocks[i] = RT_H2LE_U32(paBlocks[i]);3366 3367 3531 vdIfErrorMessage(pIfError, "Writing repaired block allocation table...\n"); 3368 3532 3533 vdiConvBlocksEndianess(VDIECONV_H2F, paBlocks, getImageBlocks(&Hdr)); 3369 3534 rc = vdIfIoIntFileWriteSync(pIfIo, pStorage, offStartBlocks, paBlocks, 3370 3535 getImageBlocks(&Hdr) * sizeof(VDIIMAGEBLOCKPOINTER), -
trunk/src/VBox/Storage/VDICore.h
r40935 r40936 605 605 } VDIASYNCBLOCKALLOC, *PVDIASYNCBLOCKALLOC; 606 606 607 /** 608 * Endianess conversion direction. 609 */ 610 typedef enum VDIECONV 611 { 612 /** Host to file endianess. */ 613 VDIECONV_H2F = 0, 614 /** File to host endianess. */ 615 VDIECONV_F2H 616 } VDIECONV; 617 607 618 #endif 608 619
Note:
See TracChangeset
for help on using the changeset viewer.

