-
Notifications
You must be signed in to change notification settings - Fork 2.5k
cmake: detect availability of posix_fallocate(3) #5087
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -157,14 +157,30 @@ int p_rename(const char *from, const char *to) | |
|
||
int p_fallocate(int fd, off_t offset, off_t len) | ||
{ | ||
#if defined (__APPLE__) || (defined (__NetBSD__) && __NetBSD_Version__ < 700000000) | ||
int error = 0, cur; | ||
char buf[BUFSIZ]; | ||
off_t pos = 0; | ||
|
||
#if defined(GIT_USE_FALLOCATE_POSIX) | ||
if ((error = posix_fallocate(fd, offset, len)) < 0) | ||
if (errno == ENOTSUP) | ||
goto fallback; | ||
#elif defined(GIT_USE_FALLOCATE_SOLARIS) | ||
struct flock64 fl; | ||
|
||
fl.l_whence = SEEK_SET; | ||
fl.l_start = offset; | ||
fl.l_len = len; | ||
|
||
if ((error = fcntl(fd, F_ALLOCSP64, &fl)) < 0) | ||
goto fallback; | ||
#elif defined(GIT_USE_FALLOCATE_BSD) | ||
fstore_t prealloc; | ||
struct stat st; | ||
size_t newsize; | ||
int error; | ||
|
||
if ((error = p_fstat(fd, &st)) < 0) | ||
return error; | ||
return -1; | ||
|
||
if (git__add_sizet_overflow(&newsize, offset, len)) { | ||
errno = EINVAL; | ||
|
@@ -182,15 +198,45 @@ int p_fallocate(int fd, off_t offset, off_t len) | |
|
||
/* | ||
* fcntl will often error when the file already exists; ignore | ||
* this error since ftruncate will also resize the file (although | ||
* this error since our fallback will also resize the file (although | ||
* likely slower). | ||
*/ | ||
fcntl(fd, F_PREALLOCATE, &prealloc); | ||
|
||
return ftruncate(fd, (offset + len)); | ||
if ((error = fcntl(fd, F_PREALLOCATE, &prealloc)) < 0) | ||
goto fallback; | ||
#elif defined(GIT_USE_FALLOCATE) | ||
do { | ||
error = fallocate(fd, 0, offset, len); | ||
} while (error < 0 && errno == EINTR); | ||
if (error < 0 && errno == ENOTSUP) | ||
goto fallback; | ||
#else | ||
return posix_fallocate(fd, offset, len); | ||
goto fallback; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd just remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's protecting against an "unused label" warning on macOS case, actually. |
||
#endif | ||
|
||
fallback: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't quite get it. Aren't we now always executing the fallback, regardless of whether the platform-specific implementation succeeded or not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Heh, true, I seem to have forgot a few |
||
/* save offset, seek, write zeroes, restore */ | ||
if ((error = p_lseek(fd, 0, SEEK_CUR)) < 0) | ||
return -1; | ||
|
||
cur = error; | ||
|
||
memset(&buf, '\0', sizeof(buf)); | ||
|
||
if ((error = p_lseek(fd, offset, SEEK_SET)) < 0) | ||
goto cleanup; | ||
|
||
while (pos < len) { | ||
size_t wlen = MIN(len - pos, (off_t)sizeof(buf)); | ||
if ((error = p_write(fd, buf, wlen)) < 0) | ||
goto cleanup; | ||
pos += wlen; | ||
} | ||
|
||
cleanup: | ||
if ((error = p_lseek(fd, cur, SEEK_SET)) < 0) | ||
return error; | ||
|
||
return error; | ||
} | ||
|
||
#endif /* GIT_WIN32 */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can
fallocate
setEAGAIN
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's copy-pasted from #5087 (comment), actually. And isn't
EAGAIN
usually async network stuff ? I'm scared now…