Skip to content

Commit b43d666

Browse files
committed
Fix the following CAS-related tests with LLVM_ENABLE_ONDISK_CAS=ON on Windows (#11194)
Clang :: ClangScanDeps/include-tree-multiple-commands.c Clang :: ClangScanDeps/include-tree-pragma-system-header.c Clang :: ClangScanDeps/include-tree-preserve-pch-path.c Clang :: ClangScanDeps/modules-include-tree-api-notes.c Clang :: ClangScanDeps/modules-include-tree-by-mod-name.c Clang :: ClangScanDeps/modules-include-tree-dependency-file.c Clang :: ClangScanDeps/modules-include-tree-diag-opts.c Clang :: ClangScanDeps/modules-include-tree-export-as.c Clang :: ClangScanDeps/modules-include-tree-exports.c Clang :: ClangScanDeps/modules-include-tree-has-include-umbrella-header.c Clang :: ClangScanDeps/modules-include-tree-implementation-private.c Clang :: ClangScanDeps/modules-include-tree-implementation-transitive.c Clang :: ClangScanDeps/modules-include-tree-implementation-via-spurious.c Clang :: ClangScanDeps/modules-include-tree-pch-common-stale.c Clang :: ClangScanDeps/modules-include-tree-sdk-settings.c Clang :: ClangScanDeps/modules-include-tree-vfsoverlay.c Clang :: ClangScanDeps/optimize-vfs-pch-tree.m Clang-Unit :: ./AllClangUnitTests.exe/8/48 DependencyScanningCASFilesystem.FilenameSpelling Clang-Unit :: ./AllClangUnitTests.exe/9/48 DependencyScanningCASFilesystem.DirectiveScanFailure LLVM-Unit :: CAS/./CASTests.exe/19/38 InMemoryCAS/CASTest.ActionCacheAsync LLVM-Unit :: CAS/./CASTests.exe/30/38 OnDiskCAS/CASTest.ActionCacheAsync LLVM-Unit :: CAS/./CASTests.exe/CASConfigurationTest/configFileSearch LLVM-Unit :: CAS/./CASTests.exe/OnDiskCASLoggerTest/MultiProcess LLVM-Unit :: CAS/./CASTests.exe/OnDiskCASTest/BlobsBigParallelMultiCAS LLVM-Unit :: CAS/./CASTests.exe/OnDiskCASTest/BlobsParallelMultiCAS LLVM-Unit :: CAS/./CASTests.exe/PluginCASTest/isMaterialized (Cherry picked from commit ba40553)
1 parent 08acc72 commit b43d666

File tree

10 files changed

+48
-13
lines changed

10 files changed

+48
-13
lines changed

llvm/include/llvm/CAS/ActionCache.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ using AsyncCASIDValue = AsyncValue<CASID>;
4848
struct AsyncErrorValue {
4949
Error take() { return std::move(Value); }
5050

51-
AsyncErrorValue() : Value(Error::success()) {}
5251
AsyncErrorValue(Error &&E) : Value(std::move(E)) {}
5352

5453
private:

llvm/include/llvm/CAS/CASID.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ class CASID {
127127
template <typename T> struct AsyncValue {
128128
Expected<std::optional<T>> take() { return std::move(Value); }
129129

130-
AsyncValue() : Value(std::nullopt) {}
131130
AsyncValue(Error &&E) : Value(std::move(E)) {}
132131
AsyncValue(T &&V) : Value(std::move(V)) {}
133132
AsyncValue(std::nullopt_t) : Value(std::nullopt) {}

llvm/include/llvm/Support/FileSystem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,11 @@ LLVM_ABI std::error_code copy_file(const Twine &From, int ToFD);
410410
/// platform-specific error_code.
411411
LLVM_ABI std::error_code resize_file(int FD, uint64_t Size);
412412

413+
/// Resize path to size with sparse files explicitly enabled. It uses
414+
/// FSCTL_SET_SPARSE On Windows. This is the same as resize_file on
415+
/// non-Windows
416+
LLVM_ABI std::error_code resize_file_sparse(int FD, uint64_t Size);
417+
413418
/// Resize \p FD to \p Size before mapping \a mapped_file_region::readwrite. On
414419
/// non-Windows, this calls \a resize_file(). On Windows, this is a no-op,
415420
/// since the subsequent mapping (via \c CreateFileMapping) automatically

llvm/lib/CAS/HierarchicalTreeBuilder.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ static StringRef canonicalize(SmallVectorImpl<char> &Path,
2222
TreeEntry::EntryKind Kind,
2323
sys::path::Style PathStyle) {
2424
const char PathSeparatorChar = get_separator(PathStyle)[0];
25-
// Make absolute.
26-
if (Path.empty() || !is_absolute(Path, PathStyle))
25+
// Make absolute. Use has_root_directory instead of is_absolute
26+
// because we may not have the drive like C: for abstract tree
27+
// structures on Windows.
28+
if (Path.empty() || !has_root_directory(Path, PathStyle))
2729
Path.insert(Path.begin(), PathSeparatorChar);
2830

2931
// FIXME: consider rejecting ".." instead of removing them.
@@ -153,7 +155,7 @@ Expected<ObjectProxy> HierarchicalTreeBuilder::create(ObjectStore &CAS) {
153155
Tree *Current = &Root;
154156
StringRef Path = Entry.getPath();
155157
{
156-
assert(is_absolute(Path, PathStyle) && "Expected absolute paths");
158+
assert(has_root_directory(Path, PathStyle) && "Expected absolute paths");
157159
StringRef root_path = sys::path::root_path(Path, PathStyle);
158160
assert(!root_path.empty() && "Expected canonical POSIX absolute paths");
159161
Path.consume_front(root_path);

llvm/lib/CAS/MappedFileRegionBumpPtr.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,8 @@ Expected<MappedFileRegionBumpPtr> MappedFileRegionBumpPtr::create(
166166
// We are initializing the file; it may be empty, or may have been shrunk
167167
// during a previous close.
168168
// FIXME: Detect a case where someone opened it with a smaller capacity.
169-
// FIXME: On Windows we should use FSCTL_SET_SPARSE and FSCTL_SET_ZERO_DATA
170-
// to make this a sparse region, if supported.
171169
assert(InitLock.Locked == FileLockRAII::Exclusive);
172-
if (std::error_code EC = sys::fs::resize_file(FD, Capacity))
170+
if (std::error_code EC = sys::fs::resize_file_sparse(FD, Capacity))
173171
return createFileError(Result.Path, EC);
174172

175173
if (Result.Logger)
@@ -230,7 +228,8 @@ void MappedFileRegionBumpPtr::destroyImpl() {
230228
assert(Size < Capacity);
231229
// sync to file system to make sure all contents are up-to-date.
232230
(void)Region.sync();
233-
(void)sys::fs::resize_file(*FD, size());
231+
Region.unmap();
232+
(void)sys::fs::resize_file(*FD, Size);
234233
(void)unlockFileThreadSafe(*SharedLockFD);
235234

236235
if (Logger)
@@ -338,4 +337,4 @@ ErrorOr<FileSizeInfo> FileSizeInfo::get(sys::fs::file_t File) {
338337
return EC;
339338
return FileSizeInfo{Status.getSize(), Status.getSize()};
340339
#endif
341-
}
340+
}

llvm/lib/Support/Unix/Path.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,10 @@ std::error_code resize_file(int FD, uint64_t Size) {
600600
return std::error_code();
601601
}
602602

603+
std::error_code resize_file_sparse(int FD, uint64_t Size) {
604+
return resize_file(FD, Size);
605+
}
606+
603607
static int convertAccessMode(AccessMode Mode) {
604608
switch (Mode) {
605609
case AccessMode::Exist:

llvm/lib/Support/Windows/Path.inc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/Support/Windows/WindowsSupport.h"
2828
#include <shellapi.h>
2929
#include <shlobj.h>
30+
#include <winioctl.h>
3031

3132
#undef max
3233

@@ -623,6 +624,22 @@ std::error_code resize_file(int FD, uint64_t Size) {
623624
return std::error_code(error, std::generic_category());
624625
}
625626

627+
std::error_code resize_file_sparse(int FD, uint64_t Size) {
628+
HANDLE hFile = reinterpret_cast<HANDLE>(::_get_osfhandle(FD));
629+
DWORD temp;
630+
if (!DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &temp,
631+
NULL)) {
632+
return mapWindowsError(GetLastError());
633+
}
634+
LARGE_INTEGER liSize;
635+
liSize.QuadPart = Size;
636+
if (!SetFilePointerEx(hFile, liSize, NULL, FILE_BEGIN) ||
637+
!SetEndOfFile(hFile)) {
638+
return mapWindowsError(GetLastError());
639+
}
640+
return std::error_code();
641+
}
642+
626643
std::error_code access(const Twine &Path, AccessMode Mode) {
627644
SmallVector<wchar_t, 128> PathUtf16;
628645

llvm/unittests/CAS/ObjectStoreTest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ TEST_P(CASTest, BlobsBigParallel) {
350350
}
351351

352352
#if LLVM_ENABLE_ONDISK_CAS
353+
#ifndef _WIN32 // create_link won't work for directories on Windows
353354
TEST(OnDiskCASTest, BlobsParallelMultiCAS) {
354355
// This test intentionally uses symlinked paths to the same CAS to subvert the
355356
// shared memory mappings that would normally be created within a single
@@ -405,8 +406,8 @@ TEST(OnDiskCASTest, BlobsBigParallelMultiCAS) {
405406
uint64_t Size = 100ULL * 1024;
406407
ASSERT_NO_FATAL_FAILURE(testBlobsParallel(*CAS1, *CAS2, *CAS3, *CAS4, Size));
407408
}
409+
#endif // _WIN32
408410

409-
#ifndef _WIN32 // FIXME: resize support on Windows.
410411
TEST(OnDiskCASTest, DiskSize) {
411412
setMaxOnDiskCASMappingSize();
412413
unittest::TempDir Temp("on-disk-cas", /*Unique=*/true);
@@ -454,5 +455,4 @@ TEST(OnDiskCASTest, DiskSize) {
454455
CAS.reset();
455456
CheckFileSizes(/*Mapped=*/false);
456457
}
457-
#endif
458-
#endif
458+
#endif // LLVM_ENABLE_ONDISK_CAS

llvm/unittests/CAS/OnDiskCASLoggerTest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,12 @@ TEST(OnDiskCASLoggerTest, MultiProcess) {
159159
SmallVector<ProcessInfo> PIs;
160160
for (int I = 0; I < 5; ++I) {
161161
bool ExecutionFailed;
162+
#ifndef _WIN32
162163
auto PI = ExecuteNoWait(Executable, Argv, ArrayRef<StringRef>{}, {}, 0, &Error,
164+
#else
165+
// CreateProcessW will fail with zero-length env on Windows
166+
auto PI = ExecuteNoWait(Executable, Argv, std::nullopt, {}, 0, &Error,
167+
#endif
163168
&ExecutionFailed);
164169
ASSERT_FALSE(ExecutionFailed) << Error;
165170
PIs.push_back(std::move(PI));

llvm/unittests/CAS/PluginCASTest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,13 @@ static std::string getCASPluginPath() {
3030
sys::fs::getMainExecutable(TestMainArgv0, &TestStringArg1);
3131
llvm::SmallString<256> PathBuf(sys::path::parent_path(
3232
sys::path::parent_path(sys::path::parent_path(Executable))));
33+
#ifndef _WIN32
3334
std::string LibName = "libCASPluginTest";
3435
sys::path::append(PathBuf, "lib", LibName + LLVM_PLUGIN_EXT);
36+
#else
37+
std::string LibName = "CASPluginTest";
38+
sys::path::append(PathBuf, "bin", LibName + LLVM_PLUGIN_EXT);
39+
#endif
3540
return std::string(PathBuf);
3641
}
3742

0 commit comments

Comments
 (0)