Skip to content

Commit

Permalink
More fixes in vhdutils
Browse files Browse the repository at this point in the history
While applying  the "zero write optimization" in a Differencing VHD, all ancestors are now checked for a block presence.
  • Loading branch information
maxpat78 committed Oct 18, 2023
1 parent 60bb258 commit ca55eb7
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
2 changes: 1 addition & 1 deletion FATtools/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.0.30'
__version__ = '1.0.31'
18 changes: 14 additions & 4 deletions FATtools/vhdutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@
In fact, Windows 11 refuses to mount a VHD >2040 GiB.
A BAT index of 0xFFFFFFFF signals a zeroed block not allocated physically:
such value is kept until a block is written with all zeros, too.
such value is kept until a block is written with all zeros, too. However,
since in a Differencing VHD the full chain must be checked, zeroing a block
already present in an ancestor requires physically allocating and zeroing it
in the descendant.
PLEASE NOTE THAT ALL NUMBERS ARE IN BIG ENDIAN FORMAT! """
import io, struct, uuid, zlib, ctypes, time, os, math
Expand Down Expand Up @@ -453,7 +456,14 @@ def tell(self):

def close(self):
self.stream.close()


def has_block(self, i):
"Returns True if the caller or some ascendant has got allocated a block"
if self.bat[i] != 0xFFFFFFFF or \
(self.Parent and self.Parent.has_block(i)):
return True
return False

def read0(self, size=-1):
"Reads (Fixed image)"
if size == -1 or self._pos + size > self.size:
Expand Down Expand Up @@ -586,8 +596,8 @@ def write1(self, s):
put=size
size=0
if block == 0xFFFFFFFF:
# we can keep a block virtualized until PARENT'S IS VIRTUALIZED AND we write zeros
if self.Parent.bat[self._pos//self.block] == 0xFFFFFFFF and s[i:i+put] == self.zero[:put]:
# we can keep a block virtual until we write zeros and no parent holds it
if not self.has_block(self._pos//self.block) and s[i:i+put] == self.zero[:put]:
i+=put
self._pos+=put
if DEBUG&16: log("block #%d @0x%X is zeroed, virtualizing write", self._pos//self.block, (block*self.block)+self.header.u64TableOffset)
Expand Down

0 comments on commit ca55eb7

Please sign in to comment.