- Timestamp:
- Mar 15, 2017 12:18:31 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vd-image-backend.h
r64272 r66110 324 324 325 325 /** 326 * Returns a region list for the disk image if supported, optional. 327 * 328 * @returns VBox status code. 329 * @retval VERR_NOT_SUPPORTED if region lists are not supported for this kind of image. 330 * @param pBackendData Opaque state data for this image. 331 * @param ppRegionList Where to store the pointer to the region list on success. 332 */ 333 DECLR3CALLBACKMEMBER(int, pfnQueryRegions, (void *pBackendData, PCVDREGIONLIST *ppRegionList)); 334 335 /** 336 * Releases the region list acquired with VDIMAGEBACKEND::pfnQueryRegions() before. 337 * 338 * @returns nothing. 339 * @param pBackendData Opaque state data for this image. 340 * @param pRegionList The region list to release. 341 */ 342 DECLR3CALLBACKMEMBER(void, pfnRegionListRelease, (void *pBackendData, PCVDREGIONLIST pRegionList)); 343 344 /** 326 345 * Get the image flags of a disk image. 327 346 * … … 589 608 590 609 /** The current version of the VDIMAGEBACKEND structure. */ 591 #define VD_IMGBACKEND_VERSION VD_VERSION_MAKE(0xff01, 1, 0)610 #define VD_IMGBACKEND_VERSION VD_VERSION_MAKE(0xff01, 2, 0) 592 611 593 612 /** @copydoc VDIMAGEBACKEND::pfnComposeLocation */ -
trunk/include/VBox/vd.h
r64272 r66110 494 494 /** Pointer to constant disk geometry. */ 495 495 typedef const VDGEOMETRY *PCVDGEOMETRY; 496 497 /** 498 * Disk region data form known to us from various standards. 499 */ 500 typedef enum VDREGIONDATAFORM 501 { 502 /** Invalid data form. */ 503 VDREGIONDATAFORM_INVALID = 0, 504 /** Raw data, no standardized format. */ 505 VDREGIONDATAFORM_RAW, 506 /** CD-DA (audio CD), 2352 bytes of data. */ 507 VDREGIONDATAFORM_CDDA, 508 /** CDDA data is pause. */ 509 VDREGIONDATAFORM_CDDA_PAUSE, 510 /** Mode 1 with 2048 bytes sector size. */ 511 VDREGIONDATAFORM_MODE1_2048, 512 /** Mode 1 with 2352 bytes sector size. */ 513 VDREGIONDATAFORM_MODE1_2352, 514 /** Mode 1 with 0 bytes sector size (generated by the drive). */ 515 VDREGIONDATAFORM_MODE1_0, 516 /** XA Mode with 2336 bytes sector size. */ 517 VDREGIONDATAFORM_XA_2336, 518 /** XA Mode with 2352 bytes sector size. */ 519 VDREGIONDATAFORM_XA_2352, 520 /** XA Mode with 0 bytes sector size (generated by the drive). */ 521 VDREGIONDATAFORM_XA_0, 522 /** Mode 2 with 2336 bytes sector size. */ 523 VDREGIONDATAFORM_MODE2_2336, 524 /** Mode 2 with 2352 bytes sector size. */ 525 VDREGIONDATAFORM_MODE2_2352, 526 /** Mode 2 with 0 bytes sector size (generated by the drive). */ 527 VDREGIONDATAFORM_MODE2_0 528 } VDREGIONDATAFORM; 529 530 /** 531 * Disk region metadata forms known to us. 532 */ 533 typedef enum VDREGIONMETADATAFORM 534 { 535 /** Invalid metadata form. */ 536 VDREGIONMETADATAFORM_INVALID = 0, 537 /** No metadata assined to the region. */ 538 VDREGIONMETADATAFORM_NONE, 539 /** Raw metadata, no standardized format. */ 540 VDREGIONMETADATAFORM_RAW 541 } VDREGIONMETADATAFORM; 542 543 /** 544 * Disk region descriptor. 545 */ 546 typedef struct VDREGIONDESC 547 { 548 /** Start of the region in bytes or LBA number (depending on the flag in the 549 * list header). */ 550 uint64_t offRegion; 551 /** Overall size of the region in bytes or number of blocks (depending on the 552 * flag in the list header). */ 553 uint64_t cRegionBlocksOrBytes; 554 /** Size of one block in bytes, containing user and metadata. */ 555 uint64_t cbBlock; 556 /** User data form of the block. */ 557 VDREGIONDATAFORM enmDataForm; 558 /** Metadata form of the block. */ 559 VDREGIONMETADATAFORM enmMetadataForm; 560 /** Size of the data block in bytes. */ 561 uint64_t cbData; 562 /** Size of the metadata in a block in bytes. */ 563 uint64_t cbMetadata; 564 } VDREGIONDESC; 565 /** Pointer to a region descriptor. */ 566 typedef VDREGIONDESC *PVDREGIONDESC; 567 /** Pointer to a constant region descriptor. */ 568 typedef const VDREGIONDESC PCVDREGIONDESC; 569 570 /** 571 * Disk region list. 572 */ 573 typedef struct VDREGIONLIST 574 { 575 /** Flags valid for the region list. */ 576 uint32_t fFlags; 577 /** Number of regions in the descriptor array. */ 578 uint32_t cRegions; 579 /** Region descriptors - variable in size. */ 580 VDREGIONDESC aRegions[RT_FLEXIBLE_ARRAY]; 581 } VDREGIONLIST; 582 /** Pointer to a region list. */ 583 typedef VDREGIONLIST *PVDREGIONLIST; 584 /** Pointer to a constant region list. */ 585 typedef const VDREGIONLIST *PCVDREGIONLIST; 586 /** Pointer to a region list pointer. */ 587 typedef PVDREGIONLIST *PPVDREGIONLIST; 588 589 /** @name Valid region list flags. 590 * @{ 591 */ 592 /** When set the region start offset and size are given in numbers of blocks 593 * instead of byte offsets and sizes. */ 594 #define VD_REGION_LIST_F_LOC_SIZE_BLOCKS RT_BIT_32(0) 595 /** Mask of all valid flags. */ 596 #define VD_REGION_LIST_F_VALID (VD_REGION_LIST_F_LOC_SIZE_BLOCKS) 597 /** @} */ 496 598 497 599 /** … … 1129 1231 1130 1232 /** 1233 * Queries the available regions of an image in the given VD container. 1234 * 1235 * @return VBox status code. 1236 * @retval VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened. 1237 * @retval VERR_NOT_SUPPORTED if the image backend doesn't support region lists. 1238 * @param pDisk Pointer to HDD container. 1239 * @param nImage Image number, counts from 0. 0 is always base image of container. 1240 * @param fFlags Combination of VD_REGION_LIST_F_* flags. 1241 * @param ppRegionList Where to store the pointer to the region list on success, must be freed 1242 * with VDRegionListFree(). 1243 */ 1244 VBOXDDU_DECL(int) VDQueryRegions(PVBOXHDD pDisk, unsigned nImage, uint32_t fFlags, 1245 PPVDREGIONLIST ppRegionList); 1246 1247 /** 1248 * Frees a region list previously queried with VDQueryRegions(). 1249 * 1250 * @return nothing. 1251 * @param pRegionList The region list to free. 1252 */ 1253 VBOXDDU_DECL(void) VDRegionListFree(PVDREGIONLIST pRegionList); 1254 1255 /** 1131 1256 * Get version of image in HDD container. 1132 1257 * -
trunk/src/VBox/Storage/DMG.cpp
r64272 r66110 2452 2452 /* pfnSetLCHSGeometry */ 2453 2453 dmgSetLCHSGeometry, 2454 /* pfnQueryRegions */ 2455 NULL, 2456 /* pfnRegionListRelease */ 2457 NULL, 2454 2458 /* pfnGetImageFlags */ 2455 2459 dmgGetImageFlags, -
trunk/src/VBox/Storage/ISCSI.cpp
r64272 r66110 5542 5542 /* pfnSetLCHSGeometry */ 5543 5543 iscsiSetLCHSGeometry, 5544 /* pfnQueryRegions */ 5545 NULL, 5546 /* pfnRegionListRelease */ 5547 NULL, 5544 5548 /* pfnGetImageFlags */ 5545 5549 iscsiGetImageFlags, -
trunk/src/VBox/Storage/Parallels.cpp
r64277 r66110 1113 1113 /* pfnSetLCHSGeometry */ 1114 1114 parallelsSetLCHSGeometry, 1115 /* pfnQueryRegions */ 1116 NULL, 1117 /* pfnRegionListRelease */ 1118 NULL, 1115 1119 /* pfnGetImageFlags */ 1116 1120 parallelsGetImageFlags, -
trunk/src/VBox/Storage/QCOW.cpp
r65644 r66110 2383 2383 /* pfnSetLCHSGeometry */ 2384 2384 qcowSetLCHSGeometry, 2385 /* pfnQueryRegions */ 2386 NULL, 2387 /* pfnRegionListRelease */ 2388 NULL, 2385 2389 /* pfnGetImageFlags */ 2386 2390 qcowGetImageFlags, -
trunk/src/VBox/Storage/QED.cpp
r65644 r66110 2436 2436 /* pfnSetLCHSGeometry */ 2437 2437 qedSetLCHSGeometry, 2438 /* pfnQueryRegions */ 2439 NULL, 2440 /* pfnRegionListRelease */ 2441 NULL, 2438 2442 /* pfnGetImageFlags */ 2439 2443 qedGetImageFlags, -
trunk/src/VBox/Storage/RAW.cpp
r64272 r66110 267 267 else 268 268 rc = vdIfError(pImage->pIfError, VERR_DISK_FULL, RT_SRC_POS, N_("Raw: disk would overflow creating image '%s'"), pImage->pszFilename); 269 } 270 else 271 { 272 rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, cbSize); 273 if (RT_SUCCESS(rc)) 274 pImage->cbSize = cbSize; 269 275 } 270 276 } … … 1001 1007 /* pfnSetLCHSGeometry */ 1002 1008 rawSetLCHSGeometry, 1009 /* pfnQueryRegions */ 1010 NULL, 1011 /* pfnRegionListRelease */ 1012 NULL, 1003 1013 /* pfnGetImageFlags */ 1004 1014 rawGetImageFlags, -
trunk/src/VBox/Storage/VD.cpp
r64766 r66110 5784 5784 5785 5785 RTSemEventSignal(hEvent); 5786 } 5787 5788 /** 5789 * Creates a new region list from the given one converting to match the flags if necessary. 5790 * 5791 * @returns VBox status code. 5792 * @param pRegionList The region list to convert from. 5793 * @param fFlags The flags for the new region list. 5794 * @param ppRegionList Where to store the new region list on success. 5795 */ 5796 static int vdRegionListConv(PCVDREGIONLIST pRegionList, uint32_t fFlags, PPVDREGIONLIST ppRegionList) 5797 { 5798 int rc = VINF_SUCCESS; 5799 PVDREGIONLIST pRegionListNew = (PVDREGIONLIST)RTMemDup(pRegionList, RT_UOFFSETOF(VDREGIONLIST, aRegions[pRegionList->cRegions])); 5800 if (RT_LIKELY(pRegionListNew)) 5801 { 5802 /* Do we have to convert anything? */ 5803 if (pRegionList->fFlags != fFlags) 5804 { 5805 uint64_t offRegionNext = 0; 5806 5807 pRegionListNew->fFlags = fFlags; 5808 for (unsigned i = 0; i < pRegionListNew->cRegions; i++) 5809 { 5810 PVDREGIONDESC pRegion = &pRegionListNew->aRegions[i]; 5811 5812 if ( (fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS) 5813 && !(pRegionList->fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS)) 5814 { 5815 Assert(!(pRegion->cRegionBlocksOrBytes % pRegion->cbBlock)); 5816 5817 /* Convert from bytes to logical blocks. */ 5818 pRegion->offRegion = offRegionNext; 5819 pRegion->cRegionBlocksOrBytes = pRegion->cRegionBlocksOrBytes / pRegion->cbBlock; 5820 offRegionNext += pRegion->cRegionBlocksOrBytes; 5821 } 5822 else 5823 { 5824 /* Convert from logical blocks to bytes. */ 5825 pRegion->offRegion = offRegionNext; 5826 pRegion->cRegionBlocksOrBytes = pRegion->cRegionBlocksOrBytes * pRegion->cbBlock; 5827 offRegionNext += pRegion->cRegionBlocksOrBytes; 5828 } 5829 } 5830 } 5831 5832 *ppRegionList = pRegionListNew; 5833 } 5834 else 5835 rc = VERR_NO_MEMORY; 5836 5837 return rc; 5786 5838 } 5787 5839 … … 10042 10094 10043 10095 /** 10096 * Queries the available regions of an image in the given VD container. 10097 * 10098 * @return VBox status code. 10099 * @retval VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened. 10100 * @retval VERR_NOT_SUPPORTED if the image backend doesn't support region lists. 10101 * @param pDisk Pointer to HDD container. 10102 * @param nImage Image number, counts from 0. 0 is always base image of container. 10103 * @param fFlags Combination of VD_REGION_LIST_F_* flags. 10104 * @param ppRegionList Where to store the pointer to the region list on success, must be freed 10105 * with VDRegionListFree(). 10106 */ 10107 VBOXDDU_DECL(int) VDQueryRegions(PVBOXHDD pDisk, unsigned nImage, uint32_t fFlags, 10108 PPVDREGIONLIST ppRegionList) 10109 { 10110 int rc = VINF_SUCCESS; 10111 int rc2; 10112 bool fLockRead = false; 10113 10114 LogFlowFunc(("pDisk=%#p nImage=%u fFlags=%#x ppRegionList=%#p\n", 10115 pDisk, nImage, fFlags, ppRegionList)); 10116 do 10117 { 10118 /* sanity check */ 10119 AssertPtrBreakStmt(pDisk, rc = VERR_INVALID_PARAMETER); 10120 AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature)); 10121 10122 /* Check arguments. */ 10123 AssertMsgBreakStmt(VALID_PTR(ppRegionList), 10124 ("ppRegionList=%#p\n", ppRegionList), 10125 rc = VERR_INVALID_PARAMETER); 10126 10127 rc2 = vdThreadStartRead(pDisk); 10128 AssertRC(rc2); 10129 fLockRead = true; 10130 10131 PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage); 10132 AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND); 10133 10134 if (pImage->Backend->pfnQueryRegions) 10135 { 10136 PCVDREGIONLIST pRegionList = NULL; 10137 rc = pImage->Backend->pfnQueryRegions(pImage->pBackendData, &pRegionList); 10138 if (RT_SUCCESS(rc)) 10139 { 10140 rc = vdRegionListConv(pRegionList, fFlags, ppRegionList); 10141 10142 AssertPtr(pImage->Backend->pfnRegionListRelease); 10143 pImage->Backend->pfnRegionListRelease(pImage->pBackendData, pRegionList); 10144 } 10145 } 10146 else 10147 rc = VERR_NOT_SUPPORTED; 10148 10149 if (rc == VERR_NOT_SUPPORTED) 10150 { 10151 /* 10152 * Create a list with a single region containing the data gathered from the 10153 * image and sector size. 10154 */ 10155 PVDREGIONLIST pRegionList = (PVDREGIONLIST)RTMemAllocZ(RT_UOFFSETOF(VDREGIONLIST, aRegions[1])); 10156 if (RT_LIKELY(pRegionList)) 10157 { 10158 uint32_t cbSector = pImage->Backend->pfnGetSectorSize(pImage->pBackendData); 10159 uint64_t cbImage = pImage->Backend->pfnGetSize(pImage->pBackendData); 10160 10161 pRegionList->cRegions = 1; 10162 pRegionList->fFlags = fFlags; 10163 10164 /* 10165 * Single region starting at the first byte/block covering the whole image, 10166 * block size equals sector size and contains no metadata. 10167 */ 10168 PVDREGIONDESC pRegion = &pRegionList->aRegions[0]; 10169 pRegion->offRegion = 0; /* Disk start. */ 10170 pRegion->cbBlock = cbSector; 10171 pRegion->enmDataForm = VDREGIONDATAFORM_RAW; 10172 pRegion->enmMetadataForm = VDREGIONMETADATAFORM_NONE; 10173 pRegion->cbData = cbSector; 10174 pRegion->cbMetadata = 0; 10175 if (fFlags & VD_REGION_LIST_F_LOC_SIZE_BLOCKS) 10176 pRegion->cRegionBlocksOrBytes = cbImage / cbSector; 10177 else 10178 pRegion->cRegionBlocksOrBytes = cbImage; 10179 10180 *ppRegionList = pRegionList; 10181 } 10182 else 10183 rc = VERR_NO_MEMORY; 10184 } 10185 } while (0); 10186 10187 if (RT_UNLIKELY(fLockRead)) 10188 { 10189 rc2 = vdThreadFinishRead(pDisk); 10190 AssertRC(rc2); 10191 } 10192 10193 LogFlowFunc((": %Rrc\n", rc)); 10194 return rc; 10195 } 10196 10197 /** 10198 * Frees a region list previously queried with VDQueryRegions(). 10199 * 10200 * @return nothing. 10201 * @param pRegionList The region list to free. 10202 */ 10203 VBOXDDU_DECL(void) VDRegionListFree(PVDREGIONLIST pRegionList) 10204 { 10205 RTMemFree(pRegionList); 10206 } 10207 10208 /** 10044 10209 * Get version of image in HDD container. 10045 10210 * -
trunk/src/VBox/Storage/VDI.cpp
r65644 r66110 3138 3138 /* pfnSetLCHSGeometry */ 3139 3139 vdiSetLCHSGeometry, 3140 /* pfnQueryRegions */ 3141 NULL, 3142 /* pfnRegionListRelease */ 3143 NULL, 3140 3144 /* pfnGetImageFlags */ 3141 3145 vdiGetImageFlags, -
trunk/src/VBox/Storage/VHD.cpp
r64272 r66110 3058 3058 /* pfnSetLCHSGeometry */ 3059 3059 vhdSetLCHSGeometry, 3060 /* pfnQueryRegions */ 3061 NULL, 3062 /* pfnRegionListRelease */ 3063 NULL, 3060 3064 /* pfnGetImageFlags */ 3061 3065 vhdGetImageFlags, -
trunk/src/VBox/Storage/VHDX.cpp
r64272 r66110 2534 2534 /* pfnSetLCHSGeometry */ 2535 2535 vhdxSetLCHSGeometry, 2536 /* pfnQueryRegions */ 2537 NULL, 2538 /* pfnRegionListRelease */ 2539 NULL, 2536 2540 /* pfnGetImageFlags */ 2537 2541 vhdxGetImageFlags, -
trunk/src/VBox/Storage/VMDK.cpp
r64272 r66110 6415 6415 /* pfnSetLCHSGeometry */ 6416 6416 vmdkSetLCHSGeometry, 6417 /* pfnQueryRegions */ 6418 NULL, 6419 /* pfnRegionListRelease */ 6420 NULL, 6417 6421 /* pfnGetImageFlags */ 6418 6422 vmdkGetImageFlags,
Note:
See TracChangeset
for help on using the changeset viewer.