From b97c3b0249d90d99e610db7588cc89aa3e92a770 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 29 Mar 2015 04:26:42 +0000 Subject: uClibc: add another missing backport patch Signed-off-by: Felix Fietkau SVN-Revision: 45102 --- .../023-libc-add-fallocate-and-fallocate64.patch | 447 +++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 toolchain/uClibc/patches-0.9.33.2/023-libc-add-fallocate-and-fallocate64.patch (limited to 'toolchain/uClibc/patches-0.9.33.2/023-libc-add-fallocate-and-fallocate64.patch') diff --git a/toolchain/uClibc/patches-0.9.33.2/023-libc-add-fallocate-and-fallocate64.patch b/toolchain/uClibc/patches-0.9.33.2/023-libc-add-fallocate-and-fallocate64.patch new file mode 100644 index 0000000000..282b64f52e --- /dev/null +++ b/toolchain/uClibc/patches-0.9.33.2/023-libc-add-fallocate-and-fallocate64.patch @@ -0,0 +1,447 @@ +From: "Anthony G. Basile" +Date: Sun, 7 Sep 2014 15:33:46 -0400 +Subject: [PATCH] libc: add fallocate() and fallocate64() + +We add the Linux-specific function fallocate() which allows the user to +directly manipulate allocate space for a file. fallocate() can operate +in different modes, but the default mode is equivalent to posix_fallocate() +which is specified in POSIX.1. + +Recent releases of e2fsprogs 1.42.11 and above expect fallocate64() to be +available. + +Signed-off-by: Anthony G. Basile +Signed-off-by: Bernhard Reutner-Fischer +--- + create mode 100644 libc/sysdeps/linux/common/fallocate.c + create mode 100644 libc/sysdeps/linux/common/fallocate64.c + create mode 100644 test/unistd/tst-fallocate.c + create mode 100644 test/unistd/tst-fallocate64.c + +--- a/extra/Configs/Config.in ++++ b/extra/Configs/Config.in +@@ -952,8 +952,8 @@ config UCLIBC_LINUX_SPECIFIC + default y + help + accept4(), bdflush(), +- capget(), capset(), eventfd(), fstatfs(), +- inotify_*(), ioperm(), iopl(), ++ capget(), capset(), eventfd(), fallocate(), ++ fstatfs(), inotify_*(), ioperm(), iopl(), + madvise(), modify_ldt(), pipe2(), personality(), + prctl()/arch_prctl(), pivot_root(), modify_ldt(), + ppoll(), readahead(), reboot(), remap_file_pages(), +--- a/include/fcntl.h ++++ b/include/fcntl.h +@@ -237,6 +237,38 @@ extern int __fcntl_nocancel (int fd, int + libc_hidden_proto(__fcntl_nocancel) + #endif + ++#if (defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU) || defined _LIBC ++/* Reserve storage for the data of a file associated with FD. This function ++ is Linux-specific. For the portable version, use posix_fallocate(). ++ Unlike the latter, fallocate can operate in different modes. The default ++ mode = 0 is equivalent to posix_fallocate(). ++ ++ Note: These declarations are used in posix_fallocate.c and ++ posix_fallocate64.c, so we expose them internally. ++ */ ++ ++/* Flags for fallocate's mode. */ ++# define FALLOC_FL_KEEP_SIZE 1 /* Don't extend size of file ++ even if offset + len is ++ greater than file size. */ ++# define FALLOC_FL_PUNCH_HOLE 2 /* Create a hole in the file. */ ++ ++# ifndef __USE_FILE_OFFSET64 ++extern int fallocate (int __fd, int __mode, __off_t __offset, __off_t __len); ++# else ++# ifdef __REDIRECT ++extern int __REDIRECT (fallocate, (int __fd, int __mode, __off64_t __offset, ++ __off64_t __len), ++ fallocate64); ++# else ++# define fallocate fallocate64 ++# endif ++# endif ++# ifdef __USE_LARGEFILE64 ++extern int fallocate64 (int __fd, int __mode, __off64_t __offset, __off64_t __len); ++# endif ++#endif ++ + __END_DECLS + + #endif /* fcntl.h */ +--- a/libc/sysdeps/linux/common/Makefile.in ++++ b/libc/sysdeps/linux/common/Makefile.in +@@ -61,6 +61,10 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \ + vmsplice.c + CSRC-$(if $(findstring yy,$(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_LFS)),y) += \ + sendfile64.c ++# posix_fallocate() needs __libc_fallocate() from fallocate.c ++# posix_fallocate64() needs __libc_fallocate64() from fallocate64.c ++CSRC-$(if $(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_ADVANCED_REALTIME),y,) += \ ++ fallocate.c $(filter fallocate64.c,$(CSRC-y)) + # NPTL needs these internally: madvise.c + CSRC-$(findstring y,$(UCLIBC_LINUX_SPECIFIC)$(UCLIBC_HAS_THREADS_NATIVE)) += madvise.c + ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y) +--- /dev/null ++++ b/libc/sysdeps/linux/common/fallocate.c +@@ -0,0 +1,48 @@ ++/* vi: set sw=4 ts=4: */ ++/* ++ * fallocate() for uClibc - Based off of posix_fallocate() by Erik Andersen ++ * http://www.opengroup.org/onlinepubs/9699919799/functions/posix_fallocate.html ++ * ++ * Copyright (C) 2000-2006 Erik Andersen ++ * ++ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#if defined __NR_fallocate ++extern __typeof(fallocate) __libc_fallocate attribute_hidden; ++int attribute_hidden __libc_fallocate(int fd, int mode, __off_t offset, __off_t len) ++{ ++ int ret; ++ ++# if __WORDSIZE == 32 ++ uint32_t off_low = offset; ++ uint32_t len_low = len; ++ /* may assert that these >>31 are 0 */ ++ uint32_t zero = 0; ++ INTERNAL_SYSCALL_DECL(err); ++ ret = (int) (INTERNAL_SYSCALL(fallocate, err, 6, fd, mode, ++ __LONG_LONG_PAIR (zero, off_low), ++ __LONG_LONG_PAIR (zero, len_low))); ++# elif __WORDSIZE == 64 ++ INTERNAL_SYSCALL_DECL(err); ++ ret = (int) (INTERNAL_SYSCALL(fallocate, err, 4, fd, mode, offset, len)); ++# else ++# error your machine is neither 32 bit or 64 bit ... it must be magical ++# endif ++ if (unlikely(INTERNAL_SYSCALL_ERROR_P (ret, err))) ++ return INTERNAL_SYSCALL_ERRNO (ret, err); ++ return 0; ++} ++ ++# if defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU ++strong_alias(__libc_fallocate,fallocate) ++# if __WORDSIZE == 64 ++strong_alias(__libc_fallocate,fallocate64) ++# endif ++# endif ++#endif +--- /dev/null ++++ b/libc/sysdeps/linux/common/fallocate64.c +@@ -0,0 +1,42 @@ ++/* vi: set sw=4 ts=4: */ ++/* ++ * fallocate() for uClibc - based off posix_fallocate() by Erik Andersen ++ * http://www.opengroup.org/onlinepubs/9699919799/functions/posix_fallocate.html ++ * ++ * Copyright (C) 2000-2006 Erik Andersen ++ * ++ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++#if defined __NR_fallocate ++ ++# if __WORDSIZE == 64 ++/* Can use normal fallocate() */ ++# elif __WORDSIZE == 32 ++extern __typeof(fallocate64) __libc_fallocate64 attribute_hidden; ++int attribute_hidden __libc_fallocate64(int fd, int mode, __off64_t offset, ++ __off64_t len) ++{ ++ int ret; ++ INTERNAL_SYSCALL_DECL(err); ++ ret = (int) (INTERNAL_SYSCALL(fallocate, err, 6, fd, mode, ++ OFF64_HI_LO (offset), OFF64_HI_LO (len))); ++ if (unlikely(INTERNAL_SYSCALL_ERROR_P (ret, err))) ++ return INTERNAL_SYSCALL_ERRNO (ret, err); ++ return 0; ++} ++ ++# if defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU ++strong_alias(__libc_fallocate64,fallocate64) ++# endif ++ ++# else ++# error your machine is neither 32 bit or 64 bit ... it must be magical ++# endif ++#endif +--- a/libc/sysdeps/linux/common/posix_fallocate.c ++++ b/libc/sysdeps/linux/common/posix_fallocate.c +@@ -14,28 +14,10 @@ + #include + + #if defined __NR_fallocate ++extern __typeof(fallocate) __libc_fallocate attribute_hidden; + int posix_fallocate(int fd, __off_t offset, __off_t len) + { +- int ret; +- +-# if __WORDSIZE == 32 +- uint32_t off_low = offset; +- uint32_t len_low = len; +- /* may assert that these >>31 are 0 */ +- uint32_t zero = 0; +- INTERNAL_SYSCALL_DECL(err); +- ret = (int) (INTERNAL_SYSCALL(fallocate, err, 6, fd, 0, +- __LONG_LONG_PAIR (zero, off_low), +- __LONG_LONG_PAIR (zero, len_low))); +-# elif __WORDSIZE == 64 +- INTERNAL_SYSCALL_DECL(err); +- ret = (int) (INTERNAL_SYSCALL(fallocate, err, 4, fd, 0, offset, len)); +-# else +-# error your machine is neither 32 bit or 64 bit ... it must be magical +-#endif +- if (unlikely(INTERNAL_SYSCALL_ERROR_P (ret, err))) +- return INTERNAL_SYSCALL_ERRNO (ret, err); +- return 0; ++ return __libc_fallocate(fd, 0, offset, len); + } + # if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64 + strong_alias(posix_fallocate,posix_fallocate64) +--- a/libc/sysdeps/linux/common/posix_fallocate64.c ++++ b/libc/sysdeps/linux/common/posix_fallocate64.c +@@ -18,22 +18,12 @@ + # if __WORDSIZE == 64 + /* Can use normal posix_fallocate() */ + # elif __WORDSIZE == 32 ++extern __typeof(fallocate64) __libc_fallocate64 attribute_hidden; + int posix_fallocate64(int fd, __off64_t offset, __off64_t len) + { +- int ret; +- uint32_t off_low = offset & 0xffffffff; +- uint32_t off_high = offset >> 32; +- uint32_t len_low = len & 0xffffffff; +- uint32_t len_high = len >> 32; +- INTERNAL_SYSCALL_DECL(err); +- ret = (int) (INTERNAL_SYSCALL(fallocate, err, 6, fd, 0, +- __LONG_LONG_PAIR (off_high, off_low), +- __LONG_LONG_PAIR (len_high, len_low))); +- if (unlikely(INTERNAL_SYSCALL_ERROR_P (ret, err))) +- return INTERNAL_SYSCALL_ERRNO (ret, err); +- return 0; ++ return __libc_fallocate64(fd, 0, offset, len); + } + # else +-# error your machine is neither 32 bit or 64 bit ... it must be magical ++# error your machine is neither 32 bit or 64 bit ... it must be magical + # endif + #endif +--- a/test/.gitignore ++++ b/test/.gitignore +@@ -302,6 +302,8 @@ unistd/getcwd + unistd/getopt + unistd/getopt_long + unistd/tstgetopt ++unistd/tst-fallocate ++unistd/tst-fallocate64 + unistd/tst-posix_fallocate + unistd/tst-posix_fallocate64 + unistd/tst-preadwrite +--- /dev/null ++++ b/test/unistd/tst-fallocate.c +@@ -0,0 +1,166 @@ ++#include ++#include ++ ++#ifndef TST_FALLOCATE64 ++# define stat64 stat ++# define fstat64 fstat ++# else ++# ifndef O_LARGEFILE ++# error no O_LARGEFILE but you want to test with LFS enabled ++# endif ++#endif ++ ++static void do_prepare(void); ++static int do_test(void); ++#define PREPARE(argc, argv) do_prepare () ++#define TEST_FUNCTION do_test () ++#include ++ ++static int fd; ++static void ++do_prepare (void) ++{ ++ fd = create_temp_file ("tst-fallocate.", NULL); ++ if (fd == -1) ++ { ++ printf ("cannot create temporary file: %m\n"); ++ exit (1); ++ } ++} ++ ++ ++static int ++do_test (void) ++{ ++ struct stat64 st; ++ int c; ++ char garbage[4096]; ++ blkcnt_t blksb4; ++ ++ if (fstat64 (fd, &st) != 0) ++ { ++ puts ("1st fstat failed"); ++ return 1; ++ } ++ ++ if (st.st_size != 0) ++ { ++ puts ("file not created with size 0"); ++ return 1; ++ } ++ ++ /* This is the default mode which is identical to posix_fallocate(). ++ Note: we need a few extra blocks for FALLOC_FL_PUNCH_HOLE below. ++ While block sizes vary, we'll assume eight 4K blocks for good measure. */ ++ if (fallocate (fd, 0, 8 * 4096, 128) != 0) ++ { ++ puts ("1st fallocate call failed"); ++ return 1; ++ } ++ ++ if (fstat64 (fd, &st) != 0) ++ { ++ puts ("2nd fstat failed"); ++ return 1; ++ } ++ ++ if (st.st_size != 8 * 4096 + 128) ++ { ++ printf ("file size after 1st fallocate call is %llu, expected %u\n", ++ (unsigned long long int) st.st_size, 8u * 4096u + 128u); ++ return 1; ++ } ++ ++ /* Without FALLOC_FL_KEEP_SIZE, this would increaste the size of the file. */ ++ if (fallocate (fd, FALLOC_FL_KEEP_SIZE, 0, 16 * 4096) != 0) ++ { ++ puts ("2nd fallocate call failed"); ++ return 1; ++ } ++ ++ if (fstat64 (fd, &st) != 0) ++ { ++ puts ("3rd fstat failed"); ++ return 1; ++ } ++ ++ if (st.st_size != 8 * 4096 + 128) ++ { ++ printf ("file size changed in 2nd fallocate call to %llu, expected %u\n", ++ (unsigned long long int) st.st_size, 8u * 4096u + 128u); ++ return 1; ++ } ++ ++ /* Let's fill up the first eight 4k blocks with 'x' to force some allocations. */ ++ ++ memset(garbage, 'x', 4096); ++ for(c=0; c < 8; c++) ++ if(write(fd, garbage, 4096) == -1) ++ { ++ puts ("write failed"); ++ return 1; ++ } ++ ++ if (fstat64 (fd, &st) != 0) ++ { ++ puts ("4th fstat failed"); ++ return 1; ++ } ++ ++ blksb4 = st.st_blocks; ++ ++ /* Let's punch a hole in the entire file, turning it effectively into a sparse file. */ ++ if (fallocate (fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 8 * 4096 + 128) != 0) ++ { ++ puts ("3rd fallocate call failed"); ++ return 1; ++ } ++ ++ if (fstat64 (fd, &st) != 0) ++ { ++ puts ("5th fstat failed"); ++ return 1; ++ } ++ ++ if (st.st_size != 8 * 4096 + 128) ++ { ++ printf ("file size after 3rd fallocate call is %llu, expected %u\n", ++ (unsigned long long int) st.st_size, 8u * 4096u + 128u); ++ return 1; ++ } ++ ++ /* The number of allocated blocks should decrease. I hope this works on ++ all filesystems! */ ++ if (st.st_blocks >= blksb4) ++ { ++ printf ("number of blocks after 3rd fallocate call is %lu, expected less than %lu\n", ++ (unsigned long int) st.st_blocks, blksb4); ++ return 1; ++ } ++ ++#ifdef TST_FALLOCATE64 ++ /* We'll just do a mode = 0 test for fallocate64() */ ++ if (fallocate64 (fd, 0, 4097ULL, 4294967295ULL + 2ULL) != 0) ++ { ++ puts ("1st fallocate64 call failed"); ++ return 1; ++ } ++ ++ if (fstat64 (fd, &st) != 0) ++ { ++ puts ("6th fstat failed"); ++ return 1; ++ } ++ ++ if (st.st_size != 4097ULL + 4294967295ULL + 2ULL) ++ { ++ printf ("file size after 1st fallocate64 call is %llu, expected %llu\n", ++ (unsigned long long int) st.st_size, 4097ULL + 4294967295ULL + 2ULL); ++ return 1; ++ } ++#endif ++ close (fd); ++ ++ return 0; ++} ++ +--- /dev/null ++++ b/test/unistd/tst-fallocate64.c +@@ -0,0 +1,2 @@ ++#define TST_FALLOCATE64 ++#include "tst-fallocate.c" +--- a/test/unistd/Makefile.in ++++ b/test/unistd/Makefile.in +@@ -2,10 +2,13 @@ + # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + + ifeq ($(UCLIBC_HAS_LFS),) +-TESTS_DISABLED := tst-preadwrite64 tst-posix_fallocate64 ++TESTS_DISABLED := tst-preadwrite64 tst-posix_fallocate64 tst-fallocate64 + endif + ifeq ($(UCLIBC_HAS_ADVANCED_REALTIME),) +-TESTS_DISABLED := tst-posix_fallocate ++TESTS_DISABLED := tst-posix_fallocate tst-fallocate64 ++endif ++ifeq ($(UCLIBC_LINUX_SPECIFIC),) ++TESTS_DISABLED += tst-fallocate + endif + OPTS_getopt := -abcXXX -9 + OPTS_getopt_long := --add XXX --delete YYY --verbose -- cgit v1.2.3