[PATCH 2/5] linux: Disable fstatat64 fallback if __ASSUME_STATX is defined

Adhemerval Zanella adhemerval.zanella@linaro.org
Fri Mar 19 18:31:18 GMT 2021


If the minimum kernel supports statx there is no need to call the
fallback stat legacy syscalls.

The statx is also called on compat xstat syscall, but different
than the fstatat it calls no fallback and it is assumed to be
always present.

Checked on powerpc-linux-gnu (with and without --enable-kernel=4.11)
and on powerpc64-linux-gnu.
---
 sysdeps/unix/sysv/linux/fstatat64.c | 57 +++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 16 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index 490226a8ec..c3a030af58 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -31,6 +31,7 @@
 #if __TIMESIZE == 64 \
      && (__WORDSIZE == 32 \
      && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+# define FSTATAT_USE_STATX 1
 /* Sanity check to avoid newer 32-bit ABI to support non-LFS calls.  */
 _Static_assert (sizeof (__off_t) == sizeof (__off64_t),
                 "__blkcnt_t and __blkcnt64_t must match");
@@ -40,27 +41,25 @@ _Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t),
                 "__blkcnt_t and __blkcnt64_t must match");
 #endif
 
-int
-__fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *buf,
-		    int flag)
+static inline int
+fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
+			int flag)
 {
-  int r;
-
-#if (__WORDSIZE == 32 \
-     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
   /* 32-bit kABI with default 64-bit time_t, e.g. arc, riscv32.   Also
      64-bit time_t support is done through statx syscall.  */
   struct statx tmp;
-  r = INTERNAL_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
-			     STATX_BASIC_STATS, &tmp);
+  int r = INTERNAL_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
+				 STATX_BASIC_STATS, &tmp);
   if (r == 0)
-    {
-      __cp_stat64_t64_statx (buf, &tmp);
-      return 0;
-    }
-  if (-r != ENOSYS)
-    return INLINE_SYSCALL_ERROR_RETURN_VALUE (-r);
-#endif
+    __cp_stat64_t64_statx (buf, &tmp);
+  return r;
+}
+
+static inline int
+fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
+		       int flag)
+{
+  int r;
 
 #if XSTAT_IS_XSTAT64
 # ifdef __NR_newfstatat
@@ -114,6 +113,32 @@ __fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *buf,
 # endif
 #endif
 
+  return r;
+}
+
+#if (__WORDSIZE == 32 \
+     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+# define FSTATAT_USE_STATX 1
+#else
+# define FSTATAT_USE_STATX 0
+#endif
+
+int
+__fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *buf,
+		    int flag)
+{
+  int r;
+
+#if FSTATAT_USE_STATX
+  r = fstatat64_time64_statx (fd, file, buf, flag);
+# ifndef __ASSUME_STATX
+  if (r == -ENOSYS)
+    r = fstatat64_time64_stat (fd, file, buf, flag);
+# endif
+#else
+  r = fstatat64_time64_stat (fd, file, buf, flag);
+#endif
+
   return INTERNAL_SYSCALL_ERROR_P (r)
 	 ? INLINE_SYSCALL_ERROR_RETURN_VALUE (-r)
 	 : 0;
-- 
2.25.1



More information about the Libc-alpha mailing list