Skip to content

Commit 367909f

Browse files
authored
Merge pull request #11054 from benlangmuir/fix-posix_fallocate-error-handling-6.2
🍒[6.2][llvm][cas] Fix error handling of posix_fallocate
2 parents 7725fb2 + 87e2107 commit 367909f

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

llvm/lib/CAS/OnDiskCommon.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "llvm/Config/config.h"
1212
#include "llvm/Support/Error.h"
1313
#include "llvm/Support/Process.h"
14+
#include <limits>
1415
#include <mutex>
1516
#include <optional>
1617
#include <thread>
@@ -115,16 +116,25 @@ cas::ondisk::tryLockFileThreadSafe(int FD, std::chrono::milliseconds Timeout,
115116
}
116117

117118
Expected<size_t> cas::ondisk::preallocateFileTail(int FD, size_t CurrentSize, size_t NewSize) {
118-
auto CreateErrorFromErrno = [&]() -> Expected<size_t> {
119-
std::error_code EC = errnoAsErrorCode();
119+
auto CreateError = [&](std::error_code EC) -> Expected<size_t> {
120120
if (EC == std::errc::not_supported)
121121
// Ignore ENOTSUP in case the filesystem cannot preallocate.
122122
return NewSize;
123+
#if defined(HAVE_POSIX_FALLOCATE)
124+
if (EC == std::errc::invalid_argument &&
125+
CurrentSize < NewSize && // len > 0
126+
NewSize < std::numeric_limits<off_t>::max()) // 0 <= offset, len < max
127+
// Prior to 2024, POSIX required EINVAL for cases that should be ENOTSUP,
128+
// so handle it the same as above if it is not one of the other ways to
129+
// get EINVAL.
130+
return NewSize;
131+
#endif
123132
return createStringError(EC, "failed to allocate to CAS file: " + EC.message());
124133
};
125134
#if defined(HAVE_POSIX_FALLOCATE)
126-
if (posix_fallocate(FD, CurrentSize, NewSize - CurrentSize))
127-
return CreateErrorFromErrno();
135+
// Note: posix_fallocate returns its error directly, not via errno.
136+
if (int Err = posix_fallocate(FD, CurrentSize, NewSize - CurrentSize))
137+
return CreateError(std::error_code(Err, std::generic_category()));
128138
return NewSize;
129139
#elif defined(__APPLE__)
130140
fstore_t FAlloc;
@@ -134,7 +144,7 @@ Expected<size_t> cas::ondisk::preallocateFileTail(int FD, size_t CurrentSize, si
134144
FAlloc.fst_length = NewSize - CurrentSize;
135145
FAlloc.fst_bytesalloc = 0;
136146
if (fcntl(FD, F_PREALLOCATE, &FAlloc))
137-
return CreateErrorFromErrno();
147+
return CreateError(errnoAsErrorCode());
138148
assert(CurrentSize + FAlloc.fst_bytesalloc >= NewSize);
139149
return CurrentSize + FAlloc.fst_bytesalloc;
140150
#else

0 commit comments

Comments
 (0)