Commit 3518cf05 authored by Kenton Varda's avatar Kenton Varda

Fix Windows: You must explicitly request sparse files on Windows.

Also CopyFile() doesn't preserve sparseness.
parent 3c091037
...@@ -824,6 +824,18 @@ KJ_TEST("DiskFile holes") { ...@@ -824,6 +824,18 @@ KJ_TEST("DiskFile holes") {
auto dir = tempDir.get(); auto dir = tempDir.get();
auto file = dir->openFile(Path("holes"), WriteMode::CREATE); auto file = dir->openFile(Path("holes"), WriteMode::CREATE);
#if _WIN32
FILE_SET_SPARSE_BUFFER sparseInfo;
memset(&sparseInfo, 0, sizeof(sparseInfo));
sparseInfo.SetSparse = TRUE;
DWORD dummy;
KJ_WIN32(DeviceIoControl(
KJ_ASSERT_NONNULL(file->getWin32Handle()),
FSCTL_SET_SPARSE, &sparseInfo, sizeof(sparseInfo),
NULL, 0, &dummy, NULL));
#endif
file->writeAll("foobar"); file->writeAll("foobar");
file->write(1 << 20, StringPtr("foobar").asBytes()); file->write(1 << 20, StringPtr("foobar").asBytes());
...@@ -833,6 +845,8 @@ KJ_TEST("DiskFile holes") { ...@@ -833,6 +845,8 @@ KJ_TEST("DiskFile holes") {
KJ_EXPECT(meta.spaceUsed <= 2 * 65536); KJ_EXPECT(meta.spaceUsed <= 2 * 65536);
byte buf[7]; byte buf[7];
#if !_WIN32 // Win32 CopyFile() does NOT preserve sparseness.
{ {
// Copy doesn't fill in holes. // Copy doesn't fill in holes.
dir->transfer(Path("copy"), WriteMode::CREATE, Path("holes"), TransferMode::COPY); dir->transfer(Path("copy"), WriteMode::CREATE, Path("holes"), TransferMode::COPY);
...@@ -847,12 +861,14 @@ KJ_TEST("DiskFile holes") { ...@@ -847,12 +861,14 @@ KJ_TEST("DiskFile holes") {
KJ_EXPECT(copy->read(1 << 19, buf) == 7); KJ_EXPECT(copy->read(1 << 19, buf) == 7);
KJ_EXPECT(StringPtr(reinterpret_cast<char*>(buf), 6) == StringPtr("\0\0\0\0\0\0", 6)); KJ_EXPECT(StringPtr(reinterpret_cast<char*>(buf), 6) == StringPtr("\0\0\0\0\0\0", 6));
} }
#endif
file->truncate(1 << 21); file->truncate(1 << 21);
KJ_EXPECT(file->stat().spaceUsed == meta.spaceUsed); KJ_EXPECT(file->stat().spaceUsed == meta.spaceUsed);
KJ_EXPECT(file->read(1 << 20, buf) == 7); KJ_EXPECT(file->read(1 << 20, buf) == 7);
KJ_EXPECT(StringPtr(reinterpret_cast<char*>(buf), 6) == "foobar"); KJ_EXPECT(StringPtr(reinterpret_cast<char*>(buf), 6) == "foobar");
#if !_WIN32 // Win32 CopyFile() does NOT preserve sparseness.
{ {
dir->transfer(Path("copy"), WriteMode::MODIFY, Path("holes"), TransferMode::COPY); dir->transfer(Path("copy"), WriteMode::MODIFY, Path("holes"), TransferMode::COPY);
auto copy = dir->openFile(Path("copy")); auto copy = dir->openFile(Path("copy"));
...@@ -866,6 +882,11 @@ KJ_TEST("DiskFile holes") { ...@@ -866,6 +882,11 @@ KJ_TEST("DiskFile holes") {
KJ_EXPECT(copy->read(1 << 19, buf) == 7); KJ_EXPECT(copy->read(1 << 19, buf) == 7);
KJ_EXPECT(StringPtr(reinterpret_cast<char*>(buf), 6) == StringPtr("\0\0\0\0\0\0", 6)); KJ_EXPECT(StringPtr(reinterpret_cast<char*>(buf), 6) == StringPtr("\0\0\0\0\0\0", 6));
} }
#endif
// Try punching a hole with zero().
file->zero(1 << 20, 4096);
KJ_EXPECT(file->stat().spaceUsed < meta.spaceUsed);
} }
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment