summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Sidorkin <osidorkin@gmail.com>2022-11-14 21:53:50 +0300
committerGitHub <noreply@github.com>2022-11-14 19:53:50 +0100
commitec77044ea62bab253e62ee5aaf2646a2ee551004 (patch)
treefe368a92b7c011cd563171d71caa0d9ce26a2b8b
parent876509ae8b95f76adebdfa1f2380d75a49f9871d (diff)
downloadccache-ec77044ea62bab253e62ee5aaf2646a2ee551004.tar.gz
fix: Fall back to emulation for unsupported posix_fallocate (#1222)
posix_fallocate can return EINVAL if filesystem doesn't support it. Fall back to emulation in this case. E.g. ZFS does so on FreeBSD (haven't tested with ZFS on linux). This fixes Utill::fallocate unit tests on ZFS.
-rw-r--r--src/Util.cpp10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/Util.cpp b/src/Util.cpp
index eaac8b95..e802a83b 100644
--- a/src/Util.cpp
+++ b/src/Util.cpp
@@ -482,8 +482,13 @@ int
fallocate(int fd, long new_size)
{
#ifdef HAVE_POSIX_FALLOCATE
- return posix_fallocate(fd, 0, new_size);
-#else
+ const int posix_fallocate_err = posix_fallocate(fd, 0, new_size);
+ if (posix_fallocate_err == 0 || posix_fallocate_err != EINVAL) {
+ return posix_fallocate_err;
+ }
+ // the underlying filesystem does not support the operation so fallback to
+ // lseeks
+#endif
off_t saved_pos = lseek(fd, 0, SEEK_END);
off_t old_size = lseek(fd, 0, SEEK_END);
if (old_size == -1) {
@@ -510,7 +515,6 @@ fallocate(int fd, long new_size)
lseek(fd, saved_pos, SEEK_SET);
free(buf);
return err;
-#endif
}
std::string