| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- --- /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
- @@ -26,7 +26,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])
- @@ -53,6 +53,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])
- @@ -64,10 +65,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
- @@ -241,6 +241,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
- @@ -2555,6 +2555,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
|