summaryrefslogtreecommitdiff
path: root/src/VBox/Storage/VHDX.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Storage/VHDX.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Storage/VHDX.cpp')
-rw-r--r--src/VBox/Storage/VHDX.cpp158
1 files changed, 92 insertions, 66 deletions
diff --git a/src/VBox/Storage/VHDX.cpp b/src/VBox/Storage/VHDX.cpp
index 035f3d04..35d99e8d 100644
--- a/src/VBox/Storage/VHDX.cpp
+++ b/src/VBox/Storage/VHDX.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2012 Oracle Corporation
+ * Copyright (C) 2012-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -510,40 +510,40 @@ typedef struct VHDXMETADATAITEMPROPS
typedef struct VHDXIMAGE
{
/** Image name. */
- const char *pszFilename;
+ const char *pszFilename;
/** Storage handle. */
- PVDIOSTORAGE pStorage;
+ PVDIOSTORAGE pStorage;
/** Pointer to the per-disk VD interface list. */
- PVDINTERFACE pVDIfsDisk;
+ PVDINTERFACE pVDIfsDisk;
/** Pointer to the per-image VD interface list. */
- PVDINTERFACE pVDIfsImage;
+ PVDINTERFACE pVDIfsImage;
/** Error interface. */
- PVDINTERFACEERROR pIfError;
+ PVDINTERFACEERROR pIfError;
/** I/O interface. */
- PVDINTERFACEIOINT pIfIo;
+ PVDINTERFACEIOINT pIfIo;
/** Open flags passed by VBoxHD layer. */
- unsigned uOpenFlags;
+ unsigned uOpenFlags;
/** Image flags defined during creation or determined during open. */
- unsigned uImageFlags;
+ unsigned uImageFlags;
/** Version of the VHDX image format. */
- unsigned uVersion;
+ unsigned uVersion;
/** Total size of the image. */
- uint64_t cbSize;
+ uint64_t cbSize;
/** Logical sector size of the image. */
- size_t cbLogicalSector;
+ uint32_t cbLogicalSector;
/** Block size of the image. */
- size_t cbBlock;
+ size_t cbBlock;
/** Physical geometry of this image. */
- VDGEOMETRY PCHSGeometry;
+ VDGEOMETRY PCHSGeometry;
/** Logical geometry of this image. */
- VDGEOMETRY LCHSGeometry;
+ VDGEOMETRY LCHSGeometry;
/** The BAT. */
- PVhdxBatEntry paBat;
+ PVhdxBatEntry paBat;
/** Chunk ratio. */
- uint32_t uChunkRatio;
+ uint32_t uChunkRatio;
} VHDXIMAGE, *PVHDXIMAGE;
@@ -586,7 +586,7 @@ static const VHDXMETADATAITEMPROPS s_aVhdxMetadataItemProps[] =
{VHDX_METADATA_TBL_ENTRY_ITEM_VDISK_SIZE, false, true, true, VHDXMETADATAITEM_VDISK_SIZE},
{VHDX_METADATA_TBL_ENTRY_ITEM_PAGE83_DATA, false, true, true, VHDXMETADATAITEM_PAGE83_DATA},
{VHDX_METADATA_TBL_ENTRY_ITEM_LOG_SECT_SIZE, false, true, true, VHDXMETADATAITEM_LOGICAL_SECTOR_SIZE},
- {VHDX_METADATA_TBL_ENTRY_ITEM_PHYS_SECT_SIZE, false, true, false, VHDXMETADATAITEM_PHYSICAL_SECTOR_SIZE},
+ {VHDX_METADATA_TBL_ENTRY_ITEM_PHYS_SECT_SIZE, false, true, true, VHDXMETADATAITEM_PHYSICAL_SECTOR_SIZE},
{VHDX_METADATA_TBL_ENTRY_ITEM_PARENT_LOCATOR, false, false, true, VHDXMETADATAITEM_PARENT_LOCATOR}
};
@@ -970,7 +970,7 @@ static int vhdxFreeImage(PVHDXIMAGE pImage, bool fDelete)
{
if (pImage->pStorage)
{
- vdIfIoIntFileClose(pImage->pIfIo, pImage->pStorage);
+ rc = vdIfIoIntFileClose(pImage->pIfIo, pImage->pStorage);
pImage->pStorage = NULL;
}
@@ -1055,7 +1055,7 @@ static int vhdxFindAndLoadCurrentHeader(PVHDXIMAGE pImage)
{
/* Read the first header. */
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, VHDX_HEADER1_OFFSET,
- pHdr1, sizeof(*pHdr1), NULL);
+ pHdr1, sizeof(*pHdr1));
if (RT_SUCCESS(rc))
{
vhdxConvHeaderEndianess(VHDXECONV_F2H, pHdr1, pHdr1);
@@ -1063,7 +1063,7 @@ static int vhdxFindAndLoadCurrentHeader(PVHDXIMAGE pImage)
/* Validate checksum. */
u32ChkSumSaved = pHdr1->u32Checksum;
pHdr1->u32Checksum = 0;
- //u32ChkSum = RTCrc32C(pHdr1, sizeof(*pHdr1));
+ //u32ChkSum = RTCrc32C(pHdr1, RT_OFFSETOF(VhdxHeader, u8Reserved[502]));
if ( pHdr1->u32Signature == VHDX_HEADER_SIGNATURE
/*&& u32ChkSum == u32ChkSumSaved*/)
@@ -1072,7 +1072,7 @@ static int vhdxFindAndLoadCurrentHeader(PVHDXIMAGE pImage)
/* Try to read the second header in any case (even if reading the first failed). */
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, VHDX_HEADER2_OFFSET,
- pHdr2, sizeof(*pHdr2), NULL);
+ pHdr2, sizeof(*pHdr2));
if (RT_SUCCESS(rc))
{
vhdxConvHeaderEndianess(VHDXECONV_F2H, pHdr2, pHdr2);
@@ -1080,7 +1080,7 @@ static int vhdxFindAndLoadCurrentHeader(PVHDXIMAGE pImage)
/* Validate checksum. */
u32ChkSumSaved = pHdr2->u32Checksum;
pHdr2->u32Checksum = 0;
- //u32ChkSum = RTCrc32C(pHdr2, sizeof(*pHdr2));
+ //u32ChkSum = RTCrc32C(pHdr2, RT_OFFSETOF(VhdxHeader, u8Reserved[502]));
if ( pHdr2->u32Signature == VHDX_HEADER_SIGNATURE
/*&& u32ChkSum == u32ChkSumSaved*/)
@@ -1143,8 +1143,11 @@ static int vhdxLoadBatRegion(PVHDXIMAGE pImage, uint64_t offRegion,
LogFlowFunc(("pImage=%#p\n", pImage));
/* Calculate required values first. */
- uChunkRatio = (RT_BIT_64(23) * pImage->cbLogicalSector) / pImage->cbBlock;
- cDataBlocks = pImage->cbSize / pImage->cbBlock;
+ uint64_t uChunkRatio64 = (RT_BIT_64(23) * pImage->cbLogicalSector) / pImage->cbBlock;
+ uChunkRatio = (uint32_t)uChunkRatio64; Assert(uChunkRatio == uChunkRatio64);
+ uint64_t cDataBlocks64 = pImage->cbSize / pImage->cbBlock;
+ cDataBlocks = (uint32_t)cDataBlocks64; Assert(cDataBlocks == cDataBlocks64);
+
if (pImage->cbSize % pImage->cbBlock)
cDataBlocks++;
@@ -1165,7 +1168,7 @@ static int vhdxLoadBatRegion(PVHDXIMAGE pImage, uint64_t offRegion,
if (paBatEntries)
{
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, offRegion,
- paBatEntries, cbBatEntries, NULL);
+ paBatEntries, cbBatEntries);
if (RT_SUCCESS(rc))
{
vhdxConvBatTableEndianess(VHDXECONV_F2H, paBatEntries, paBatEntries,
@@ -1177,6 +1180,12 @@ static int vhdxLoadBatRegion(PVHDXIMAGE pImage, uint64_t offRegion,
if ( i != 0
&& (i % uChunkRatio) == 0)
{
+/**
+ * Disabled the verification because there are images out there with the sector bitmap
+ * marked as present. The entry is never accessed and the image is readonly anyway,
+ * so no harm done.
+ */
+#if 0
/* Sector bitmap block. */
if ( VHDX_BAT_ENTRY_GET_STATE(paBatEntries[i].u64BatEntry)
!= VHDX_BAT_ENTRY_SB_BLOCK_NOT_PRESENT)
@@ -1186,6 +1195,7 @@ static int vhdxLoadBatRegion(PVHDXIMAGE pImage, uint64_t offRegion,
i, pImage->pszFilename);
break;
}
+#endif
}
else
{
@@ -1253,7 +1263,7 @@ static int vhdxLoadFileParametersMetadata(PVHDXIMAGE pImage, uint64_t offItem, s
VhdxFileParameters FileParameters;
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, offItem,
- &FileParameters, sizeof(FileParameters), NULL);
+ &FileParameters, sizeof(FileParameters));
if (RT_SUCCESS(rc))
{
vhdxConvFileParamsEndianess(VHDXECONV_F2H, &FileParameters, &FileParameters);
@@ -1298,7 +1308,7 @@ static int vhdxLoadVDiskSizeMetadata(PVHDXIMAGE pImage, uint64_t offItem, size_t
VhdxVDiskSize VDiskSize;
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, offItem,
- &VDiskSize, sizeof(VDiskSize), NULL);
+ &VDiskSize, sizeof(VDiskSize));
if (RT_SUCCESS(rc))
{
vhdxConvVDiskSizeEndianess(VHDXECONV_F2H, &VDiskSize, &VDiskSize);
@@ -1337,7 +1347,7 @@ static int vhdxLoadVDiskLogSectorSizeMetadata(PVHDXIMAGE pImage, uint64_t offIte
VhdxVDiskLogicalSectorSize VDiskLogSectSize;
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, offItem,
- &VDiskLogSectSize, sizeof(VDiskLogSectSize), NULL);
+ &VDiskLogSectSize, sizeof(VDiskLogSectSize));
if (RT_SUCCESS(rc))
{
vhdxConvVDiskLogSectSizeEndianess(VHDXECONV_F2H, &VDiskLogSectSize,
@@ -1372,7 +1382,7 @@ static int vhdxLoadMetadataRegion(PVHDXIMAGE pImage, uint64_t offRegion,
/* Load the header first. */
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, offRegion,
- &MetadataTblHdr, sizeof(MetadataTblHdr), NULL);
+ &MetadataTblHdr, sizeof(MetadataTblHdr));
if (RT_SUCCESS(rc))
{
vhdxConvMetadataTblHdrEndianess(VHDXECONV_F2H, &MetadataTblHdr, &MetadataTblHdr);
@@ -1402,7 +1412,7 @@ static int vhdxLoadMetadataRegion(PVHDXIMAGE pImage, uint64_t offRegion,
VhdxMetadataTblEntry MetadataTblEntry;
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, offMetadataTblEntry,
- &MetadataTblEntry, sizeof(MetadataTblEntry), NULL);
+ &MetadataTblEntry, sizeof(MetadataTblEntry));
if (RT_FAILURE(rc))
{
rc = vdIfError(pImage->pIfError, rc, RT_SRC_POS,
@@ -1419,6 +1429,12 @@ static int vhdxLoadMetadataRegion(PVHDXIMAGE pImage, uint64_t offRegion,
if (!RTUuidCompareStr(&MetadataTblEntry.UuidItem,
s_aVhdxMetadataItemProps[idxProp].pszItemUuid))
{
+ /*
+ * Check for specification violations and bail out, except
+ * for the required flag of the physical sector size metadata item.
+ * Early images had the required flag not set opposed to the specification.
+ * We don't want to brerak those images.
+ */
if ( !!(MetadataTblEntry.u32Flags & VHDX_METADATA_TBL_ENTRY_FLAGS_IS_USER)
!= s_aVhdxMetadataItemProps[idxProp].fIsUser)
rc = vdIfError(pImage->pIfError, VERR_VD_GEN_INVALID_HEADER, RT_SRC_POS,
@@ -1429,8 +1445,9 @@ static int vhdxLoadMetadataRegion(PVHDXIMAGE pImage, uint64_t offRegion,
rc = vdIfError(pImage->pIfError, VERR_VD_GEN_INVALID_HEADER, RT_SRC_POS,
"VHDX: Virtual disk flag of metadata item does not meet expectations \'%s\'",
pImage->pszFilename);
- else if ( !!(MetadataTblEntry.u32Flags & VHDX_METADATA_TBL_ENTRY_FLAGS_IS_REQUIRED)
- != s_aVhdxMetadataItemProps[idxProp].fIsRequired)
+ else if ( !!(MetadataTblEntry.u32Flags & VHDX_METADATA_TBL_ENTRY_FLAGS_IS_REQUIRED)
+ != s_aVhdxMetadataItemProps[idxProp].fIsRequired
+ && (s_aVhdxMetadataItemProps[idxProp].enmMetadataItem != VHDXMETADATAITEM_PHYSICAL_SECTOR_SIZE))
rc = vdIfError(pImage->pIfError, VERR_VD_GEN_INVALID_HEADER, RT_SRC_POS,
"VHDX: Required flag of metadata item does not meet expectations \'%s\'",
pImage->pszFilename);
@@ -1533,7 +1550,7 @@ static int vhdxLoadRegionTable(PVHDXIMAGE pImage)
if (pbRegionTbl)
{
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, VHDX_REGION_TBL_HDR_OFFSET,
- pbRegionTbl, VHDX_REGION_TBL_SIZE_MAX, NULL);
+ pbRegionTbl, VHDX_REGION_TBL_SIZE_MAX);
if (RT_SUCCESS(rc))
{
PVhdxRegionTblHdr pRegionTblHdr;
@@ -1574,8 +1591,9 @@ static int vhdxLoadRegionTable(PVHDXIMAGE pImage)
{
/* Parse the region table entries. */
PVhdxRegionTblEntry pRegTblEntry = (PVhdxRegionTblEntry)(pbRegionTbl + sizeof(VhdxRegionTblHdr));
- VhdxRegionTblEntry RegTblEntryBat; /**<< BAT region table entry. */
+ VhdxRegionTblEntry RegTblEntryBat; /* BAT region table entry. */
bool fBatRegPresent = false;
+ RT_ZERO(RegTblEntryBat); /* Maybe uninitialized, gcc. */
for (unsigned i = 0; i < RegionTblHdr.u32EntryCount; i++)
{
@@ -1663,11 +1681,9 @@ static int vhdxOpenImage(PVHDXIMAGE pImage, unsigned uOpenFlags)
pImage->pIfIo = VDIfIoIntGet(pImage->pVDIfsImage);
AssertPtrReturn(pImage->pIfIo, VERR_INVALID_PARAMETER);
-#if 0
/* Refuse write access, it is not implemented so far. */
if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY))
return VERR_NOT_SUPPORTED;
-#endif
/*
* Open the image.
@@ -1687,7 +1703,7 @@ static int vhdxOpenImage(PVHDXIMAGE pImage, unsigned uOpenFlags)
if (cbFile > sizeof(FileIdentifier))
{
rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, VHDX_FILE_IDENTIFIER_OFFSET,
- &FileIdentifier, sizeof(FileIdentifier), NULL);
+ &FileIdentifier, sizeof(FileIdentifier));
if (RT_SUCCESS(rc))
{
vhdxConvFileIdentifierEndianess(VHDXECONV_F2H, &FileIdentifier,
@@ -1747,7 +1763,7 @@ static int vhdxCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk,
if (cbFile > sizeof(FileIdentifier))
{
rc = vdIfIoIntFileReadSync(pIfIo, pStorage, VHDX_FILE_IDENTIFIER_OFFSET,
- &FileIdentifier, sizeof(FileIdentifier), NULL);
+ &FileIdentifier, sizeof(FileIdentifier));
if (RT_SUCCESS(rc))
{
vhdxConvFileIdentifierEndianess(VHDXECONV_F2H, &FileIdentifier,
@@ -1865,10 +1881,11 @@ static int vhdxClose(void *pBackendData, bool fDelete)
}
/** @copydoc VBOXHDDBACKEND::pfnRead */
-static int vhdxRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
- size_t cbToRead, size_t *pcbActuallyRead)
+static int vhdxRead(void *pBackendData, uint64_t uOffset, size_t cbToRead,
+ PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
{
- LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToRead=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbToRead, pcbActuallyRead));
+ LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToRead=%zu pcbActuallyRead=%#p\n",
+ pBackendData, uOffset, pIoCtx, cbToRead, pcbActuallyRead));
PVHDXIMAGE pImage = (PVHDXIMAGE)pBackendData;
int rc = VINF_SUCCESS;
@@ -1881,7 +1898,7 @@ static int vhdxRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
rc = VERR_INVALID_PARAMETER;
else
{
- uint32_t idxBat = uOffset / pImage->cbBlock;
+ uint32_t idxBat = (uint32_t)(uOffset / pImage->cbBlock); Assert(idxBat == uOffset / pImage->cbBlock);
uint32_t offRead = uOffset % pImage->cbBlock;
uint64_t uBatEntry;
@@ -1897,14 +1914,14 @@ static int vhdxRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
case VHDX_BAT_ENTRY_PAYLOAD_BLOCK_ZERO:
case VHDX_BAT_ENTRY_PAYLOAD_BLOCK_UNMAPPED:
{
- memset(pvBuf, 0, cbToRead);
+ vdIfIoIntIoCtxSet(pImage->pIfIo, pIoCtx, 0, cbToRead);
break;
}
case VHDX_BAT_ENTRY_PAYLOAD_BLOCK_FULLY_PRESENT:
{
uint64_t offFile = VHDX_BAT_ENTRY_GET_FILE_OFFSET(uBatEntry) + offRead;
- rc = vdIfIoIntFileReadSync(pImage->pIfIo, pImage->pStorage, offFile,
- pvBuf, cbToRead, NULL);
+ rc = vdIfIoIntFileReadUser(pImage->pIfIo, pImage->pStorage, offFile,
+ pIoCtx, cbToRead);
break;
}
case VHDX_BAT_ENTRY_PAYLOAD_BLOCK_PARTIALLY_PRESENT:
@@ -1922,12 +1939,12 @@ static int vhdxRead(void *pBackendData, uint64_t uOffset, void *pvBuf,
}
/** @copydoc VBOXHDDBACKEND::pfnWrite */
-static int vhdxWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf,
- size_t cbToWrite, size_t *pcbWriteProcess,
- size_t *pcbPreRead, size_t *pcbPostRead, unsigned fWrite)
+static int vhdxWrite(void *pBackendData, uint64_t uOffset, size_t cbToWrite,
+ PVDIOCTX pIoCtx, size_t *pcbWriteProcess, size_t *pcbPreRead,
+ size_t *pcbPostRead, unsigned fWrite)
{
- LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToWrite=%zu pcbWriteProcess=%#p pcbPreRead=%#p pcbPostRead=%#p\n",
- pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess, pcbPreRead, pcbPostRead));
+ LogFlowFunc(("pBackendData=%#p uOffset=%llu pIoCtx=%#p cbToWrite=%zu pcbWriteProcess=%#p pcbPreRead=%#p pcbPostRead=%#p\n",
+ pBackendData, uOffset, pIoCtx, cbToWrite, pcbWriteProcess, pcbPreRead, pcbPostRead));
PVHDXIMAGE pImage = (PVHDXIMAGE)pBackendData;
int rc;
@@ -1948,9 +1965,9 @@ static int vhdxWrite(void *pBackendData, uint64_t uOffset, const void *pvBuf,
}
/** @copydoc VBOXHDDBACKEND::pfnFlush */
-static int vhdxFlush(void *pBackendData)
+static int vhdxFlush(void *pBackendData, PVDIOCTX pIoCtx)
{
- LogFlowFunc(("pBackendData=%#p\n", pBackendData));
+ LogFlowFunc(("pBackendData=%#p pIoCtx=%#p\n", pBackendData, pIoCtx));
PVHDXIMAGE pImage = (PVHDXIMAGE)pBackendData;
int rc;
@@ -1977,6 +1994,22 @@ static unsigned vhdxGetVersion(void *pBackendData)
return 0;
}
+/** @copydoc VBOXHDDBACKEND::pfnGetSectorSize */
+static uint32_t vhdxGetSectorSize(void *pBackendData)
+{
+ LogFlowFunc(("pBackendData=%#p\n", pBackendData));
+ PVHDXIMAGE pImage = (PVHDXIMAGE)pBackendData;
+ uint32_t cb = 0;
+
+ AssertPtr(pImage);
+
+ if (pImage && pImage->pStorage)
+ cb = pImage->cbLogicalSector;
+
+ LogFlowFunc(("returns %u\n", cb));
+ return cb;
+}
+
/** @copydoc VBOXHDDBACKEND::pfnGetSize */
static uint64_t vhdxGetSize(void *pBackendData)
{
@@ -2064,7 +2097,6 @@ static int vhdxSetPCHSGeometry(void *pBackendData,
else
rc = VERR_VD_NOT_OPENED;
-out:
LogFlowFunc(("returns %Rrc\n", rc));
return rc;
}
@@ -2161,7 +2193,7 @@ static int vhdxSetOpenFlags(void *pBackendData, unsigned uOpenFlags)
int rc = VINF_SUCCESS;
/* Image must be opened and the new flags must be valid. */
- if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO)))
+ if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_SKIP_CONSISTENCY_CHECKS)))
rc = VERR_INVALID_PARAMETER;
else
{
@@ -2390,7 +2422,7 @@ static void vhdxDump(void *pBackendData)
AssertPtr(pImage);
if (pImage)
{
- vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%zu\n",
+ vdIfErrorMessage(pImage->pIfError, "Header: Geometry PCHS=%u/%u/%u LCHS=%u/%u/%u cbSector=%u\n",
pImage->PCHSGeometry.cCylinders, pImage->PCHSGeometry.cHeads, pImage->PCHSGeometry.cSectors,
pImage->LCHSGeometry.cCylinders, pImage->LCHSGeometry.cHeads, pImage->LCHSGeometry.cSectors,
pImage->cbLogicalSector);
@@ -2428,8 +2460,12 @@ VBOXHDDBACKEND g_VhdxBackend =
vhdxWrite,
/* pfnFlush */
vhdxFlush,
+ /* pfnDiscard */
+ NULL,
/* pfnGetVersion */
vhdxGetVersion,
+ /* pfnGetSectorSize */
+ vhdxGetSectorSize,
/* pfnGetSize */
vhdxGetSize,
/* pfnGetFileSize */
@@ -2480,12 +2516,6 @@ VBOXHDDBACKEND g_VhdxBackend =
NULL,
/* pfnSetParentFilename */
NULL,
- /* pfnAsyncRead */
- NULL,
- /* pfnAsyncWrite */
- NULL,
- /* pfnAsyncFlush */
- NULL,
/* pfnComposeLocation */
genericFileComposeLocation,
/* pfnComposeName */
@@ -2494,10 +2524,6 @@ VBOXHDDBACKEND g_VhdxBackend =
NULL,
/* pfnResize */
NULL,
- /* pfnDiscard */
- NULL,
- /* pfnAsyncDiscard */
- NULL,
/* pfnRepair */
NULL
};