Merge pull request #9462 from ThomasWaldmann/trailing-sparse-windows-master
Some checks are pending
Lint / lint (push) Waiting to run
CI / lint (push) Waiting to run
CI / security (push) Waiting to run
CI / asan_ubsan (push) Blocked by required conditions
CI / native_tests (push) Blocked by required conditions
CI / vm_tests (Haiku, false, haiku, r1beta5) (push) Blocked by required conditions
CI / vm_tests (NetBSD, false, netbsd, 10.1) (push) Blocked by required conditions
CI / vm_tests (OmniOS, false, omnios, r151056) (push) Blocked by required conditions
CI / vm_tests (OpenBSD, false, openbsd, 7.7) (push) Blocked by required conditions
CI / vm_tests (borg-freebsd-14-x86_64-gh, FreeBSD, true, freebsd, 14.3) (push) Blocked by required conditions
CI / windows_tests (push) Blocked by required conditions
CodeQL / Analyze (push) Waiting to run

fix spurious sparse test fail on win32, fixes #7616
This commit is contained in:
TW 2026-03-11 13:57:56 +01:00 committed by GitHub
commit a03d1780a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 9 additions and 1 deletions

View file

@ -865,6 +865,7 @@ Duration: {0.duration}
with backup_io("open"):
fd = open(path, "wb")
with fd:
trailing_hole = False
for data in self.pipeline.fetch_many(item.chunks, is_preloaded=True, ro_type=ROBJ_FILE_STREAM):
if pi:
pi.show(increase=len(data), info=[remove_surrogates(item.path)])
@ -872,10 +873,18 @@ Duration: {0.duration}
if sparse and zeros.startswith(data):
# all-zero chunk: create a hole in a sparse file
fd.seek(len(data), 1)
trailing_hole = True
else:
fd.write(data)
trailing_hole = False
with backup_io("truncate_and_attrs"):
pos = item_chunks_size = fd.tell()
if is_win32 and trailing_hole and pos > 0:
# Windows: truncate() does not zero-fill properly (no VDL update).
# Writing a single zero at the end forces NTFS to zero-fill the hole
# and update valid data length.
fd.seek(pos - 1)
fd.write(b"\0")
fd.truncate(pos)
fd.flush()
self.restore_attrs(path, item, fd=fd.fileno())

View file

@ -182,7 +182,6 @@ def test_birthtime(archivers, request):
assert same_ts_ns(sto.st_mtime_ns, mtime * 10**9)
@pytest.mark.skipif(is_win32, reason="frequent test failures on github CI on win32")
def test_sparse_file(archivers, request):
archiver = request.getfixturevalue(archivers)