VHD Performance enhancementsDaa:
optimize BAT updates when writing to previously unwritten data blocks data block alignment for optimal behavior on Advance Format host disks (4096 sectors)
This commit is contained in:
parent
321b05c705
commit
2a9ac8a830
1 changed files with 61 additions and 27 deletions
88
sim_disk.c
88
sim_disk.c
|
@ -2902,11 +2902,11 @@ if (!hVHD) {
|
|||
}
|
||||
LocatorPosition = NtoHll (hVHD->Dynamic.TableOffset)+BytesPerSector*((NtoHl (hVHD->Dynamic.MaxTableEntries)*sizeof(*hVHD->BAT)+BytesPerSector-1)/BytesPerSector);
|
||||
hVHD->Dynamic.Checksum = 0;
|
||||
RelativeParentVHDPath = calloc (1, BytesPerSector+1);
|
||||
FullParentVHDPath = calloc (1, BytesPerSector+1);
|
||||
RelativeParentVHDPathBuffer = calloc (1, BytesPerSector);
|
||||
FullParentVHDPathBuffer = calloc (1, BytesPerSector);
|
||||
FullVHDPath = calloc (1, BytesPerSector+1);
|
||||
RelativeParentVHDPath = calloc (1, BytesPerSector+2);
|
||||
FullParentVHDPath = calloc (1, BytesPerSector+2);
|
||||
RelativeParentVHDPathBuffer = calloc (1, BytesPerSector+2);
|
||||
FullParentVHDPathBuffer = calloc (1, BytesPerSector+2);
|
||||
FullVHDPath = calloc (1, BytesPerSector+2);
|
||||
ExpandToFullPath (szParentVHDPath, FullParentVHDPath, BytesPerSector);
|
||||
for (i=0; i < strlen (FullParentVHDPath); i++)
|
||||
hVHD->Dynamic.ParentUnicodeName[i*2+1] = FullParentVHDPath[i];
|
||||
|
@ -3240,8 +3240,13 @@ while (sects) {
|
|||
}
|
||||
SectorsInWrite = 1;
|
||||
if (hVHD->BAT[BlockNumber] == VHD_BAT_FREE_ENTRY) {
|
||||
void *BitMap = NULL;
|
||||
uint8 *BitMap = NULL;
|
||||
uint32 BitMapBufferSize = VHD_DATA_BLOCK_ALIGNMENT;
|
||||
uint8 *BitMapBuffer = NULL;
|
||||
void *BlockData = NULL;
|
||||
uint8 *BATUpdateBufferAddress;
|
||||
uint32 BATUpdateBufferSize;
|
||||
uint64 BATUpdateStorageAddress;
|
||||
|
||||
if (!hVHD->Parent && BufferIsZeros(buf, SectorSize))
|
||||
goto IO_Done;
|
||||
|
@ -3249,28 +3254,51 @@ while (sects) {
|
|||
BlockOffset = sim_fsize_ex (hVHD->File);
|
||||
if (((int64)BlockOffset) == -1)
|
||||
return SCPE_IOERR;
|
||||
BitMap = malloc(BitMapSectors*SectorSize);
|
||||
if (BitMapSectors*SectorSize > BitMapBufferSize)
|
||||
BitMapBufferSize = BitMapSectors*SectorSize;
|
||||
BitMapBuffer = calloc(1, BitMapBufferSize + SectorSize*SectorsPerBlock);
|
||||
if (BitMapBufferSize > BitMapSectors*SectorSize)
|
||||
BitMap = BitMapBuffer + BitMapBufferSize-BitMapBytes;
|
||||
else
|
||||
BitMap = BitMapBuffer;
|
||||
memset(BitMap, 0xFF, BitMapBytes);
|
||||
BlockOffset -= sizeof(hVHD->Footer);
|
||||
/* align the data portion of the block to the desired alignment */
|
||||
/* compute the address of the data portion of the block */
|
||||
BlockOffset += BitMapSectors*SectorSize;
|
||||
/* round up this address to the desired alignment */
|
||||
BlockOffset += VHD_DATA_BLOCK_ALIGNMENT-1;
|
||||
BlockOffset &= ~(VHD_DATA_BLOCK_ALIGNMENT-1);
|
||||
/* the actual block address is the beginning of the block bitmap */
|
||||
if (0 == (BlockOffset & ~(VHD_DATA_BLOCK_ALIGNMENT-1)))
|
||||
{ // Already aligned, so use padded BitMapBuffer
|
||||
if (WriteFilePosition(hVHD->File,
|
||||
BitMapBuffer,
|
||||
BitMapBufferSize + SectorSize*SectorsPerBlock,
|
||||
NULL,
|
||||
BlockOffset)) {
|
||||
free (BitMapBuffer);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
BlockOffset += BitMapBufferSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// align the data portion of the block to the desired alignment
|
||||
// compute the address of the data portion of the block
|
||||
BlockOffset += BitMapSectors*SectorSize;
|
||||
// round up this address to the desired alignment
|
||||
BlockOffset += VHD_DATA_BLOCK_ALIGNMENT-1;
|
||||
BlockOffset &= ~(VHD_DATA_BLOCK_ALIGNMENT-1);
|
||||
BlockOffset -= BitMapSectors*SectorSize;
|
||||
if (WriteFilePosition(hVHD->File,
|
||||
BitMap,
|
||||
SectorSize * (BitMapSectors + SectorsPerBlock),
|
||||
NULL,
|
||||
BlockOffset)) {
|
||||
free (BitMapBuffer);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
BlockOffset += BitMapSectors*SectorSize;
|
||||
}
|
||||
free(BitMapBuffer);
|
||||
BitMapBuffer = BitMap = NULL;
|
||||
/* the BAT block address is the beginning of the block bitmap */
|
||||
BlockOffset -= BitMapSectors*SectorSize;
|
||||
hVHD->BAT[BlockNumber] = NtoHl((uint32)(BlockOffset/SectorSize));
|
||||
if (WriteFilePosition(hVHD->File,
|
||||
BitMap,
|
||||
BitMapSectors*SectorSize,
|
||||
NULL,
|
||||
BlockOffset)) {
|
||||
free (BitMap);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
free(BitMap);
|
||||
BitMap = NULL;
|
||||
BlockOffset += SectorSize * (SectorsPerBlock + BitMapSectors);
|
||||
if (WriteFilePosition(hVHD->File,
|
||||
&hVHD->Footer,
|
||||
|
@ -3278,11 +3306,17 @@ while (sects) {
|
|||
NULL,
|
||||
BlockOffset))
|
||||
goto Fatal_IO_Error;
|
||||
BATUpdateBufferAddress = ((uint8 *)hVHD->BAT) +
|
||||
(((((size_t)&hVHD->BAT[BlockNumber]) - ((size_t)hVHD->BAT) + VHD_DATA_BLOCK_ALIGNMENT - 1)/VHD_DATA_BLOCK_ALIGNMENT)*VHD_DATA_BLOCK_ALIGNMENT);
|
||||
BATUpdateBufferSize = SectorSize*((sizeof(*hVHD->BAT)*NtoHl(hVHD->Dynamic.MaxTableEntries)+511)/512);
|
||||
if (BATUpdateBufferSize > VHD_DATA_BLOCK_ALIGNMENT)
|
||||
BATUpdateBufferSize = VHD_DATA_BLOCK_ALIGNMENT;
|
||||
BATUpdateStorageAddress = NtoHll(hVHD->Dynamic.TableOffset) + BATUpdateBufferAddress - ((uint8 *)hVHD->BAT);
|
||||
if (WriteFilePosition(hVHD->File,
|
||||
hVHD->BAT,
|
||||
SectorSize*((sizeof(*hVHD->BAT)*NtoHl(hVHD->Dynamic.MaxTableEntries)+511)/512),
|
||||
BATUpdateBufferAddress,
|
||||
BATUpdateBufferSize,
|
||||
NULL,
|
||||
NtoHll(hVHD->Dynamic.TableOffset)))
|
||||
BATUpdateStorageAddress))
|
||||
goto Fatal_IO_Error;
|
||||
if (hVHD->Parent)
|
||||
{ /* Need to populate data block contents from parent VHD */
|
||||
|
|
Loading…
Add table
Reference in a new issue