Message ID | 20210319183121.2252064-3-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
Series | More stat fixes | expand |
On 19/03/2021 19:31, Adhemerval Zanella via Libc-alpha wrote: > 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 This will lead to a redefinition later in the file. > /* 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 FSTATAT_USE_STATX will be redefined as mentioned earlier > + > +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 > + The former __fstatat64_time64 is splitted into fstatat64_time64_statx and fstatat64_time64_stat. And if statx is always available, we can skip the stat part. OK > return INTERNAL_SYSCALL_ERROR_P (r) > ? INLINE_SYSCALL_ERROR_RETURN_VALUE (-r) > : 0; >
On 26/03/2021 06:24, Stefan Liebler via Libc-alpha wrote: > On 19/03/2021 19:31, Adhemerval Zanella via Libc-alpha wrote: >> 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 > This will lead to a redefinition later in the file. This is incorrect and a left over from a rebase, I will remove it.
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;