[CAS] Retry blocking syscalls on EINTR (#194691)

Wrap blocking syscalls used by LLVMCAS inside RetryAfterSignal so they
are retried on EINTR instead of surfacing as error or silently dropping
actions due to failed to acquire locks.
This commit is contained in:
Steven Wu 2026-04-28 12:31:43 -07:00 committed by GitHub
parent 6830f04a25
commit e9144cc197
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 21 additions and 11 deletions

View file

@ -56,6 +56,7 @@
#include "OnDiskCommon.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CAS/OnDiskCASLogger.h"
#include "llvm/Support/Errno.h"
#if LLVM_ON_UNIX
#include <sys/stat.h>
@ -425,7 +426,7 @@ Expected<int64_t> MappedFileRegionArena::allocateOffset(uint64_t AllocSize) {
ErrorOr<FileSizeInfo> FileSizeInfo::get(sys::fs::file_t File) {
#if LLVM_ON_UNIX && defined(MAPPED_FILE_BSIZE)
struct stat Status;
int StatRet = ::fstat(File, &Status);
int StatRet = sys::RetryAfterSignal(-1, ::fstat, File, &Status);
if (StatRet)
return errnoAsErrorCode();
uint64_t AllocatedSize = uint64_t(Status.st_blksize) * MAPPED_FILE_BSIZE;

View file

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "OnDiskCommon.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
@ -74,7 +75,9 @@ void cas::ondisk::setMaxMappingSize(uint64_t Size) {
std::error_code cas::ondisk::lockFileThreadSafe(int FD,
sys::fs::LockKind Kind) {
#if HAVE_FLOCK
if (flock(FD, Kind == sys::fs::LockKind::Exclusive ? LOCK_EX : LOCK_SH) == 0)
if (sys::RetryAfterSignal(
-1, flock, FD,
Kind == sys::fs::LockKind::Exclusive ? LOCK_EX : LOCK_SH) == 0)
return std::error_code();
return std::error_code(errno, std::generic_category());
#elif defined(_WIN32)
@ -87,7 +90,7 @@ std::error_code cas::ondisk::lockFileThreadSafe(int FD,
std::error_code cas::ondisk::unlockFileThreadSafe(int FD) {
#if HAVE_FLOCK
if (flock(FD, LOCK_UN) == 0)
if (sys::RetryAfterSignal(-1, flock, FD, LOCK_UN) == 0)
return std::error_code();
return std::error_code(errno, std::generic_category());
#elif defined(_WIN32)
@ -105,8 +108,10 @@ cas::ondisk::tryLockFileThreadSafe(int FD, std::chrono::milliseconds Timeout,
auto Start = std::chrono::steady_clock::now();
auto End = Start + Timeout;
do {
if (flock(FD, (Kind == sys::fs::LockKind::Exclusive ? LOCK_EX : LOCK_SH) |
LOCK_NB) == 0)
if (sys::RetryAfterSignal(
-1, flock, FD,
(Kind == sys::fs::LockKind::Exclusive ? LOCK_EX : LOCK_SH) |
LOCK_NB) == 0)
return std::error_code();
int Error = errno;
if (Error == EWOULDBLOCK) {
@ -146,7 +151,11 @@ Expected<size_t> cas::ondisk::preallocateFileTail(int FD, size_t CurrentSize,
};
#if defined(HAVE_POSIX_FALLOCATE)
// Note: posix_fallocate returns its error directly, not via errno.
if (int Err = posix_fallocate(FD, CurrentSize, NewSize - CurrentSize))
int Err;
do {
Err = posix_fallocate(FD, CurrentSize, NewSize - CurrentSize);
} while (Err == EINTR);
if (Err)
return CreateError(std::error_code(Err, std::generic_category()));
return NewSize;
#elif defined(__APPLE__)
@ -162,7 +171,7 @@ Expected<size_t> cas::ondisk::preallocateFileTail(int FD, size_t CurrentSize,
FAlloc.fst_offset = 0;
FAlloc.fst_length = NewSize - CurrentSize;
FAlloc.fst_bytesalloc = 0;
if (fcntl(FD, F_PREALLOCATE, &FAlloc))
if (sys::RetryAfterSignal(-1, ::fcntl, FD, F_PREALLOCATE, &FAlloc) == -1)
return CreateError(errnoAsErrorCode());
assert(CurrentSize + FAlloc.fst_bytesalloc >= NewSize);
return CurrentSize + FAlloc.fst_bytesalloc;

View file

@ -612,7 +612,7 @@ std::error_code rename(const Twine &from, const Twine &to) {
std::error_code resize_file(int FD, uint64_t Size) {
// Use ftruncate as a fallback. It may or may not allocate space. At least on
// OS X with HFS+ it does.
if (::ftruncate(FD, Size) == -1)
if (sys::RetryAfterSignal(-1, ::ftruncate, FD, Size) == -1)
return errnoAsErrorCode();
return std::error_code();
@ -913,7 +913,7 @@ void mapped_file_region::unmapImpl() {
}
std::error_code mapped_file_region::sync() const {
if (int Res = ::msync(Mapping, Size, MS_SYNC))
if (int Res = sys::RetryAfterSignal(-1, ::msync, Mapping, Size, MS_SYNC))
return std::error_code(Res, std::generic_category());
return std::error_code();
}
@ -1340,7 +1340,7 @@ std::error_code lockFile(int FD, LockKind Kind) {
Lock.l_whence = SEEK_SET;
Lock.l_start = 0;
Lock.l_len = 0;
if (::fcntl(FD, F_SETLKW, &Lock) != -1)
if (sys::RetryAfterSignal(-1, ::fcntl, FD, F_SETLKW, &Lock) != -1)
return std::error_code();
return errnoAsErrorCode();
}
@ -1351,7 +1351,7 @@ std::error_code unlockFile(int FD) {
Lock.l_whence = SEEK_SET;
Lock.l_start = 0;
Lock.l_len = 0;
if (::fcntl(FD, F_SETLK, &Lock) != -1)
if (sys::RetryAfterSignal(-1, ::fcntl, FD, F_SETLK, &Lock) != -1)
return std::error_code();
return errnoAsErrorCode();
}