11
11
#include " llvm/Config/config.h"
12
12
#include " llvm/Support/Error.h"
13
13
#include " llvm/Support/Process.h"
14
+ #include < limits>
14
15
#include < mutex>
15
16
#include < optional>
16
17
#include < thread>
@@ -115,16 +116,25 @@ cas::ondisk::tryLockFileThreadSafe(int FD, std::chrono::milliseconds Timeout,
115
116
}
116
117
117
118
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 > {
120
120
if (EC == std::errc::not_supported)
121
121
// Ignore ENOTSUP in case the filesystem cannot preallocate.
122
122
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
123
132
return createStringError (EC, " failed to allocate to CAS file: " + EC.message ());
124
133
};
125
134
#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 ()));
128
138
return NewSize;
129
139
#elif defined(__APPLE__)
130
140
fstore_t FAlloc;
@@ -134,7 +144,7 @@ Expected<size_t> cas::ondisk::preallocateFileTail(int FD, size_t CurrentSize, si
134
144
FAlloc.fst_length = NewSize - CurrentSize;
135
145
FAlloc.fst_bytesalloc = 0 ;
136
146
if (fcntl (FD, F_PREALLOCATE, &FAlloc))
137
- return CreateErrorFromErrno ( );
147
+ return CreateError ( errnoAsErrorCode () );
138
148
assert (CurrentSize + FAlloc.fst_bytesalloc >= NewSize);
139
149
return CurrentSize + FAlloc.fst_bytesalloc ;
140
150
#else
0 commit comments