VAX, PDP11: Fix VHD support to save the correct updated part of the Block Allocation Table (BAT) when new blocks are added to a VHD.

This commit is contained in:
Mark Pizzolato 2014-09-03 13:21:38 -07:00
parent b2aaec0b3e
commit 0dff1076a0

View file

@ -3821,20 +3821,25 @@ while (sects) {
NULL, NULL,
BlockOffset)) BlockOffset))
goto Fatal_IO_Error; goto Fatal_IO_Error;
/* Write just the aligned sector which contains the updated BAT entry */ /* Since a large VHD can have a pretty large BAT, and we've only changed one longword bat entry
BATUpdateBufferAddress = (uint8 *)hVHD->BAT - (size_t)NtoHll(hVHD->Dynamic.TableOffset) + in the current BAT, we write just the aligned sector which contains the updated BAT entry */
(size_t)((((size_t)&hVHD->BAT[BlockNumber+1]) - (size_t)hVHD->BAT + (size_t)NtoHll(hVHD->Dynamic.TableOffset)) & ~(VHD_DATA_BLOCK_ALIGNMENT-1)); BATUpdateBufferAddress = (uint8 *)hVHD->BAT - (size_t)NtoHll(hVHD->Dynamic.TableOffset) +
(size_t)((((size_t)&hVHD->BAT[BlockNumber]) - (size_t)hVHD->BAT + (size_t)NtoHll(hVHD->Dynamic.TableOffset)) & ~(VHD_DATA_BLOCK_ALIGNMENT-1));
/* If the starting of the BAT isn't on a VHD_DATA_BLOCK_ALIGNMENT boundary and we've just updated
a BAT entry early in the array, the buffer computed address might be before the start of the
BAT table. If so, only write the BAT data needed */
if (BATUpdateBufferAddress < (uint8 *)hVHD->BAT) { if (BATUpdateBufferAddress < (uint8 *)hVHD->BAT) {
BATUpdateBufferAddress = (uint8 *)hVHD->BAT; BATUpdateBufferAddress = (uint8 *)hVHD->BAT;
BATUpdateBufferSize = (((((size_t)&hVHD->BAT[BlockNumber+1]) - (size_t)hVHD->BAT) + 511)/512)*512; BATUpdateBufferSize = (uint32)((((size_t)&hVHD->BAT[BlockNumber]) - (size_t)hVHD->BAT) + 512) & ~511;
BATUpdateStorageAddress = NtoHll(hVHD->Dynamic.TableOffset); BATUpdateStorageAddress = NtoHll(hVHD->Dynamic.TableOffset);
} }
else { else {
BATUpdateBufferSize = VHD_DATA_BLOCK_ALIGNMENT; BATUpdateBufferSize = VHD_DATA_BLOCK_ALIGNMENT;
BATUpdateStorageAddress = NtoHll(hVHD->Dynamic.TableOffset) + BATUpdateBufferAddress - ((uint8 *)hVHD->BAT); BATUpdateStorageAddress = NtoHll(hVHD->Dynamic.TableOffset) + BATUpdateBufferAddress - ((uint8 *)hVHD->BAT);
} }
/* If the total BAT is smaller than one VHD_DATA_BLOCK_ALIGNMENT, then be sure to only write out the BAT data */
if ((size_t)(BATUpdateBufferAddress - (uint8 *)hVHD->BAT + BATUpdateBufferSize) > 512*((sizeof(*hVHD->BAT)*NtoHl(hVHD->Dynamic.MaxTableEntries) + 511)/512)) if ((size_t)(BATUpdateBufferAddress - (uint8 *)hVHD->BAT + BATUpdateBufferSize) > 512*((sizeof(*hVHD->BAT)*NtoHl(hVHD->Dynamic.MaxTableEntries) + 511)/512))
BATUpdateBufferSize = 512*((sizeof(*hVHD->BAT)*NtoHl(hVHD->Dynamic.MaxTableEntries) + 511)/512) - (BATUpdateBufferAddress - ((uint8 *)hVHD->BAT)); BATUpdateBufferSize = (uint32)(512*((sizeof(*hVHD->BAT)*NtoHl(hVHD->Dynamic.MaxTableEntries) + 511)/512) - (BATUpdateBufferAddress - ((uint8 *)hVHD->BAT)));
if (WriteFilePosition(hVHD->File, if (WriteFilePosition(hVHD->File,
BATUpdateBufferAddress, BATUpdateBufferAddress,
BATUpdateBufferSize, BATUpdateBufferSize,