From 1fbffbda365ae8582981dfb284c83903931dd312 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Thu, 18 Mar 2021 22:30:23 +0300 Subject: linux: Disable fstatat64 fallback if __ASSUME_STATX is defined 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 | 56 ++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c index 490226a..4d936ee 100644 --- a/sysdeps/unix/sysv/linux/fstatat64.c +++ b/sysdeps/unix/sysv/linux/fstatat64.c @@ -40,27 +40,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 +112,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; -- cgit v1.1