libc: add fallocate() and fallocate64()

Submitted by Anthony Basile on Sept. 1, 2014, 2:27 p.m.

Details

Message ID 1409581662-19636-1-git-send-email-basile@opensource.dyc.edu
State New
Headers show

Commit Message

Anthony Basile Sept. 1, 2014, 2:27 p.m.
From: "Anthony G. Basile" <blueness@gentoo.org>

We add the Linux-specific system call fallocate() which allows the user to
directly manipulate allocate space for a file.  The default operation is
equivalent to posix_fallocate() which is specified in POSIX.1.  However,
recent releases of e2fsprogs 1.42.11 and above expect fallocate() to be
available.

Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
---
 extra/Configs/Config.in                       |  1 +
 include/fcntl.h                               | 14 ++++++++
 libc/sysdeps/linux/common/Makefile.in         |  4 +--
 libc/sysdeps/linux/common/fallocate.c         | 51 +++++++++++++++++++++++++++
 libc/sysdeps/linux/common/fallocate64.c       | 44 +++++++++++++++++++++++
 libc/sysdeps/linux/common/posix_fallocate.c   | 21 +----------
 libc/sysdeps/linux/common/posix_fallocate64.c |  8 +----
 7 files changed, 114 insertions(+), 29 deletions(-)
 create mode 100644 libc/sysdeps/linux/common/fallocate.c
 create mode 100644 libc/sysdeps/linux/common/fallocate64.c

Comments

aldot Sept. 4, 2014, 11:48 a.m.
On 1 September 2014 16:27,  <basile@opensource.dyc.edu> wrote:
> From: "Anthony G. Basile" <blueness@gentoo.org>
>
> We add the Linux-specific system call fallocate() which allows the user to

Please only enable the non-hidden symbol if UCLIBC_LINUX_SPECIFIC is set.
Also, you seem to completely ignore the type of the function decl. You should
make sure the fallocate decl is visible when being compiled with _LIBC (i.e.
internally) and use extern __typeof(fallocate) _fallocate in the impl. We would
potentially miss changed function "signature" otherwise..
TIA,

> directly manipulate allocate space for a file.  The default operation is
> equivalent to posix_fallocate() which is specified in POSIX.1.  However,
> recent releases of e2fsprogs 1.42.11 and above expect fallocate() to be
> available.
Anthony Basile Sept. 6, 2014, 11:44 p.m.
On 09/04/14 07:48, Bernhard Reutner-Fischer wrote:
> On 1 September 2014 16:27,  <basile@opensource.dyc.edu> wrote:
>> From: "Anthony G. Basile" <blueness@gentoo.org>
>>
>> We add the Linux-specific system call fallocate() which allows the user to
>
> Please only enable the non-hidden symbol if UCLIBC_LINUX_SPECIFIC is set.
> Also, you seem to completely ignore the type of the function decl. You should
> make sure the fallocate decl is visible when being compiled with _LIBC (i.e.
> internally) and use extern __typeof(fallocate) _fallocate in the impl. We would
> potentially miss changed function "signature" otherwise..
> TIA,
>

Bernhard, thanks, it took me a bit but I see how to do it now.  I'm 
working on the patch because I also want to add tests for fallocates 
mode = FALLOC_FL_KEEP_SIZE and FALLOC_FL_PUNCH_HOLE.

However, in testing with UCLIBC_LINUX_SPECIFIC unset, I hit an error 
with statfs's libc_hidden_def/proto stuff:

libc/sysdeps/linux/common/statfs.c:51:1: error: '__EI_statfs' aliased to 
undefined symbol '__GI_statfs'
make: *** [libc/sysdeps/linux/common/statfs.os] Error 1
make: *** Waiting for unfinished jobs....

The fix is trivial.  I'm sending a patch in my next email.

Patch hide | download patch | download mbox

diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index 7789002..b22ffc7 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -1155,6 +1155,7 @@  config UCLIBC_HAS_ADVANCED_REALTIME
 
 	  clock_getcpuclockid()
 	  clock_nanosleep()
+	  fallocate()
 	  mq_timedreceive()
 	  mq_timedsend()
 	  posix_fadvise()
diff --git a/include/fcntl.h b/include/fcntl.h
index c749ad5..c46cdc0 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -225,17 +225,31 @@  extern int posix_fadvise64 (int __fd, __off64_t __offset, __off64_t __len,
    marked with __THROW.  */
 # ifndef __USE_FILE_OFFSET64
 extern int posix_fallocate (int __fd, __off_t __offset, __off_t __len);
+#   ifdef __USE_GNU
+extern int fallocate (int __fd, int __mode, __off_t __offset, __off_t __len);
+#   endif
 # else
 #  ifdef __REDIRECT
 extern int __REDIRECT (posix_fallocate, (int __fd, __off64_t __offset,
 					 __off64_t __len),
 		       posix_fallocate64);
+#   ifdef __USE_GNU
+extern int __REDIRECT (fallocate, (int __fd, int __mode, __off64_t __offset,
+					 __off64_t __len),
+		       fallocate64);
+#   endif
 #  else
 #   define posix_fallocate posix_fallocate64
+#   ifdef __USE_GNU
+#    define fallocate fallocate64
+#   endif
 #  endif
 # endif
 # ifdef __USE_LARGEFILE64
 extern int posix_fallocate64 (int __fd, __off64_t __offset, __off64_t __len);
+#  ifdef __USE_GNU
+extern int fallocate64 (int __fd, int __mode, __off64_t __offset, __off64_t __len);
+#  endif
 # endif
 #endif
 
diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in
index 13dd77b..b0f1bde 100644
--- a/libc/sysdeps/linux/common/Makefile.in
+++ b/libc/sysdeps/linux/common/Makefile.in
@@ -86,9 +86,9 @@  CSRC-$(UCLIBC_HAS_REALTIME) += clock_adjtime.c clock_getres.c clock_gettime.c cl
 	nanosleep.c __rt_sigtimedwait.c __rt_sigwaitinfo.c sched_getparam.c \
 	sched_get_priority_max.c sched_get_priority_min.c sched_getscheduler.c \
 	sched_rr_get_interval.c sched_setparam.c sched_setscheduler.c sigqueue.c
-# clock_getcpuclockid|clock_nanosleep|mq_timedreceive|mq_timedsend|posix_fadvise|posix_fallocate|posix_madvise|posix_memalign|posix_mem_offset|posix_spawnattr_destroy|posix_spawnattr_init|posix_spawnattr_getflags|posix_spawnattr_setflags|posix_spawnattr_getpgroup|posix_spawnattr_setpgroup|posix_spawnattr_getschedparam|posix_spawnattr_setschedparam|posix_spawnattr_getschedpolicy|posix_spawnattr_setschedpolicy|posix_spawnattr_getsigdefault|posix_spawnattr_setsigdefault|posix_spawnattr_getsigmask|posix_spawnattr_setsigmask|posix_spawnattr_init|posix_spawnattr_setflags|posix_spawnattr_setpgroup|posix_spawnattr_setschedparam|posix_spawnattr_setschedpolicy|posix_spawnattr_setsigdefault|posix_spawnattr_setsigmask|posix_spawn_file_actions_addclose|posix_spawn_file_actions_addopen|posix_spawn_file_actions_adddup2|posix_spawn_file_actions_addopen|posix_spawn_file_actions_destroy|posix_spawn_file_actions_init|posix_spawn_file_actions_init|posix_spawn|posix_spawnp|posix_spawnp|posix_typ
 ed_mem_g
 et_info|pthread_mutex_timedlock|sem_timedwait
+# clock_getcpuclockid|clock_nanosleep|mq_timedreceive|mq_timedsend|posix_fadvise|posix_fallocate|fallocate|posix_madvise|posix_memalign|posix_mem_offset|posix_spawnattr_destroy|posix_spawnattr_init|posix_spawnattr_getflags|posix_spawnattr_setflags|posix_spawnattr_getpgroup|posix_spawnattr_setpgroup|posix_spawnattr_getschedparam|posix_spawnattr_setschedparam|posix_spawnattr_getschedpolicy|posix_spawnattr_setschedpolicy|posix_spawnattr_getsigdefault|posix_spawnattr_setsigdefault|posix_spawnattr_getsigmask|posix_spawnattr_setsigmask|posix_spawnattr_init|posix_spawnattr_setflags|posix_spawnattr_setpgroup|posix_spawnattr_setschedparam|posix_spawnattr_setschedpolicy|posix_spawnattr_setsigdefault|posix_spawnattr_setsigmask|posix_spawn_file_actions_addclose|posix_spawn_file_actions_addopen|posix_spawn_file_actions_adddup2|posix_spawn_file_actions_addopen|posix_spawn_file_actions_destroy|posix_spawn_file_actions_init|posix_spawn_file_actions_init|posix_spawn|posix_spawnp|posix_spawnp
 |posix_t
 yped_mem_get_info|pthread_mutex_timedlock|sem_timedwait
 CSRC-$(UCLIBC_HAS_ADVANCED_REALTIME) += posix_fadvise64.c posix_fadvise.c posix_madvise.c \
-	posix_fallocate.c posix_fallocate64.c
+	posix_fallocate.c posix_fallocate64.c fallocate.c fallocate64.c
 CSRC-$(UCLIBC_SUSV4_LEGACY) += utime.c
 CSRC-$(UCLIBC_HAS_EPOLL) += epoll.c
 CSRC-$(UCLIBC_HAS_XATTR) += xattr.c
diff --git a/libc/sysdeps/linux/common/fallocate.c b/libc/sysdeps/linux/common/fallocate.c
new file mode 100644
index 0000000..4f37265
--- /dev/null
+++ b/libc/sysdeps/linux/common/fallocate.c
@@ -0,0 +1,51 @@ 
+/* 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 <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <bits/kernel-features.h>
+#include <stdint.h>
+
+#if defined __NR_fallocate
+int attribute_hidden _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 __USE_GNU
+int fallocate(int fd, int mode, __off_t offset, __off_t len)
+{
+	return _fallocate(fd, mode, offset, len);
+}
+#  if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64
+strong_alias(fallocate,fallocate64)
+#  endif
+# endif
+
+#endif
diff --git a/libc/sysdeps/linux/common/fallocate64.c b/libc/sysdeps/linux/common/fallocate64.c
new file mode 100644
index 0000000..9dc0234
--- /dev/null
+++ b/libc/sysdeps/linux/common/fallocate64.c
@@ -0,0 +1,44 @@ 
+/* 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 <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
+ */
+
+#include <sys/syscall.h>
+
+#include <fcntl.h>
+#include <bits/kernel-features.h>
+#include <stdint.h>
+
+#if defined __NR_fallocate
+
+# if __WORDSIZE == 64
+/* Can use normal fallocate() */
+# elif __WORDSIZE == 32
+int attribute_hidden _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 __USE_GNU
+int fallocate64(int fd, int mode, __off64_t offset, __off64_t len)
+{
+	return _fallocate64(fd, mode, offset, len);
+}
+#  endif
+
+# else
+# error your machine is neither 32 bit or 64 bit ... it must be magical
+# endif
+#endif
+
diff --git a/libc/sysdeps/linux/common/posix_fallocate.c b/libc/sysdeps/linux/common/posix_fallocate.c
index 9aaa6ce..0da9267 100644
--- a/libc/sysdeps/linux/common/posix_fallocate.c
+++ b/libc/sysdeps/linux/common/posix_fallocate.c
@@ -16,26 +16,7 @@ 
 #if defined __NR_fallocate
 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 _fallocate(fd, 0, offset, len);
 }
 # if defined __UCLIBC_HAS_LFS__ && __WORDSIZE == 64
 strong_alias(posix_fallocate,posix_fallocate64)
diff --git a/libc/sysdeps/linux/common/posix_fallocate64.c b/libc/sysdeps/linux/common/posix_fallocate64.c
index 76dc9b8..f003a57 100644
--- a/libc/sysdeps/linux/common/posix_fallocate64.c
+++ b/libc/sysdeps/linux/common/posix_fallocate64.c
@@ -20,13 +20,7 @@ 
 # elif __WORDSIZE == 32
 int posix_fallocate64(int fd, __off64_t offset, __off64_t len)
 {
-	int ret;
-	INTERNAL_SYSCALL_DECL(err);
-	ret = (int) (INTERNAL_SYSCALL(fallocate, err, 6, fd, 0,
-		OFF64_HI_LO (offset), OFF64_HI_LO (len)));
-    if (unlikely(INTERNAL_SYSCALL_ERROR_P (ret, err)))
-      return INTERNAL_SYSCALL_ERRNO (ret, err);
-    return 0;
+	return _fallocate64(fd, 0, offset, len);
 }
 # else
 # error your machine is neither 32 bit or 64 bit ... it must be magical