Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion llvm/lib/Support/Caching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
TempFilePrefixRef.toVector(TempFilePrefix);
CacheDirectoryPathRef.toVector(CacheDirectoryPath);

bool OnNFS = !sys::fs::is_local(CacheDirectoryPath);

auto Func = [=](unsigned Task, StringRef Key,
const Twine &ModuleName) -> Expected<AddStreamFn> {
// This choice of file name allows the cache to be pruned (see pruneCache()
Expand All @@ -52,7 +54,8 @@ Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
MemoryBuffer::getOpenFile(*FDOrErr, EntryPath,
/*FileSize=*/-1,
/*RequiresNullTerminator=*/false);
/*RequiresNullTerminator=*/false,
/*IsVolatile=*/OnNFS);
sys::fs::closeFile(*FDOrErr);
if (MBOrErr) {
AddBuffer(Task, ModuleName, std::move(*MBOrErr));
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Support/MemoryBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,21 @@ static bool shouldUseMmap(sys::fs::file_t FD,
return false;
#endif

// Do not use mmap on NFS file systems (IsVolatile is true).
// IsVolatile=true should be used on NFS file systems or when the files are
// expected to change (this happens on clangd when reading user's code).
// Otherwise, accessing the buffer obtained through mmap may result in a
// SIGBUS. Doing regular read() may result in "Stale file handle" errors,
// which is also not great, but at least `getOpenFileImpl` can forward the
// error to the user. In contrast, the SIGBUS happens on the caller's code and
// we cannot prevent it.
//
// FIXME: We could use the `CrashRecoveryContext`, and read one byte from
// every page of the file to catch the SIGBUS in advance. ATM I haven't
// managed to make this work, thus the conservative solution.
if (IsVolatile)
return false;

// mmap may leave the buffer without null terminator if the file size changed
// by the time the last page is mapped in, so avoid it if the file size is
// likely to change.
Expand Down
Loading