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
117118Expected<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