|
@@ -0,0 +1,326 @@
|
|
|
|
|
+--- /dev/null
|
|
|
|
|
++++ b/modules/fallocate-posix
|
|
|
|
|
+@@ -0,0 +1,43 @@
|
|
|
|
|
++Description:
|
|
|
|
|
++posix_fallocate function that is glibc compatible.
|
|
|
|
|
++
|
|
|
|
|
++Files:
|
|
|
|
|
++lib/posix_fallocate.c
|
|
|
|
|
++m4/fcntl_h.m4
|
|
|
|
|
++m4/posix_fallocate.m4
|
|
|
|
|
++
|
|
|
|
|
++Depends-on:
|
|
|
|
|
++errno [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++fcntl [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++fstat [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++ftruncate [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++pread [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++pwrite [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++stdint [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++sys_stat [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++unistd [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1]
|
|
|
|
|
++fcntl-h
|
|
|
|
|
++
|
|
|
|
|
++configure.ac:
|
|
|
|
|
++gl_FUNC_POSIX_FALLOCATE
|
|
|
|
|
++gl_CONDITIONAL([GL_COND_OBJ_POSIX_FALLOCATE],
|
|
|
|
|
++ [test $HAVE_FALLOCATE_POSIX = 0 || test $REPLACE_FALLOCATE_POSIX = 1])
|
|
|
|
|
++AM_COND_IF([GL_COND_OBJ_POSIX_FALLOCATE], [
|
|
|
|
|
++ gl_PREREQ_POSIX_FALLOCATE
|
|
|
|
|
++])
|
|
|
|
|
++gl_MODULE_INDICATOR([fallocate-posix])
|
|
|
|
|
++gl_FCNTL_MODULE_INDICATOR([fallocate-posix])
|
|
|
|
|
++
|
|
|
|
|
++Makefile.am:
|
|
|
|
|
++if GL_COND_OBJ_POSIX_FALLOCATE
|
|
|
|
|
++lib_SOURCES += posix_fallocate.c
|
|
|
|
|
++endif
|
|
|
|
|
++
|
|
|
|
|
++Include:
|
|
|
|
|
++<fcntl.h>
|
|
|
|
|
++
|
|
|
|
|
++License:
|
|
|
|
|
++LGPLv2+
|
|
|
|
|
++
|
|
|
|
|
++Maintainer:
|
|
|
|
|
++all
|
|
|
|
|
+--- /dev/null
|
|
|
|
|
++++ b/m4/posix_fallocate.m4
|
|
|
|
|
+@@ -0,0 +1,20 @@
|
|
|
|
|
++# posix_fallocate.m4 serial 1
|
|
|
|
|
++dnl Copyright (C) 2024 Free Software Foundation, Inc.
|
|
|
|
|
++dnl This file is free software; the Free Software Foundation
|
|
|
|
|
++dnl gives unlimited permission to copy and/or distribute it,
|
|
|
|
|
++dnl with or without modifications, as long as this notice is preserved.
|
|
|
|
|
++
|
|
|
|
|
++AC_DEFUN([gl_FUNC_POSIX_FALLOCATE],
|
|
|
|
|
++[
|
|
|
|
|
++ AC_REQUIRE([gl_FCNTL_H_DEFAULTS])
|
|
|
|
|
++ gl_CHECK_FUNCS_ANDROID([posix_fallocate], [[#include <fcntl.h>]])
|
|
|
|
|
++ if test "$ac_cv_func_posix_fallocate" = no; then
|
|
|
|
|
++ HAVE_FALLOCATE_POSIX=0
|
|
|
|
|
++ case "$gl_cv_onwards_func_posix_fallocate" in
|
|
|
|
|
++ future*) REPLACE_FALLOCATE_POSIX=1 ;;
|
|
|
|
|
++ esac
|
|
|
|
|
++ fi
|
|
|
|
|
++])
|
|
|
|
|
++
|
|
|
|
|
++# Prerequisites of lib/posix_fallocate.c.
|
|
|
|
|
++AC_DEFUN([gl_PREREQ_POSIX_FALLOCATE], [:])
|
|
|
|
|
+--- a/m4/fcntl_h.m4
|
|
|
|
|
++++ b/m4/fcntl_h.m4
|
|
|
|
|
+@@ -23,7 +23,7 @@ AC_DEFUN_ONCE([gl_FCNTL_H],
|
|
|
|
|
+ dnl corresponding gnulib module is not in use, if it is not common
|
|
|
|
|
+ dnl enough to be declared everywhere.
|
|
|
|
|
+ gl_WARN_ON_USE_PREPARE([[#include <fcntl.h>
|
|
|
|
|
+- ]], [fcntl openat])
|
|
|
|
|
++ ]], [fcntl openat posix_fallocate])
|
|
|
|
|
+ ])
|
|
|
|
|
+
|
|
|
|
|
+ # gl_FCNTL_MODULE_INDICATOR([modulename])
|
|
|
|
|
+@@ -50,6 +50,7 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
|
|
|
|
|
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NONBLOCKING])
|
|
|
|
|
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPEN])
|
|
|
|
|
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPENAT])
|
|
|
|
|
++ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FALLOCATE_POSIX])
|
|
|
|
|
+ dnl Support Microsoft deprecated alias function names by default.
|
|
|
|
|
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CREAT], [1])
|
|
|
|
|
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_OPEN], [1])
|
|
|
|
|
+@@ -61,10 +62,12 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
|
|
|
|
|
+ AC_DEFUN([gl_FCNTL_H_DEFAULTS],
|
|
|
|
|
+ [
|
|
|
|
|
+ dnl Assume proper GNU behavior unless another module says otherwise.
|
|
|
|
|
+- HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL])
|
|
|
|
|
+- HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT])
|
|
|
|
|
+- REPLACE_CREAT=0; AC_SUBST([REPLACE_CREAT])
|
|
|
|
|
+- REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL])
|
|
|
|
|
+- REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN])
|
|
|
|
|
+- REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT])
|
|
|
|
|
++ HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL])
|
|
|
|
|
++ HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT])
|
|
|
|
|
++ HAVE_FALLOCATE_POSIX=1; AC_SUBST([HAVE_FALLOCATE_POSIX])
|
|
|
|
|
++ REPLACE_CREAT=0; AC_SUBST([REPLACE_CREAT])
|
|
|
|
|
++ REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL])
|
|
|
|
|
++ REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN])
|
|
|
|
|
++ REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT])
|
|
|
|
|
++ REPLACE_FALLOCATE_POSIX=0; AC_SUBST([REPLACE_FALLOCATE_POSIX])
|
|
|
|
|
+ ])
|
|
|
|
|
+--- a/modules/fcntl-h
|
|
|
|
|
++++ b/modules/fcntl-h
|
|
|
|
|
+@@ -40,14 +40,17 @@ fcntl.h: fcntl.in.h $(top_builddir)/conf
|
|
|
|
|
+ -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \
|
|
|
|
|
+ -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \
|
|
|
|
|
+ -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \
|
|
|
|
|
++ -e 's/@''GNULIB_FALLOCATE_POSIX''@/$(GNULIB_FALLOCATE_POSIX)/g' \
|
|
|
|
|
+ -e 's/@''GNULIB_MDA_CREAT''@/$(GNULIB_MDA_CREAT)/g' \
|
|
|
|
|
+ -e 's/@''GNULIB_MDA_OPEN''@/$(GNULIB_MDA_OPEN)/g' \
|
|
|
|
|
+ -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
|
|
|
|
|
+ -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \
|
|
|
|
|
++ -e 's|@''HAVE_FALLOCATE_POSIX''@|$(HAVE_FALLOCATE_POSIX)|g' \
|
|
|
|
|
+ -e 's|@''REPLACE_CREAT''@|$(REPLACE_CREAT)|g' \
|
|
|
|
|
+ -e 's|@''REPLACE_FCNTL''@|$(REPLACE_FCNTL)|g' \
|
|
|
|
|
+ -e 's|@''REPLACE_OPEN''@|$(REPLACE_OPEN)|g' \
|
|
|
|
|
+ -e 's|@''REPLACE_OPENAT''@|$(REPLACE_OPENAT)|g' \
|
|
|
|
|
++ -e 's|@''REPLACE_FALLOCATE_POSIX''@|$(REPLACE_FALLOCATE_POSIX)|g' \
|
|
|
|
|
+ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
|
|
|
|
|
+ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
|
|
|
|
|
+ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
|
|
|
|
|
+--- a/lib/fcntl.in.h
|
|
|
|
|
++++ b/lib/fcntl.in.h
|
|
|
|
|
+@@ -238,6 +238,33 @@ _GL_WARN_ON_USE (openat, "openat is not
|
|
|
|
|
+ # endif
|
|
|
|
|
+ #endif
|
|
|
|
|
+
|
|
|
|
|
++#if @GNULIB_FALLOCATE_POSIX@
|
|
|
|
|
++# if @REPLACE_FALLOCATE_POSIX@
|
|
|
|
|
++# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
|
|
|
|
++# undef posix_fallocate
|
|
|
|
|
++# define posix_fallocate rpl_posix_fallocate
|
|
|
|
|
++# endif
|
|
|
|
|
++_GL_FUNCDECL_RPL (posix_fallocate, int,
|
|
|
|
|
++ (int fd, off_t offset, off_t len));
|
|
|
|
|
++_GL_CXXALIAS_RPL (posix_fallocate, int,
|
|
|
|
|
++ (int fd, off_t offset, off_t len));
|
|
|
|
|
++# else
|
|
|
|
|
++# if !@HAVE_FALLOCATE_POSIX@
|
|
|
|
|
++_GL_FUNCDECL_SYS (posix_fallocate, int,
|
|
|
|
|
++ (int fd, off_t offset, off_t len));
|
|
|
|
|
++# endif
|
|
|
|
|
++_GL_CXXALIAS_SYS (posix_fallocate, int,
|
|
|
|
|
++ (int fd, off_t offset, off_t len));
|
|
|
|
|
++# endif
|
|
|
|
|
++_GL_CXXALIASWARN (posix_fallocate);
|
|
|
|
|
++#elif defined GNULIB_POSIXCHECK
|
|
|
|
|
++# undef posix_fallocate
|
|
|
|
|
++# if HAVE_RAW_DECL_POSIX_FALLOCATE
|
|
|
|
|
++_GL_WARN_ON_USE (posix_fallocate, "posix_fallocate is not portable - "
|
|
|
|
|
++ "use gnulib module fallocate-posix for portability");
|
|
|
|
|
++# endif
|
|
|
|
|
++#endif
|
|
|
|
|
++
|
|
|
|
|
+
|
|
|
|
|
+ /* Fix up the FD_* macros, only known to be missing on mingw. */
|
|
|
|
|
+
|
|
|
|
|
+--- /dev/null
|
|
|
|
|
++++ b/lib/posix_fallocate.c
|
|
|
|
|
+@@ -0,0 +1,150 @@
|
|
|
|
|
++/* posix_fallocate function that is glibc compatible.
|
|
|
|
|
++
|
|
|
|
|
++ Copyright (C) 2024 Free Software Foundation, Inc.
|
|
|
|
|
++
|
|
|
|
|
++ This file is free software: you can redistribute it and/or modify
|
|
|
|
|
++ it under the terms of the GNU Lesser General Public License as
|
|
|
|
|
++ published by the Free Software Foundation; either version 2.1 of the
|
|
|
|
|
++ License, or (at your option) any later version.
|
|
|
|
|
++
|
|
|
|
|
++ This file is distributed in the hope that it will be useful,
|
|
|
|
|
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
++ GNU Lesser General Public License for more details.
|
|
|
|
|
++
|
|
|
|
|
++ You should have received a copy of the GNU Lesser General Public License
|
|
|
|
|
++ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
|
|
|
|
++
|
|
|
|
|
++#include <config.h>
|
|
|
|
|
++
|
|
|
|
|
++#include <errno.h>
|
|
|
|
|
++#include <fcntl.h>
|
|
|
|
|
++#include <unistd.h>
|
|
|
|
|
++#include <stdint.h>
|
|
|
|
|
++#include <sys/fcntl.h>
|
|
|
|
|
++#include <sys/stat.h>
|
|
|
|
|
++
|
|
|
|
|
++#ifdef __APPLE__
|
|
|
|
|
++# include <sys/param.h>
|
|
|
|
|
++# include <sys/mount.h>
|
|
|
|
|
++#else
|
|
|
|
|
++# include <sys/statfs.h>
|
|
|
|
|
++#endif
|
|
|
|
|
++
|
|
|
|
|
++/* Reserve storage for the data of the file associated with FD. This
|
|
|
|
|
++ emulation is far from perfect, but the kernel cannot do not much
|
|
|
|
|
++ better for network file systems, either. */
|
|
|
|
|
++
|
|
|
|
|
++int
|
|
|
|
|
++posix_fallocate (int fd, off_t offset, off_t len)
|
|
|
|
|
++{
|
|
|
|
|
++ int ret;
|
|
|
|
|
++ struct stat st;
|
|
|
|
|
++
|
|
|
|
|
++ if (fd < 0 || offset < 0 || len < 0)
|
|
|
|
|
++ return EINVAL;
|
|
|
|
|
++
|
|
|
|
|
++ /* Perform overflow check. The outer cast relies on a GCC
|
|
|
|
|
++ extension. */
|
|
|
|
|
++ if ((off_t) ((uint64_t) offset + (uint64_t) len) < 0)
|
|
|
|
|
++ return EFBIG;
|
|
|
|
|
++
|
|
|
|
|
++ /* pwrite below will not do the right thing in O_APPEND mode. */
|
|
|
|
|
++ {
|
|
|
|
|
++ int flags = fcntl (fd, F_GETFL, 0);
|
|
|
|
|
++ if (flags < 0 || (flags & O_APPEND) != 0)
|
|
|
|
|
++ return EBADF;
|
|
|
|
|
++ }
|
|
|
|
|
++
|
|
|
|
|
++ /* We have to make sure that this is really a regular file. */
|
|
|
|
|
++ if (fstat (fd, &st) != 0)
|
|
|
|
|
++ return EBADF;
|
|
|
|
|
++ if (S_ISFIFO (st.st_mode))
|
|
|
|
|
++ return ESPIPE;
|
|
|
|
|
++ if (! S_ISREG (st.st_mode))
|
|
|
|
|
++ return ENODEV;
|
|
|
|
|
++
|
|
|
|
|
++ if (len == 0)
|
|
|
|
|
++ {
|
|
|
|
|
++ /* This is racy, but there is no good way to satisfy a
|
|
|
|
|
++ zero-length allocation request. */
|
|
|
|
|
++ if (st.st_size < offset)
|
|
|
|
|
++ {
|
|
|
|
|
++ ret = ftruncate (fd, offset);
|
|
|
|
|
++
|
|
|
|
|
++ if (ret != 0)
|
|
|
|
|
++ ret = errno;
|
|
|
|
|
++ return ret;
|
|
|
|
|
++ }
|
|
|
|
|
++ return ret;
|
|
|
|
|
++ }
|
|
|
|
|
++
|
|
|
|
|
++#ifdef __APPLE__
|
|
|
|
|
++ fstore_t sto = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, offset + len, 0};
|
|
|
|
|
++ /* allocate continuous */
|
|
|
|
|
++ ret = fcntl (fd, F_PREALLOCATE, &sto);
|
|
|
|
|
++ if (ret < 0)
|
|
|
|
|
++ {
|
|
|
|
|
++ /* allocate non-continuous */
|
|
|
|
|
++ sto.fst_flags = F_ALLOCATEALL;
|
|
|
|
|
++ ret = fcntl (fd, F_PREALLOCATE, &sto);
|
|
|
|
|
++ if (ret < 0)
|
|
|
|
|
++ {
|
|
|
|
|
++ return ret;
|
|
|
|
|
++ }
|
|
|
|
|
++ }
|
|
|
|
|
++ ret = ftruncate(fd, offset + len);
|
|
|
|
|
++#else
|
|
|
|
|
++
|
|
|
|
|
++ /* Minimize data transfer for network file systems, by issuing
|
|
|
|
|
++ single-byte write requests spaced by the file system block size.
|
|
|
|
|
++ (Most local file systems have fallocate support, so this fallback
|
|
|
|
|
++ code is not used there.) */
|
|
|
|
|
++
|
|
|
|
|
++ unsigned increment;
|
|
|
|
|
++ {
|
|
|
|
|
++ struct statfs f;
|
|
|
|
|
++
|
|
|
|
|
++ if (fstatfs (fd, &f) != 0)
|
|
|
|
|
++ return errno;
|
|
|
|
|
++ if (f.f_bsize == 0)
|
|
|
|
|
++ increment = 512;
|
|
|
|
|
++ else if (f.f_bsize < 4096)
|
|
|
|
|
++ increment = f.f_bsize;
|
|
|
|
|
++ else
|
|
|
|
|
++ /* NFS does not propagate the block size of the underlying
|
|
|
|
|
++ storage and may report a much larger value which would still
|
|
|
|
|
++ leave holes after the loop below, so we cap the increment at
|
|
|
|
|
++ 4096. */
|
|
|
|
|
++ increment = 4096;
|
|
|
|
|
++ }
|
|
|
|
|
++
|
|
|
|
|
++ /* Write a null byte to every block. This is racy; we currently
|
|
|
|
|
++ lack a better option. Compare-and-swap against a file mapping
|
|
|
|
|
++ might additional local races, but requires interposition of a
|
|
|
|
|
++ signal handler to catch SIGBUS. */
|
|
|
|
|
++ for (offset += (len - 1) % increment; len > 0; offset += increment)
|
|
|
|
|
++ {
|
|
|
|
|
++ len -= increment;
|
|
|
|
|
++
|
|
|
|
|
++ if (offset < st.st_size)
|
|
|
|
|
++ {
|
|
|
|
|
++ unsigned char c;
|
|
|
|
|
++ ssize_t rsize = pread (fd, &c, 1, offset);
|
|
|
|
|
++
|
|
|
|
|
++ if (rsize < 0)
|
|
|
|
|
++ return errno;
|
|
|
|
|
++ /* If there is a non-zero byte, the block must have been
|
|
|
|
|
++ allocated already. */
|
|
|
|
|
++ else if (rsize == 1 && c != 0)
|
|
|
|
|
++ continue;
|
|
|
|
|
++ }
|
|
|
|
|
++
|
|
|
|
|
++ if (pwrite (fd, "", 1, offset) != 1)
|
|
|
|
|
++ return errno;
|
|
|
|
|
++ }
|
|
|
|
|
++
|
|
|
|
|
++#endif /* __APPLE__ */
|
|
|
|
|
++
|
|
|
|
|
++ return ret;
|
|
|
|
|
++}
|
|
|
|
|
+--- a/MODULES.html.sh
|
|
|
|
|
++++ b/MODULES.html.sh
|
|
|
|
|
+@@ -2552,6 +2552,7 @@ func_all_modules ()
|
|
|
|
|
+ func_module execve
|
|
|
|
|
+ func_module execvp
|
|
|
|
|
+ func_module execvpe
|
|
|
|
|
++ func_module fallocate-posix
|
|
|
|
|
+ func_module fchdir
|
|
|
|
|
+ func_module fclose
|
|
|
|
|
+ func_module fcntl-h
|