Commit 2d85c7e86d893946a4f0e84f57698833c3b79c37

Patrick Steinhardt 2019-06-14T14:12:19

posix: remove `p_fallocate` abstraction By now, we have repeatedly failed to provide a nice cross-platform implementation of `p_fallocate`. Recent tries to do that escalated quite fast to a set of different CMake checks, implementations, fallbacks, etc., which started to look real awkward to maintain. In fact, `p_fallocate` had only been introduced in commit 4e3949b73 (tests: test that largefiles can be read through the tree API, 2019-01-30) to support a test with large files, but given the maintenance costs it just seems not to be worht it. As we have removed the sole user of `p_fallocate` in the previous commit, let's drop it altogether.

diff --git a/src/posix.c b/src/posix.c
index 32ca704..bffe02e 100644
--- a/src/posix.c
+++ b/src/posix.c
@@ -155,44 +155,6 @@ int p_rename(const char *from, const char *to)
 	return -1;
 }
 
-int p_fallocate(int fd, off_t offset, off_t len)
-{
-#if defined (__APPLE__) || (defined (__NetBSD__) && __NetBSD_Version__ < 700000000)
-	fstore_t prealloc;
-	struct stat st;
-	size_t newsize;
-	int error;
-
-	if ((error = p_fstat(fd, &st)) < 0)
-		return error;
-
-	if (git__add_sizet_overflow(&newsize, offset, len)) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (newsize < (unsigned long long)st.st_size)
-		return 0;
-
-	memset(&prealloc, 0, sizeof(prealloc));
-	prealloc.fst_flags  = F_ALLOCATEALL;
-	prealloc.fst_posmode = F_PEOFPOSMODE;
-	prealloc.fst_offset = offset;
-	prealloc.fst_length = len;
-
-	/*
-	 * fcntl will often error when the file already exists; ignore
-	 * this error since ftruncate will also resize the file (although
-	 * likely slower).
-	 */
-	fcntl(fd, F_PREALLOCATE, &prealloc);
-
-	return ftruncate(fd, (offset + len));
-#else
-	return posix_fallocate(fd, offset, len);
-#endif
-}
-
 #endif /* GIT_WIN32 */
 
 ssize_t p_read(git_file fd, void *buf, size_t cnt)
diff --git a/src/posix.h b/src/posix.h
index 0119b6b..2934f24 100644
--- a/src/posix.h
+++ b/src/posix.h
@@ -115,7 +115,6 @@ extern int p_open(const char *path, int flags, ...);
 extern int p_creat(const char *path, mode_t mode);
 extern int p_getcwd(char *buffer_out, size_t size);
 extern int p_rename(const char *from, const char *to);
-extern int p_fallocate(int fd, off_t offset, off_t len);
 
 extern int git__page_size(size_t *page_size);
 extern int git__mmap_alignment(size_t *page_size);
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index c082dba..91e1643 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -525,58 +525,6 @@ int p_creat(const char *path, mode_t mode)
 	return p_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
 }
 
-int p_fallocate(int fd, off_t offset, off_t len)
-{
-	HANDLE fh = (HANDLE)_get_osfhandle(fd);
-	LARGE_INTEGER zero, position, oldsize, newsize;
-	size_t size;
-
-	if (fh == INVALID_HANDLE_VALUE) {
-		errno = EBADF;
-		return -1;
-	}
-
-	if (offset < 0 || len <= 0) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (git__add_sizet_overflow(&size, offset, len)) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	zero.u.LowPart = 0;
-	zero.u.HighPart = 0;
-
-	newsize.u.LowPart = (size & 0xffffffff);
-
-#if (SIZE_MAX > UINT32_MAX)
-	newsize.u.HighPart = size >> 32;
-#else
-	newsize.u.HighPart = 0;
-#endif
-
-	if (!GetFileSizeEx(fh, &oldsize)) {
-		set_errno();
-		return -1;
-	}
-
-	/* POSIX emulation: attempting to shrink the file is ignored */
-	if (oldsize.QuadPart >= newsize.QuadPart)
-		return 0;
-
-	if (!SetFilePointerEx(fh, zero, &position, FILE_CURRENT) ||
-	    !SetFilePointerEx(fh, newsize, NULL, FILE_BEGIN) ||
-	    !SetEndOfFile(fh) ||
-	    !SetFilePointerEx(fh, position, 0, FILE_BEGIN)) {
-		set_errno();
-		return -1;
-	}
-
-	return 0;
-}
-
 int p_utimes(const char *path, const struct p_timeval times[2])
 {
 	git_win32_path wpath;
diff --git a/tests/core/posix.c b/tests/core/posix.c
index 2b60077..a459b26 100644
--- a/tests/core/posix.c
+++ b/tests/core/posix.c
@@ -35,11 +35,6 @@ void test_core_posix__initialize(void)
 #endif
 }
 
-void test_core_posix__cleanup(void)
-{
-    p_unlink("fallocate_test");
-}
-
 static bool supports_ipv6(void)
 {
 #ifdef GIT_WIN32
@@ -268,39 +263,3 @@ void test_core_posix__p_regcomp_compile_userdiff_regexps(void)
 		cl_assert(!error);
 	}
 }
-
-void test_core_posix__fallocate(void)
-{
-	int fd;
-	struct stat st;
-
-	/* fallocate a new file succeeds */
-	cl_must_pass(fd = p_open("fallocate_test", O_RDWR|O_CREAT, 0666));
-	cl_must_pass(p_fallocate(fd, 0, 42));
-	cl_must_pass(p_fstat(fd, &st));
-	cl_assert_equal_i(42, st.st_size);
-	p_close(fd);
-
-	/* fallocate an existing file succeeds */
-	cl_must_pass(fd = p_open("fallocate_test", O_RDWR, 0666));
-	cl_must_pass(p_fallocate(fd, 90, 9));
-	cl_must_pass(p_fstat(fd, &st));
-	cl_assert_equal_i(99, st.st_size);
-	p_close(fd);
-
-	/* fallocate doesn't shrink */
-	cl_must_pass(fd = p_open("fallocate_test", O_RDWR, 0666));
-	cl_must_pass(p_fallocate(fd, 0, 14));
-	cl_must_pass(p_fstat(fd, &st));
-	cl_assert_equal_i(99, st.st_size);
-	p_close(fd);
-
-	/* fallocate doesn't move the cursor */
-	cl_must_pass(fd = p_open("fallocate_test", O_RDWR, 0666));
-	cl_must_pass(p_fallocate(fd, 0, 100));
-	cl_assert_equal_i(0, p_lseek(fd, 0, SEEK_CUR));
-	cl_must_pass(p_lseek(fd, 42, SEEK_SET));
-	cl_must_pass(p_fallocate(fd, 0, 200));
-	cl_assert_equal_i(42, p_lseek(fd, 0, SEEK_CUR));
-	p_close(fd);
-}