public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] More stat fixes
@ 2021-03-19 18:31 Adhemerval Zanella
  2021-03-19 18:31 ` [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64 Adhemerval Zanella
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-19 18:31 UTC (permalink / raw)
  To: libc-alpha

This patchset fixes 2 issues recently found with newer stat tests
(s390-32 missing nanoseconds support on legacy stat calls and
MIPSn64 y2106 limitation), adds the __ASSUME_STATX optimization
on fstatat/fstatat64, and improve the 64 bit timestamp tests on
Linux.

I have checked on i686-linux-gnu and x86_64-linux-gnu
(kernel 5.4 x86_64-64) and on powerpc-linux-gnu and
(kernel 5.10 ppc64).

I also tested the utimensat tests on mips64el on two kernels:
4.1.4 (without statx support) and 5.10 (with statx support).
On 4.1.4 kernel the tst-utime now shows the missing y2106
support:

| $ ./testrun mist/tst-utime
| warning: skipping tests[3] { 100000000, fffffffe }: unsupported timestamp value
| warning: skipping tests[4] { 100000001, 100000002 }: unsupported timestamp value

While on a 5.10 kernel all the tests pass without any warning.

Adhemerval Zanella (5):
  linux: Implement fstatat with __fstatat64_time64
  linux: Disable fstatat64 fallback if __ASSUME_STATX is defined
  linux: Use statx for MIPSn64
  support: Add support_path_support_time64_value
  linux: Add y2106 support on utimensat tests

 support/support.h                             | 11 ++-
 support/support_path_support_time64.c         | 10 +-
 sysdeps/unix/sysv/linux/fstatat.c             | 52 +++--------
 sysdeps/unix/sysv/linux/fstatat64.c           | 82 +++++++++++++----
 sysdeps/unix/sysv/linux/fxstat64.c            |  1 +
 sysdeps/unix/sysv/linux/mips/kernel_stat.h    |  4 +
 sysdeps/unix/sysv/linux/statx_cp.c            | 29 ------
 sysdeps/unix/sysv/linux/tst-futimens.c        | 63 ++-----------
 sysdeps/unix/sysv/linux/tst-utime.c           | 63 ++-----------
 .../unix/sysv/linux/tst-utimensat-skeleton.c  | 92 +++++++++++++++++++
 sysdeps/unix/sysv/linux/tst-utimes.c          | 68 +++-----------
 11 files changed, 212 insertions(+), 263 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c

-- 
2.25.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64
  2021-03-19 18:31 [PATCH 0/5] More stat fixes Adhemerval Zanella
@ 2021-03-19 18:31 ` Adhemerval Zanella
  2021-03-23 16:13   ` Stefan Liebler
  2021-03-26  9:24   ` Stefan Liebler
  2021-03-19 18:31 ` [PATCH 2/5] linux: Disable fstatat64 fallback if __ASSUME_STATX is defined Adhemerval Zanella
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-19 18:31 UTC (permalink / raw)
  To: libc-alpha

It makes fstatat use __NR_statx, which fix the s390 issue with
missing nanoxsecond support on compat stat syscalls (at least
on recent kernels) and limits the statx call to only one function
(which simplifies the __ASSUME_STATX support).

Checked on i686-linux-gnu and on powerpc-linux-gnu.
---
 sysdeps/unix/sysv/linux/fstatat.c | 52 +++++++------------------------
 1 file changed, 11 insertions(+), 41 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/fstatat.c b/sysdeps/unix/sysv/linux/fstatat.c
index 59efff615f..618c254d6f 100644
--- a/sysdeps/unix/sysv/linux/fstatat.c
+++ b/sysdeps/unix/sysv/linux/fstatat.c
@@ -26,33 +26,19 @@
 int
 __fstatat (int fd, const char *file, struct stat *buf, int flag)
 {
-  int r;
-
-# if STAT_IS_KERNEL_STAT
-  /* New kABIs which uses generic pre 64-bit time Linux ABI, e.g.
-     csky, nios2  */
-  r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, buf, flag);
-  if (r == 0 && (buf->__st_ino_pad != 0
-		 || buf->__st_size_pad != 0
-		 || buf->__st_blocks_pad != 0))
-    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
-# else
-#  ifdef __NR_fstatat64
-  /* Old KABIs with old non-LFS support, e.g. arm, i386, hppa, m68k, mips32,
-     microblaze, s390, sh, powerpc, and sparc.  */
-  struct stat64 st64;
-  r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
+  struct __stat64_t64 st64;
+  int r = __fstatat64_time64 (fd, file, &st64, flag);
   if (r == 0)
     {
       if (! in_ino_t_range (st64.st_ino)
 	  || ! in_off_t_range (st64.st_size)
-	  || ! in_blkcnt_t_range (st64.st_blocks))
+	  || ! in_blkcnt_t_range (st64.st_blocks)
+	  || ! in_time_t_range (st64.st_atim.tv_sec)
+	  || ! in_time_t_range (st64.st_mtim.tv_sec)
+	  || ! in_time_t_range (st64.st_ctim.tv_sec))
 	return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
 
-      /* Clear internal pad and reserved fields.  */
-      memset (buf, 0, sizeof (*buf));
-
-      buf->st_dev = st64.st_dev,
+      buf->st_dev = st64.st_dev;
       buf->st_ino = st64.st_ino;
       buf->st_mode = st64.st_mode;
       buf->st_nlink = st64.st_nlink;
@@ -62,27 +48,11 @@ __fstatat (int fd, const char *file, struct stat *buf, int flag)
       buf->st_size = st64.st_size;
       buf->st_blksize = st64.st_blksize;
       buf->st_blocks  = st64.st_blocks;
-      buf->st_atim.tv_sec = st64.st_atim.tv_sec;
-      buf->st_atim.tv_nsec = st64.st_atim.tv_nsec;
-      buf->st_mtim.tv_sec = st64.st_mtim.tv_sec;
-      buf->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;
-      buf->st_ctim.tv_sec = st64.st_ctim.tv_sec;
-      buf->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;
-
-      return 0;
+      buf->st_atim = valid_timespec64_to_timespec (st64.st_atim);
+      buf->st_mtim = valid_timespec64_to_timespec (st64.st_mtim);
+      buf->st_ctim = valid_timespec64_to_timespec (st64.st_ctim);
     }
-#  else
-  /* 64-bit kabi outlier, e.g. mips64 and mips64-n32.  */
-  struct kernel_stat kst;
-  r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
-  if (r == 0)
-    r = __cp_kstat_stat (&kst, buf);
-#  endif /* __nr_fstatat64  */
-# endif /* STAT_IS_KERNEL_STAT  */
-
-  return INTERNAL_SYSCALL_ERROR_P (r)
-	 ? INLINE_SYSCALL_ERROR_RETURN_VALUE (-r)
-	 : 0;
+  return r;
 }
 
 weak_alias (__fstatat, fstatat)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2/5] linux: Disable fstatat64 fallback if __ASSUME_STATX is defined
  2021-03-19 18:31 [PATCH 0/5] More stat fixes Adhemerval Zanella
  2021-03-19 18:31 ` [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64 Adhemerval Zanella
@ 2021-03-19 18:31 ` Adhemerval Zanella
  2021-03-26  9:24   ` Stefan Liebler
  2021-03-19 18:31 ` [PATCH 3/5] linux: Use statx for MIPSn64 Adhemerval Zanella
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-19 18:31 UTC (permalink / raw)
  To: libc-alpha

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


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 3/5] linux: Use statx for MIPSn64
  2021-03-19 18:31 [PATCH 0/5] More stat fixes Adhemerval Zanella
  2021-03-19 18:31 ` [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64 Adhemerval Zanella
  2021-03-19 18:31 ` [PATCH 2/5] linux: Disable fstatat64 fallback if __ASSUME_STATX is defined Adhemerval Zanella
@ 2021-03-19 18:31 ` Adhemerval Zanella
  2021-03-29 12:48   ` Adhemerval Zanella
  2021-04-01  0:07   ` Maciej W. Rozycki
  2021-03-19 18:31 ` [PATCH 4/5] support: Add support_path_support_time64_value Adhemerval Zanella
  2021-03-19 18:31 ` [PATCH 5/5] linux: Add y2106 support on utimensat tests Adhemerval Zanella
  4 siblings, 2 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-19 18:31 UTC (permalink / raw)
  To: libc-alpha

MIPSn64 kernel ABI for legacy stat uses unsigned 32 bit for second
timestamp, which limits the maximum value to y2106.  This patch
make mips64 use statx as for 32-bit architectures.

Thie __cp_stat64_t64_statx is open coded, its usage is solely on
fstatat64 and it avoid the need to redefine the name for mips64
(which will call __cp_stat64_statx since its does not use
__stat64_t64 internally).
---
 sysdeps/unix/sysv/linux/fstatat64.c        | 29 +++++++++++++++++++---
 sysdeps/unix/sysv/linux/fxstat64.c         |  1 +
 sysdeps/unix/sysv/linux/mips/kernel_stat.h |  4 +++
 sysdeps/unix/sysv/linux/statx_cp.c         | 29 ----------------------
 4 files changed, 30 insertions(+), 33 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index c3a030af58..b9b8cd994b 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -24,9 +24,9 @@
 #include <kernel_stat.h>
 #include <sysdep.h>
 #include <time.h>
-#include <statx_cp.h>
 #include <kstat_cp.h>
 #include <stat_t64_cp.h>
+#include <sys/sysmacros.h>
 
 #if __TIMESIZE == 64 \
      && (__WORDSIZE == 32 \
@@ -50,8 +50,28 @@ fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
   struct statx 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);
+  if (r != 0)
+    return r;
+
+  *buf = (struct __stat64_t64) {
+    .st_dev = makedev (tmp.stx_dev_major, tmp.stx_dev_minor),
+    .st_rdev = makedev (tmp.stx_rdev_major, tmp.stx_rdev_minor),
+    .st_ino = tmp.stx_ino,
+    .st_mode = tmp.stx_mode,
+    .st_nlink = tmp.stx_nlink,
+    .st_uid = tmp.stx_uid,
+    .st_gid = tmp.stx_gid,
+    .st_atime = tmp.stx_atime.tv_sec,
+    .st_atim.tv_nsec = tmp.stx_atime.tv_nsec,
+    .st_mtime = tmp.stx_mtime.tv_sec,
+    .st_mtim.tv_nsec = tmp.stx_mtime.tv_nsec,
+    .st_ctime = tmp.stx_ctime.tv_sec,
+    .st_ctim.tv_nsec = tmp.stx_ctime.tv_nsec,
+    .st_size = tmp.stx_size,
+    .st_blocks = tmp.stx_blocks,
+    .st_blksize = tmp.stx_blksize,
+  };
+
   return r;
 }
 
@@ -117,7 +137,8 @@ fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
 }
 
 #if (__WORDSIZE == 32 \
-     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
+     || defined STAT_HAS_TIME32
 # define FSTATAT_USE_STATX 1
 #else
 # define FSTATAT_USE_STATX 0
diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
index be12798273..23d9d92b00 100644
--- a/sysdeps/unix/sysv/linux/fxstat64.c
+++ b/sysdeps/unix/sysv/linux/fxstat64.c
@@ -25,6 +25,7 @@
 #include <xstatconv.h>
 #include <statx_cp.h>
 #include <shlib-compat.h>
+#include <sys/sysmacros.h>
 
 #if LIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_33)
 
diff --git a/sysdeps/unix/sysv/linux/mips/kernel_stat.h b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
index e4b0f211ca..19524f7ea4 100644
--- a/sysdeps/unix/sysv/linux/mips/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
@@ -67,5 +67,9 @@ struct kernel_stat
 #else
 # define STATFS_IS_STATFS64 0
 #endif
+/* MIPS64 has unsigned 32 bit timestamps fields, so use statx as well.  */
+#if _MIPS_SIM == _ABI64
+# define STAT_HAS_TIME32
+#endif
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/statx_cp.c b/sysdeps/unix/sysv/linux/statx_cp.c
index 53068704c6..73405a9612 100644
--- a/sysdeps/unix/sysv/linux/statx_cp.c
+++ b/sysdeps/unix/sysv/linux/statx_cp.c
@@ -48,32 +48,3 @@ __cp_stat64_statx (struct stat64 *to, struct statx *from)
 }
 #endif
 
-#if (__WORDSIZE == 32 \
-     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
-void
-__cp_stat64_t64_statx (struct __stat64_t64 *to, const struct statx *from)
-{
-  /* Clear both pad and reserved fields.  */
-  memset (to, 0, sizeof (*to));
-
-  to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major << 8)
-		| ((from->stx_dev_minor & ~0xff) << 12));
-  to->st_ino = from->stx_ino;
-  to->st_mode = from->stx_mode;
-  to->st_nlink = from->stx_nlink;
-  to->st_uid = from->stx_uid;
-  to->st_gid = from->stx_gid;
-  to->st_rdev = ((from->stx_rdev_minor & 0xff) | (from->stx_rdev_major << 8)
-		 | ((from->stx_rdev_minor & ~0xff) << 12));
-  to->st_size = from->stx_size;
-  to->st_blksize = from->stx_blksize;
-  to->st_blocks = from->stx_blocks;
-
-  to->st_atime = from->stx_atime.tv_sec;
-  to->st_atim.tv_nsec = from->stx_atime.tv_nsec;
-  to->st_mtime = from->stx_mtime.tv_sec;
-  to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec;
-  to->st_ctime = from->stx_ctime.tv_sec;
-  to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec;
-}
-#endif
-- 
2.25.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 4/5] support: Add support_path_support_time64_value
  2021-03-19 18:31 [PATCH 0/5] More stat fixes Adhemerval Zanella
                   ` (2 preceding siblings ...)
  2021-03-19 18:31 ` [PATCH 3/5] linux: Use statx for MIPSn64 Adhemerval Zanella
@ 2021-03-19 18:31 ` Adhemerval Zanella
  2021-03-26  9:24   ` Stefan Liebler
  2021-03-19 18:31 ` [PATCH 5/5] linux: Add y2106 support on utimensat tests Adhemerval Zanella
  4 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-19 18:31 UTC (permalink / raw)
  To: libc-alpha

It allows to check for support on arbitrary timestamp values.
---
 support/support.h                     | 11 +++++++++--
 support/support_path_support_time64.c | 10 +++-------
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/support/support.h b/support/support.h
index 2e477c9e7c..5757c40833 100644
--- a/support/support.h
+++ b/support/support.h
@@ -130,9 +130,16 @@ extern void support_copy_file (const char *from, const char *to);
 extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *,
 					size_t, unsigned int);
 
-/* Return true is PATH supports 64-bit time_t interfaces for file
+/* Return true if PATH supports 64-bit time_t interfaces for file
    operations (such as fstatat or utimensat).  */
-extern bool support_path_support_time64 (const char *path);
+extern bool support_path_support_time64_value (const char *path, int64_t at,
+					       int64_t mt);
+static __inline bool support_path_support_time64 (const char *path)
+{
+  /* 1s and 2s after y2038 limit.  */
+  return support_path_support_time64_value (path, 0x80000001ULL,
+					    0x80000002ULL);
+}
 
 __END_DECLS
 
diff --git a/support/support_path_support_time64.c b/support/support_path_support_time64.c
index 452fedcde5..33b2bdff66 100644
--- a/support/support_path_support_time64.c
+++ b/support/support_path_support_time64.c
@@ -36,19 +36,15 @@ utimesat_call (const char *path, const struct __timespec64 tsp[2])
 #endif
 
 bool
-support_path_support_time64 (const char *path)
+support_path_support_time64_value (const char *path, int64_t at, int64_t mt)
 {
 #ifdef __linux__
   /* Obtain the original timestamps to restore at the end.  */
   struct statx ostx;
   TEST_VERIFY_EXIT (statx (AT_FDCWD, path, 0, STATX_BASIC_STATS, &ostx) == 0);
 
-  const struct __timespec64 tsp[] =
-  {
-    /* 1s and 2s after y2038 limit.  */
-    { 0x80000001ULL, 0 },
-    { 0x80000002ULL, 0 }
-  };
+  const struct __timespec64 tsp[] = { { at, 0 }, { mt, 0 } };
+
   /* Return is kernel does not support __NR_utimensat_time64.  */
   if (utimesat_call (path, tsp) == -1)
     return false;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 5/5] linux: Add y2106 support on utimensat tests
  2021-03-19 18:31 [PATCH 0/5] More stat fixes Adhemerval Zanella
                   ` (3 preceding siblings ...)
  2021-03-19 18:31 ` [PATCH 4/5] support: Add support_path_support_time64_value Adhemerval Zanella
@ 2021-03-19 18:31 ` Adhemerval Zanella
  2021-03-26  9:24   ` Stefan Liebler
  4 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-19 18:31 UTC (permalink / raw)
  To: libc-alpha

The tests are refactored to use a common skeleton that handles whether
the underlying filesystem supports 64 bit time, skips 64 bit time
tests when the TU only supports 32 bit, and also skip 64 bit time
tests larger than 32 unsigned int (y2106) if the system does not
support it (MIPSn64 on kernels without statx support).

Checked on x86_64-linux-gnu and i686-linux-gnu.  I also checked
on a mips64el-linux-gnu with 4.1.4 and 5.10.0-4-5kc-malta kernel
to verify if the y2106 are indeed skipped.
---
 sysdeps/unix/sysv/linux/tst-futimens.c        | 63 ++-----------
 sysdeps/unix/sysv/linux/tst-utime.c           | 63 ++-----------
 .../unix/sysv/linux/tst-utimensat-skeleton.c  | 92 +++++++++++++++++++
 sysdeps/unix/sysv/linux/tst-utimes.c          | 68 +++-----------
 4 files changed, 120 insertions(+), 166 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c

diff --git a/sysdeps/unix/sysv/linux/tst-futimens.c b/sysdeps/unix/sysv/linux/tst-futimens.c
index 785cd87557..ac7a980017 100644
--- a/sysdeps/unix/sysv/linux/tst-futimens.c
+++ b/sysdeps/unix/sysv/linux/tst-futimens.c
@@ -16,57 +16,18 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
 #include <support/check.h>
-#include <support/support.h>
 #include <support/xunistd.h>
-#include <support/temp_file.h>
-
-static int temp_fd = -1;
-static char *testfile;
-
-/* struct timespec array with Y2038 threshold minus 2 and 1 seconds.  */
-const struct timespec t1[2] = { { 0x7FFFFFFE, 0 },  { 0x7FFFFFFF, 0 } };
-
-/* struct timespec array with Y2038 threshold plus 1 and 2 seconds.  */
-const struct timespec t2[2] = { { 0x80000001ULL, 0 },  { 0x80000002ULL, 0 } };
-
-/* struct timespec array around Y2038 threshold.  */
-const struct timespec t3[2] = { { 0x7FFFFFFE, 0 },  { 0x80000002ULL, 0 } };
-
-#define PREPARE do_prepare
-static void
-do_prepare (int argc, char *argv[])
-{
-  temp_fd = create_temp_file ("futimensat", &testfile);
-  TEST_VERIFY_EXIT (temp_fd > 0);
-}
+#include <sys/stat.h>
 
 static int
-test_futimens_helper (const struct timespec *ts)
+test_futimens_helper (const char *file, int fd, const struct timespec *ts)
 {
-  if (!support_path_support_time64 (testfile))
-    FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
-		      testfile);
-
-  struct stat64 st;
-  int result;
-  time_t t;
-
-  /* Check if we run on port with 32 bit time_t size */
-  if (__builtin_add_overflow (ts->tv_sec, 0, &t))
-    {
-      printf("time_t overflow!");
-      return 0;
-    }
-
-  result = futimens (temp_fd, ts);
+  int result = futimens (fd, ts);
   TEST_VERIFY_EXIT (result == 0);
 
-  xfstat (temp_fd, &st);
+  struct stat64 st;
+  xfstat (fd, &st);
 
   /* Check if seconds for atime match */
   TEST_COMPARE (st.st_atime, ts[0].tv_sec);
@@ -77,14 +38,8 @@ test_futimens_helper (const struct timespec *ts)
   return 0;
 }
 
-static int
-do_test (void)
-{
-  test_futimens_helper (&t1[0]);
-  test_futimens_helper (&t2[0]);
-  test_futimens_helper (&t3[0]);
-
-  return 0;
-}
+#define TEST_CALL(fname, fd, v1, v2) \
+  test_futimens_helper (fname, fd, (struct timespec[]) { { v1, 0 }, \
+							 { v2, 0 } })
 
-#include <support/test-driver.c>
+#include "tst-utimensat-skeleton.c"
diff --git a/sysdeps/unix/sysv/linux/tst-utime.c b/sysdeps/unix/sysv/linux/tst-utime.c
index 21e4e41dea..c1c7e75a29 100644
--- a/sysdeps/unix/sysv/linux/tst-utime.c
+++ b/sysdeps/unix/sysv/linux/tst-utime.c
@@ -16,59 +16,19 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
 #include <utime.h>
 #include <support/check.h>
-#include <support/support.h>
 #include <support/xunistd.h>
-#include <support/temp_file.h>
-
-static int temp_fd = -1;
-static char *testfile;
-
-/* struct utimbuf with Y2038 threshold minus 2 and 1 seconds.  */
-const static struct utimbuf t1 = { 0x7FFFFFFE, 0x7FFFFFFF };
-
-/* struct utimbuf with Y2038 threshold plus 1 and 2 seconds.  */
-const static struct utimbuf t2 = { 0x80000001ULL, 0x80000002ULL };
-
-/* struct utimbuf around Y2038 threshold.  */
-const static struct utimbuf t3 = { 0x7FFFFFFE, 0x80000002ULL };
-
-#define PREPARE do_prepare
-static void
-do_prepare (int argc, char *argv[])
-{
-  temp_fd = create_temp_file ("utime", &testfile);
-  TEST_VERIFY_EXIT (temp_fd > 0);
-}
+#include <sys/stat.h>
 
 static int
-test_utime_helper (const struct utimbuf *ut)
+test_utime_helper (const char *file, int fd, const struct utimbuf *ut)
 {
-  if (!support_path_support_time64 (testfile))
-    FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
-		      testfile);
-
-  struct stat64 st;
-  int result;
-  time_t t;
-
-  /* Check if we run on port with 32 bit time_t size */
-  if (__builtin_add_overflow (ut->actime, 0, &t))
-    {
-      printf("time_t overflow!");
-      return 0;
-    }
-
-  result = utime (testfile, ut);
+  int result = utime (file, ut);
   TEST_VERIFY_EXIT (result == 0);
 
-  xfstat (temp_fd, &st);
+  struct stat64 st;
+  xfstat (fd, &st);
 
   /* Check if seconds for actime match */
   TEST_COMPARE (st.st_atime, ut->actime);
@@ -79,14 +39,7 @@ test_utime_helper (const struct utimbuf *ut)
   return 0;
 }
 
-static int
-do_test (void)
-{
-  test_utime_helper (&t1);
-  test_utime_helper (&t2);
-  test_utime_helper (&t3);
-
-  return 0;
-}
+#define TEST_CALL(fname, fd, v1, v2) \
+  test_utime_helper (fname, fd, &(struct utimbuf) { (v1), (v2) })
 
-#include <support/test-driver.c>
+#include "tst-utimensat-skeleton.c"
diff --git a/sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c b/sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c
new file mode 100644
index 0000000000..ed3d537b1f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c
@@ -0,0 +1,92 @@
+/* Common tests for utimensat routines.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <array_length.h>
+#include <inttypes.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <stdio.h>
+
+static int temp_fd = -1;
+static char *testfile;
+
+const static struct {
+  int64_t v1;
+  int64_t v2;
+} tests[] = {
+  /* Y2038 threshold minus 2 and 1 seconds.  */
+  { 0x7FFFFFFELL, 0x7FFFFFFFLL },
+  /* Y2038 threshold plus 1 and 2 seconds.  */
+  { 0x80000001LL, 0x80000002LL },
+  /* Around Y2038 threshold.  */
+  { 0x7FFFFFFELL, 0x80000002LL },
+  /* Y2106 threshold minus 2 and 1 seconds.  */
+  { 0x100000000LL, 0xFFFFFFFELL },
+  /* Y2106 threshold plus 1 and 2 seconds.  */
+  { 0x100000001LL, 0x100000002LL },
+  /* Around Y2106 threshold.  */
+  { 0xFFFFFFFELL, 0xFFFFFFFELL },
+};
+
+#define PREPARE do_prepare
+static void
+do_prepare (int argc, char *argv[])
+{
+  temp_fd = create_temp_file ("utime", &testfile);
+  TEST_VERIFY_EXIT (temp_fd > 0);
+}
+
+static int
+do_test (void)
+{
+  if (!support_path_support_time64 (testfile))
+    FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
+		      testfile);
+
+  bool y2106 = support_path_support_time64_value (testfile,
+						  0x100000001LL,
+						  0x100000002LL);
+
+  for (int i = 0; i < array_length (tests); i++)
+    {
+      /* Check if we run on port with 32 bit time_t size.  */
+      time_t t;
+      if (__builtin_add_overflow (tests[i].v1, 0, &t)
+	  || __builtin_add_overflow (tests[i].v2, 0, &t))
+        {
+          printf ("warning: skipping tests[%d] { %" PRIx64 ", %" PRIx64 " }: "
+		  "time_t overflows\n", i, tests[i].v1, tests[i].v2);
+	  continue;
+        }
+
+      if (tests[i].v1 >= 0x100000000LL && !y2106)
+	{
+          printf ("warning: skipping tests[%d] { %" PRIx64 ", %" PRIx64 " }: "
+		  "unsupported timestamp value\n",
+		  i, tests[i].v1, tests[i].v2);
+	  continue;
+	}
+
+      //test_utime_helper (&(struct utimbuf) { tests[i].v1, tests[i].v2 });
+      TEST_CALL (testfile, temp_fd, tests[i].v1, tests[i].v2);
+    }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/tst-utimes.c b/sysdeps/unix/sysv/linux/tst-utimes.c
index 0f23e44897..ba710508b7 100644
--- a/sysdeps/unix/sysv/linux/tst-utimes.c
+++ b/sysdeps/unix/sysv/linux/tst-utimes.c
@@ -16,60 +16,20 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/time.h>
 #include <support/check.h>
-#include <support/support.h>
 #include <support/xunistd.h>
-#include <support/temp_file.h>
-
-static int temp_fd = -1;
-static char *testfile;
-
-/* struct timeval array with Y2038 threshold minus 2 and 1 seconds.  */
-const static struct timeval t1[2] = { { 0x7FFFFFFE, 0 },  { 0x7FFFFFFF, 0 } };
-
-/* struct timeval array with Y2038 threshold plus 1 and 2 seconds.  */
-const static
-struct timeval t2[2] = { { 0x80000001ULL, 0 },  { 0x80000002ULL, 0 } };
-
-/* struct timeval array around Y2038 threshold.  */
-const static
-struct timeval t3[2] = { { 0x7FFFFFFE, 0 },  { 0x80000002ULL, 0 } };
-
-#define PREPARE do_prepare
-static void
-do_prepare (int argc, char *argv[])
-{
-  temp_fd = create_temp_file ("utimes", &testfile);
-  TEST_VERIFY_EXIT (temp_fd > 0);
-}
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <time.h>
 
 static int
-test_utime_helper (const struct timeval *tv)
+test_utimes_helper (const char *file, int fd, const struct timeval *tv)
 {
-  if (!support_path_support_time64 (testfile))
-    FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
-		      testfile);
-
-  struct stat64 st;
-  int result;
-  time_t t;
-
-  /* Check if we run on port with 32 bit time_t size */
-  if (__builtin_add_overflow (tv->tv_sec, 0, &t))
-    {
-      printf("time_t overflow!");
-      return 0;
-    }
-
-  result = utimes (testfile, tv);
+  int result = utimes (file, tv);
   TEST_VERIFY_EXIT (result == 0);
 
-  xfstat (temp_fd, &st);
+  struct stat64 st;
+  xfstat (fd, &st);
 
   /* Check if seconds for atime match */
   TEST_COMPARE (st.st_atime, tv[0].tv_sec);
@@ -80,14 +40,8 @@ test_utime_helper (const struct timeval *tv)
   return 0;
 }
 
-static int
-do_test (void)
-{
-  test_utime_helper (&t1[0]);
-  test_utime_helper (&t2[0]);
-  test_utime_helper (&t3[0]);
-
-  return 0;
-}
+#define TEST_CALL(fname, fd, v1, v2) \
+  test_utimes_helper (fname, fd, (struct timeval[]) { { v1, 0 }, \
+						      { v2, 0 } })
 
-#include <support/test-driver.c>
+#include "tst-utimensat-skeleton.c"
-- 
2.25.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64
  2021-03-19 18:31 ` [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64 Adhemerval Zanella
@ 2021-03-23 16:13   ` Stefan Liebler
  2021-03-26  9:24   ` Stefan Liebler
  1 sibling, 0 replies; 18+ messages in thread
From: Stefan Liebler @ 2021-03-23 16:13 UTC (permalink / raw)
  To: libc-alpha

On 19/03/2021 19:31, Adhemerval Zanella via Libc-alpha wrote:
> It makes fstatat use __NR_statx, which fix the s390 issue with
> missing nanoxsecond support on compat stat syscalls (at least
> on recent kernels) and limits the statx call to only one function
> (which simplifies the __ASSUME_STATX support).
> 
> Checked on i686-linux-gnu and on powerpc-linux-gnu.
> ---

Hi Adhemerval,

I've applied your series and on s390, io/tst-stat is now passing as stat
is now using statx and the nanosecond fields are not zero anymore.

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64
  2021-03-19 18:31 ` [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64 Adhemerval Zanella
  2021-03-23 16:13   ` Stefan Liebler
@ 2021-03-26  9:24   ` Stefan Liebler
  2021-03-26 19:32     ` Adhemerval Zanella
  1 sibling, 1 reply; 18+ messages in thread
From: Stefan Liebler @ 2021-03-26  9:24 UTC (permalink / raw)
  To: libc-alpha

On 19/03/2021 19:31, Adhemerval Zanella via Libc-alpha wrote:
> It makes fstatat use __NR_statx, which fix the s390 issue with
> missing nanoxsecond support on compat stat syscalls (at least
> on recent kernels) and limits the statx call to only one function
> (which simplifies the __ASSUME_STATX support).
> 
> Checked on i686-linux-gnu and on powerpc-linux-gnu.
> ---
>  sysdeps/unix/sysv/linux/fstatat.c | 52 +++++++------------------------
>  1 file changed, 11 insertions(+), 41 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/fstatat.c b/sysdeps/unix/sysv/linux/fstatat.c
> index 59efff615f..618c254d6f 100644
> --- a/sysdeps/unix/sysv/linux/fstatat.c
> +++ b/sysdeps/unix/sysv/linux/fstatat.c
> @@ -26,33 +26,19 @@
>  int
>  __fstatat (int fd, const char *file, struct stat *buf, int flag)
>  {
> -  int r;
> -
> -# if STAT_IS_KERNEL_STAT
> -  /* New kABIs which uses generic pre 64-bit time Linux ABI, e.g.
> -     csky, nios2  */
> -  r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, buf, flag);
> -  if (r == 0 && (buf->__st_ino_pad != 0
> -		 || buf->__st_size_pad != 0
> -		 || buf->__st_blocks_pad != 0))
> -    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
> -# else
> -#  ifdef __NR_fstatat64
> -  /* Old KABIs with old non-LFS support, e.g. arm, i386, hppa, m68k, mips32,
> -     microblaze, s390, sh, powerpc, and sparc.  */
> -  struct stat64 st64;
> -  r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
> +  struct __stat64_t64 st64;
> +  int r = __fstatat64_time64 (fd, file, &st64, flag);
>    if (r == 0)
>      {
>        if (! in_ino_t_range (st64.st_ino)
>  	  || ! in_off_t_range (st64.st_size)
> -	  || ! in_blkcnt_t_range (st64.st_blocks))
> +	  || ! in_blkcnt_t_range (st64.st_blocks)
> +	  || ! in_time_t_range (st64.st_atim.tv_sec)
> +	  || ! in_time_t_range (st64.st_mtim.tv_sec)
> +	  || ! in_time_t_range (st64.st_ctim.tv_sec))
>  	return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
OK
> 
> -      /* Clear internal pad and reserved fields.  */
> -      memset (buf, 0, sizeof (*buf));
Do we have to clear the user provided struct as before?

> -
> -      buf->st_dev = st64.st_dev,
> +      buf->st_dev = st64.st_dev;
>        buf->st_ino = st64.st_ino;
>        buf->st_mode = st64.st_mode;
>        buf->st_nlink = st64.st_nlink;
> @@ -62,27 +48,11 @@ __fstatat (int fd, const char *file, struct stat *buf, int flag)
>        buf->st_size = st64.st_size;
>        buf->st_blksize = st64.st_blksize;
>        buf->st_blocks  = st64.st_blocks;
> -      buf->st_atim.tv_sec = st64.st_atim.tv_sec;
> -      buf->st_atim.tv_nsec = st64.st_atim.tv_nsec;
> -      buf->st_mtim.tv_sec = st64.st_mtim.tv_sec;
> -      buf->st_mtim.tv_nsec = st64.st_mtim.tv_nsec;
> -      buf->st_ctim.tv_sec = st64.st_ctim.tv_sec;
> -      buf->st_ctim.tv_nsec = st64.st_ctim.tv_nsec;
> -
> -      return 0;
> +      buf->st_atim = valid_timespec64_to_timespec (st64.st_atim);
> +      buf->st_mtim = valid_timespec64_to_timespec (st64.st_mtim);
> +      buf->st_ctim = valid_timespec64_to_timespec (st64.st_ctim);
>      }
> -#  else
> -  /* 64-bit kabi outlier, e.g. mips64 and mips64-n32.  */
> -  struct kernel_stat kst;
> -  r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
> -  if (r == 0)
> -    r = __cp_kstat_stat (&kst, buf);
> -#  endif /* __nr_fstatat64  */
> -# endif /* STAT_IS_KERNEL_STAT  */
> -
> -  return INTERNAL_SYSCALL_ERROR_P (r)
> -	 ? INLINE_SYSCALL_ERROR_RETURN_VALUE (-r)
> -	 : 0;
> +  return r;
>  }
> 
>  weak_alias (__fstatat, fstatat)
> 
OK

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/5] linux: Disable fstatat64 fallback if __ASSUME_STATX is defined
  2021-03-19 18:31 ` [PATCH 2/5] linux: Disable fstatat64 fallback if __ASSUME_STATX is defined Adhemerval Zanella
@ 2021-03-26  9:24   ` Stefan Liebler
  2021-03-26 19:38     ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Liebler @ 2021-03-26  9:24 UTC (permalink / raw)
  To: libc-alpha

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;
> 


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 4/5] support: Add support_path_support_time64_value
  2021-03-19 18:31 ` [PATCH 4/5] support: Add support_path_support_time64_value Adhemerval Zanella
@ 2021-03-26  9:24   ` Stefan Liebler
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Liebler @ 2021-03-26  9:24 UTC (permalink / raw)
  To: libc-alpha

On 19/03/2021 19:31, Adhemerval Zanella via Libc-alpha wrote:
> It allows to check for support on arbitrary timestamp values.
> ---
>  support/support.h                     | 11 +++++++++--
>  support/support_path_support_time64.c | 10 +++-------
>  2 files changed, 12 insertions(+), 9 deletions(-)
> 
> diff --git a/support/support.h b/support/support.h
> index 2e477c9e7c..5757c40833 100644
> --- a/support/support.h
> +++ b/support/support.h
> @@ -130,9 +130,16 @@ extern void support_copy_file (const char *from, const char *to);
>  extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *,
>  					size_t, unsigned int);
> 
> -/* Return true is PATH supports 64-bit time_t interfaces for file
> +/* Return true if PATH supports 64-bit time_t interfaces for file
>     operations (such as fstatat or utimensat).  */
> -extern bool support_path_support_time64 (const char *path);
> +extern bool support_path_support_time64_value (const char *path, int64_t at,
> +					       int64_t mt);
> +static __inline bool support_path_support_time64 (const char *path)
> +{
> +  /* 1s and 2s after y2038 limit.  */
> +  return support_path_support_time64_value (path, 0x80000001ULL,
> +					    0x80000002ULL);
> +}
> 
>  __END_DECLS
> 
> diff --git a/support/support_path_support_time64.c b/support/support_path_support_time64.c
> index 452fedcde5..33b2bdff66 100644
> --- a/support/support_path_support_time64.c
> +++ b/support/support_path_support_time64.c
> @@ -36,19 +36,15 @@ utimesat_call (const char *path, const struct __timespec64 tsp[2])
>  #endif
> 
>  bool
> -support_path_support_time64 (const char *path)
> +support_path_support_time64_value (const char *path, int64_t at, int64_t mt)
>  {
>  #ifdef __linux__
>    /* Obtain the original timestamps to restore at the end.  */
>    struct statx ostx;
>    TEST_VERIFY_EXIT (statx (AT_FDCWD, path, 0, STATX_BASIC_STATS, &ostx) == 0);
> 
> -  const struct __timespec64 tsp[] =
> -  {
> -    /* 1s and 2s after y2038 limit.  */
> -    { 0x80000001ULL, 0 },
> -    { 0x80000002ULL, 0 }
> -  };
> +  const struct __timespec64 tsp[] = { { at, 0 }, { mt, 0 } };
> +
>    /* Return is kernel does not support __NR_utimensat_time64.  */
>    if (utimesat_call (path, tsp) == -1)
>      return false;
> 
OK

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] linux: Add y2106 support on utimensat tests
  2021-03-19 18:31 ` [PATCH 5/5] linux: Add y2106 support on utimensat tests Adhemerval Zanella
@ 2021-03-26  9:24   ` Stefan Liebler
  2021-03-26 19:40     ` Adhemerval Zanella
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Liebler @ 2021-03-26  9:24 UTC (permalink / raw)
  To: libc-alpha

On 19/03/2021 19:31, Adhemerval Zanella via Libc-alpha wrote:
> The tests are refactored to use a common skeleton that handles whether
> the underlying filesystem supports 64 bit time, skips 64 bit time
> tests when the TU only supports 32 bit, and also skip 64 bit time
> tests larger than 32 unsigned int (y2106) if the system does not
> support it (MIPSn64 on kernels without statx support).
> 
> Checked on x86_64-linux-gnu and i686-linux-gnu.  I also checked
> on a mips64el-linux-gnu with 4.1.4 and 5.10.0-4-5kc-malta kernel
> to verify if the y2106 are indeed skipped.
> ---
>  sysdeps/unix/sysv/linux/tst-futimens.c        | 63 ++-----------
>  sysdeps/unix/sysv/linux/tst-utime.c           | 63 ++-----------
>  .../unix/sysv/linux/tst-utimensat-skeleton.c  | 92 +++++++++++++++++++
>  sysdeps/unix/sysv/linux/tst-utimes.c          | 68 +++-----------
>  4 files changed, 120 insertions(+), 166 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c
> 
> diff --git a/sysdeps/unix/sysv/linux/tst-futimens.c b/sysdeps/unix/sysv/linux/tst-futimens.c
> index 785cd87557..ac7a980017 100644
> --- a/sysdeps/unix/sysv/linux/tst-futimens.c
> +++ b/sysdeps/unix/sysv/linux/tst-futimens.c
> @@ -16,57 +16,18 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
> 
> -#include <time.h>
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <sys/stat.h>
>  #include <support/check.h>
> -#include <support/support.h>
>  #include <support/xunistd.h>
> -#include <support/temp_file.h>
> -
> -static int temp_fd = -1;
> -static char *testfile;
> -
> -/* struct timespec array with Y2038 threshold minus 2 and 1 seconds.  */
> -const struct timespec t1[2] = { { 0x7FFFFFFE, 0 },  { 0x7FFFFFFF, 0 } };
> -
> -/* struct timespec array with Y2038 threshold plus 1 and 2 seconds.  */
> -const struct timespec t2[2] = { { 0x80000001ULL, 0 },  { 0x80000002ULL, 0 } };
> -
> -/* struct timespec array around Y2038 threshold.  */
> -const struct timespec t3[2] = { { 0x7FFFFFFE, 0 },  { 0x80000002ULL, 0 } };
> -
> -#define PREPARE do_prepare
> -static void
> -do_prepare (int argc, char *argv[])
> -{
> -  temp_fd = create_temp_file ("futimensat", &testfile);
> -  TEST_VERIFY_EXIT (temp_fd > 0);
> -}
> +#include <sys/stat.h>
> 
>  static int
> -test_futimens_helper (const struct timespec *ts)
> +test_futimens_helper (const char *file, int fd, const struct timespec *ts)
>  {
> -  if (!support_path_support_time64 (testfile))
> -    FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
> -		      testfile);
> -
> -  struct stat64 st;
> -  int result;
> -  time_t t;
> -
> -  /* Check if we run on port with 32 bit time_t size */
> -  if (__builtin_add_overflow (ts->tv_sec, 0, &t))
> -    {
> -      printf("time_t overflow!");
> -      return 0;
> -    }
> -
> -  result = futimens (temp_fd, ts);
> +  int result = futimens (fd, ts);
>    TEST_VERIFY_EXIT (result == 0);
> 
> -  xfstat (temp_fd, &st);
> +  struct stat64 st;
> +  xfstat (fd, &st);
> 
>    /* Check if seconds for atime match */
>    TEST_COMPARE (st.st_atime, ts[0].tv_sec);
> @@ -77,14 +38,8 @@ test_futimens_helper (const struct timespec *ts)
>    return 0;
>  }
> 
> -static int
> -do_test (void)
> -{
> -  test_futimens_helper (&t1[0]);
> -  test_futimens_helper (&t2[0]);
> -  test_futimens_helper (&t3[0]);
> -
> -  return 0;
> -}
> +#define TEST_CALL(fname, fd, v1, v2) \
> +  test_futimens_helper (fname, fd, (struct timespec[]) { { v1, 0 }, \
> +							 { v2, 0 } })
> 
> -#include <support/test-driver.c>
> +#include "tst-utimensat-skeleton.c"
OK

> diff --git a/sysdeps/unix/sysv/linux/tst-utime.c b/sysdeps/unix/sysv/linux/tst-utime.c
> index 21e4e41dea..c1c7e75a29 100644
> --- a/sysdeps/unix/sysv/linux/tst-utime.c
> +++ b/sysdeps/unix/sysv/linux/tst-utime.c
> @@ -16,59 +16,19 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
> 
> -#include <time.h>
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <sys/stat.h>
> -#include <sys/types.h>
>  #include <utime.h>
>  #include <support/check.h>
> -#include <support/support.h>
>  #include <support/xunistd.h>
> -#include <support/temp_file.h>
> -
> -static int temp_fd = -1;
> -static char *testfile;
> -
> -/* struct utimbuf with Y2038 threshold minus 2 and 1 seconds.  */
> -const static struct utimbuf t1 = { 0x7FFFFFFE, 0x7FFFFFFF };
> -
> -/* struct utimbuf with Y2038 threshold plus 1 and 2 seconds.  */
> -const static struct utimbuf t2 = { 0x80000001ULL, 0x80000002ULL };
> -
> -/* struct utimbuf around Y2038 threshold.  */
> -const static struct utimbuf t3 = { 0x7FFFFFFE, 0x80000002ULL };
> -
> -#define PREPARE do_prepare
> -static void
> -do_prepare (int argc, char *argv[])
> -{
> -  temp_fd = create_temp_file ("utime", &testfile);
> -  TEST_VERIFY_EXIT (temp_fd > 0);
> -}
> +#include <sys/stat.h>
> 
>  static int
> -test_utime_helper (const struct utimbuf *ut)
> +test_utime_helper (const char *file, int fd, const struct utimbuf *ut)
>  {
> -  if (!support_path_support_time64 (testfile))
> -    FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
> -		      testfile);
> -
> -  struct stat64 st;
> -  int result;
> -  time_t t;
> -
> -  /* Check if we run on port with 32 bit time_t size */
> -  if (__builtin_add_overflow (ut->actime, 0, &t))
> -    {
> -      printf("time_t overflow!");
> -      return 0;
> -    }
> -
> -  result = utime (testfile, ut);
> +  int result = utime (file, ut);
>    TEST_VERIFY_EXIT (result == 0);
> 
> -  xfstat (temp_fd, &st);
> +  struct stat64 st;
> +  xfstat (fd, &st);
> 
>    /* Check if seconds for actime match */
>    TEST_COMPARE (st.st_atime, ut->actime);
> @@ -79,14 +39,7 @@ test_utime_helper (const struct utimbuf *ut)
>    return 0;
>  }
> 
> -static int
> -do_test (void)
> -{
> -  test_utime_helper (&t1);
> -  test_utime_helper (&t2);
> -  test_utime_helper (&t3);
> -
> -  return 0;
> -}
> +#define TEST_CALL(fname, fd, v1, v2) \
> +  test_utime_helper (fname, fd, &(struct utimbuf) { (v1), (v2) })
> 
> -#include <support/test-driver.c>
> +#include "tst-utimensat-skeleton.c"
OK

> diff --git a/sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c b/sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c
> new file mode 100644
> index 0000000000..ed3d537b1f
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-utimensat-skeleton.c
> @@ -0,0 +1,92 @@
> +/* Common tests for utimensat routines.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +#include <array_length.h>
> +#include <inttypes.h>
> +#include <support/support.h>
> +#include <support/temp_file.h>
> +#include <stdio.h>
> +
> +static int temp_fd = -1;
> +static char *testfile;
> +
> +const static struct {
> +  int64_t v1;
> +  int64_t v2;
> +} tests[] = {
> +  /* Y2038 threshold minus 2 and 1 seconds.  */
> +  { 0x7FFFFFFELL, 0x7FFFFFFFLL },
> +  /* Y2038 threshold plus 1 and 2 seconds.  */
> +  { 0x80000001LL, 0x80000002LL },
> +  /* Around Y2038 threshold.  */
> +  { 0x7FFFFFFELL, 0x80000002LL },
> +  /* Y2106 threshold minus 2 and 1 seconds.  */
> +  { 0x100000000LL, 0xFFFFFFFELL },
> +  /* Y2106 threshold plus 1 and 2 seconds.  */
> +  { 0x100000001LL, 0x100000002LL },
> +  /* Around Y2106 threshold.  */
> +  { 0xFFFFFFFELL, 0xFFFFFFFELL },
> +};
> +
> +#define PREPARE do_prepare
> +static void
> +do_prepare (int argc, char *argv[])
> +{
> +  temp_fd = create_temp_file ("utime", &testfile);
> +  TEST_VERIFY_EXIT (temp_fd > 0);
> +}
> +
> +static int
> +do_test (void)
> +{
> +  if (!support_path_support_time64 (testfile))
> +    FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
> +		      testfile);
> +
> +  bool y2106 = support_path_support_time64_value (testfile,
> +						  0x100000001LL,
> +						  0x100000002LL);
> +
> +  for (int i = 0; i < array_length (tests); i++)
> +    {
> +      /* Check if we run on port with 32 bit time_t size.  */
> +      time_t t;
> +      if (__builtin_add_overflow (tests[i].v1, 0, &t)
> +	  || __builtin_add_overflow (tests[i].v2, 0, &t))
Thanks for also testing v2 instead of only v1 in the former tests.
> +        {
> +          printf ("warning: skipping tests[%d] { %" PRIx64 ", %" PRIx64 " }: "
> +		  "time_t overflows\n", i, tests[i].v1, tests[i].v2);
> +	  continue;
> +        }
> +
> +      if (tests[i].v1 >= 0x100000000LL && !y2106)
> +	{
> +          printf ("warning: skipping tests[%d] { %" PRIx64 ", %" PRIx64 " }: "
> +		  "unsupported timestamp value\n",
> +		  i, tests[i].v1, tests[i].v2);
> +	  continue;
> +	}
> +
> +      //test_utime_helper (&(struct utimbuf) { tests[i].v1, tests[i].v2 });
Do we need this comment?
> +      TEST_CALL (testfile, temp_fd, tests[i].v1, tests[i].v2);
> +    }
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
OK

> diff --git a/sysdeps/unix/sysv/linux/tst-utimes.c b/sysdeps/unix/sysv/linux/tst-utimes.c
> index 0f23e44897..ba710508b7 100644
> --- a/sysdeps/unix/sysv/linux/tst-utimes.c
> +++ b/sysdeps/unix/sysv/linux/tst-utimes.c
> @@ -16,60 +16,20 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
> 
> -#include <time.h>
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <sys/stat.h>
> -#include <sys/time.h>
>  #include <support/check.h>
> -#include <support/support.h>
>  #include <support/xunistd.h>
> -#include <support/temp_file.h>
> -
> -static int temp_fd = -1;
> -static char *testfile;
> -
> -/* struct timeval array with Y2038 threshold minus 2 and 1 seconds.  */
> -const static struct timeval t1[2] = { { 0x7FFFFFFE, 0 },  { 0x7FFFFFFF, 0 } };
> -
> -/* struct timeval array with Y2038 threshold plus 1 and 2 seconds.  */
> -const static
> -struct timeval t2[2] = { { 0x80000001ULL, 0 },  { 0x80000002ULL, 0 } };
> -
> -/* struct timeval array around Y2038 threshold.  */
> -const static
> -struct timeval t3[2] = { { 0x7FFFFFFE, 0 },  { 0x80000002ULL, 0 } };
> -
> -#define PREPARE do_prepare
> -static void
> -do_prepare (int argc, char *argv[])
> -{
> -  temp_fd = create_temp_file ("utimes", &testfile);
> -  TEST_VERIFY_EXIT (temp_fd > 0);
> -}
> +#include <sys/stat.h>
> +#include <sys/time.h>
> +#include <time.h>
> 
>  static int
> -test_utime_helper (const struct timeval *tv)
> +test_utimes_helper (const char *file, int fd, const struct timeval *tv)
>  {
> -  if (!support_path_support_time64 (testfile))
> -    FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
> -		      testfile);
> -
> -  struct stat64 st;
> -  int result;
> -  time_t t;
> -
> -  /* Check if we run on port with 32 bit time_t size */
> -  if (__builtin_add_overflow (tv->tv_sec, 0, &t))
> -    {
> -      printf("time_t overflow!");
> -      return 0;
> -    }
> -
> -  result = utimes (testfile, tv);
> +  int result = utimes (file, tv);
>    TEST_VERIFY_EXIT (result == 0);
> 
> -  xfstat (temp_fd, &st);
> +  struct stat64 st;
> +  xfstat (fd, &st);
> 
>    /* Check if seconds for atime match */
>    TEST_COMPARE (st.st_atime, tv[0].tv_sec);
> @@ -80,14 +40,8 @@ test_utime_helper (const struct timeval *tv)
>    return 0;
>  }
> 
> -static int
> -do_test (void)
> -{
> -  test_utime_helper (&t1[0]);
> -  test_utime_helper (&t2[0]);
> -  test_utime_helper (&t3[0]);
> -
> -  return 0;
> -}
> +#define TEST_CALL(fname, fd, v1, v2) \
> +  test_utimes_helper (fname, fd, (struct timeval[]) { { v1, 0 }, \
> +						      { v2, 0 } })
> 
> -#include <support/test-driver.c>
> +#include "tst-utimensat-skeleton.c"
> 
Ok

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64
  2021-03-26  9:24   ` Stefan Liebler
@ 2021-03-26 19:32     ` Adhemerval Zanella
  0 siblings, 0 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-26 19:32 UTC (permalink / raw)
  To: libc-alpha



On 26/03/2021 06:24, Stefan Liebler via Libc-alpha wrote:
> On 19/03/2021 19:31, Adhemerval Zanella via Libc-alpha wrote:
>> It makes fstatat use __NR_statx, which fix the s390 issue with
>> missing nanoxsecond support on compat stat syscalls (at least
>> on recent kernels) and limits the statx call to only one function
>> (which simplifies the __ASSUME_STATX support).
>>
>> Checked on i686-linux-gnu and on powerpc-linux-gnu.
>> ---
>>  sysdeps/unix/sysv/linux/fstatat.c | 52 +++++++------------------------
>>  1 file changed, 11 insertions(+), 41 deletions(-)
>>
>> diff --git a/sysdeps/unix/sysv/linux/fstatat.c b/sysdeps/unix/sysv/linux/fstatat.c
>> index 59efff615f..618c254d6f 100644
>> --- a/sysdeps/unix/sysv/linux/fstatat.c
>> +++ b/sysdeps/unix/sysv/linux/fstatat.c
>> @@ -26,33 +26,19 @@
>>  int
>>  __fstatat (int fd, const char *file, struct stat *buf, int flag)
>>  {
>> -  int r;
>> -
>> -# if STAT_IS_KERNEL_STAT
>> -  /* New kABIs which uses generic pre 64-bit time Linux ABI, e.g.
>> -     csky, nios2  */
>> -  r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, buf, flag);
>> -  if (r == 0 && (buf->__st_ino_pad != 0
>> -		 || buf->__st_size_pad != 0
>> -		 || buf->__st_blocks_pad != 0))
>> -    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
>> -# else
>> -#  ifdef __NR_fstatat64
>> -  /* Old KABIs with old non-LFS support, e.g. arm, i386, hppa, m68k, mips32,
>> -     microblaze, s390, sh, powerpc, and sparc.  */
>> -  struct stat64 st64;
>> -  r = INTERNAL_SYSCALL_CALL (fstatat64, fd, file, &st64, flag);
>> +  struct __stat64_t64 st64;
>> +  int r = __fstatat64_time64 (fd, file, &st64, flag);
>>    if (r == 0)
>>      {
>>        if (! in_ino_t_range (st64.st_ino)
>>  	  || ! in_off_t_range (st64.st_size)
>> -	  || ! in_blkcnt_t_range (st64.st_blocks))
>> +	  || ! in_blkcnt_t_range (st64.st_blocks)
>> +	  || ! in_time_t_range (st64.st_atim.tv_sec)
>> +	  || ! in_time_t_range (st64.st_mtim.tv_sec)
>> +	  || ! in_time_t_range (st64.st_ctim.tv_sec))
>>  	return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
> OK
>>
>> -      /* Clear internal pad and reserved fields.  */
>> -      memset (buf, 0, sizeof (*buf));
> Do we have to clear the user provided struct as before?

I think it is not strictly required, but some architecture does
have padding and reserved fields.  I will reinstate it, the compiler
should have enough information to only zero the fields not actively
set.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/5] linux: Disable fstatat64 fallback if __ASSUME_STATX is defined
  2021-03-26  9:24   ` Stefan Liebler
@ 2021-03-26 19:38     ` Adhemerval Zanella
  0 siblings, 0 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-26 19:38 UTC (permalink / raw)
  To: libc-alpha, Stefan Liebler



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.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 5/5] linux: Add y2106 support on utimensat tests
  2021-03-26  9:24   ` Stefan Liebler
@ 2021-03-26 19:40     ` Adhemerval Zanella
  0 siblings, 0 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-26 19:40 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha



On 26/03/2021 06:24, Stefan Liebler via Libc-alpha wrote:
> On 19/03/2021 19:31, Adhemerval Zanella via Libc-alpha wrote:
>> +      //test_utime_helper (&(struct utimbuf) { tests[i].v1, tests[i].v2 });
> Do we need this comment?

No, I will remove it.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/5] linux: Use statx for MIPSn64
  2021-03-19 18:31 ` [PATCH 3/5] linux: Use statx for MIPSn64 Adhemerval Zanella
@ 2021-03-29 12:48   ` Adhemerval Zanella
  2021-04-01  0:07   ` Maciej W. Rozycki
  1 sibling, 0 replies; 18+ messages in thread
From: Adhemerval Zanella @ 2021-03-29 12:48 UTC (permalink / raw)
  To: libc-alpha

Since other patches have been reviewed, I will commit this shortly.
I ran the tst-futimens, tst-utime, and tst-utimes on a mips64-le
with both a 4.1.4 and 5.10 kernel and got the expected results.

On 19/03/2021 15:31, Adhemerval Zanella wrote:
> MIPSn64 kernel ABI for legacy stat uses unsigned 32 bit for second
> timestamp, which limits the maximum value to y2106.  This patch
> make mips64 use statx as for 32-bit architectures.
> 
> Thie __cp_stat64_t64_statx is open coded, its usage is solely on
> fstatat64 and it avoid the need to redefine the name for mips64
> (which will call __cp_stat64_statx since its does not use
> __stat64_t64 internally).
> ---
>  sysdeps/unix/sysv/linux/fstatat64.c        | 29 +++++++++++++++++++---
>  sysdeps/unix/sysv/linux/fxstat64.c         |  1 +
>  sysdeps/unix/sysv/linux/mips/kernel_stat.h |  4 +++
>  sysdeps/unix/sysv/linux/statx_cp.c         | 29 ----------------------
>  4 files changed, 30 insertions(+), 33 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
> index c3a030af58..b9b8cd994b 100644
> --- a/sysdeps/unix/sysv/linux/fstatat64.c
> +++ b/sysdeps/unix/sysv/linux/fstatat64.c
> @@ -24,9 +24,9 @@
>  #include <kernel_stat.h>
>  #include <sysdep.h>
>  #include <time.h>
> -#include <statx_cp.h>
>  #include <kstat_cp.h>
>  #include <stat_t64_cp.h>
> +#include <sys/sysmacros.h>
>  
>  #if __TIMESIZE == 64 \
>       && (__WORDSIZE == 32 \
> @@ -50,8 +50,28 @@ fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
>    struct statx 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);
> +  if (r != 0)
> +    return r;
> +
> +  *buf = (struct __stat64_t64) {
> +    .st_dev = makedev (tmp.stx_dev_major, tmp.stx_dev_minor),
> +    .st_rdev = makedev (tmp.stx_rdev_major, tmp.stx_rdev_minor),
> +    .st_ino = tmp.stx_ino,
> +    .st_mode = tmp.stx_mode,
> +    .st_nlink = tmp.stx_nlink,
> +    .st_uid = tmp.stx_uid,
> +    .st_gid = tmp.stx_gid,
> +    .st_atime = tmp.stx_atime.tv_sec,
> +    .st_atim.tv_nsec = tmp.stx_atime.tv_nsec,
> +    .st_mtime = tmp.stx_mtime.tv_sec,
> +    .st_mtim.tv_nsec = tmp.stx_mtime.tv_nsec,
> +    .st_ctime = tmp.stx_ctime.tv_sec,
> +    .st_ctim.tv_nsec = tmp.stx_ctime.tv_nsec,
> +    .st_size = tmp.stx_size,
> +    .st_blocks = tmp.stx_blocks,
> +    .st_blksize = tmp.stx_blksize,
> +  };
> +
>    return r;
>  }
>  
> @@ -117,7 +137,8 @@ fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
>  }
>  
>  #if (__WORDSIZE == 32 \
> -     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
> +     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
> +     || defined STAT_HAS_TIME32
>  # define FSTATAT_USE_STATX 1
>  #else
>  # define FSTATAT_USE_STATX 0
> diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
> index be12798273..23d9d92b00 100644
> --- a/sysdeps/unix/sysv/linux/fxstat64.c
> +++ b/sysdeps/unix/sysv/linux/fxstat64.c
> @@ -25,6 +25,7 @@
>  #include <xstatconv.h>
>  #include <statx_cp.h>
>  #include <shlib-compat.h>
> +#include <sys/sysmacros.h>
>  
>  #if LIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_33)
>  

This is not required.

> diff --git a/sysdeps/unix/sysv/linux/mips/kernel_stat.h b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
> index e4b0f211ca..19524f7ea4 100644
> --- a/sysdeps/unix/sysv/linux/mips/kernel_stat.h
> +++ b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
> @@ -67,5 +67,9 @@ struct kernel_stat
>  #else
>  # define STATFS_IS_STATFS64 0
>  #endif
> +/* MIPS64 has unsigned 32 bit timestamps fields, so use statx as well.  */
> +#if _MIPS_SIM == _ABI64
> +# define STAT_HAS_TIME32
> +#endif
>  
>  #endif
> diff --git a/sysdeps/unix/sysv/linux/statx_cp.c b/sysdeps/unix/sysv/linux/statx_cp.c
> index 53068704c6..73405a9612 100644
> --- a/sysdeps/unix/sysv/linux/statx_cp.c
> +++ b/sysdeps/unix/sysv/linux/statx_cp.c
> @@ -48,32 +48,3 @@ __cp_stat64_statx (struct stat64 *to, struct statx *from)
>  }
>  #endif
>  
> -#if (__WORDSIZE == 32 \
> -     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
> -void
> -__cp_stat64_t64_statx (struct __stat64_t64 *to, const struct statx *from)
> -{
> -  /* Clear both pad and reserved fields.  */
> -  memset (to, 0, sizeof (*to));
> -
> -  to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major << 8)
> -		| ((from->stx_dev_minor & ~0xff) << 12));
> -  to->st_ino = from->stx_ino;
> -  to->st_mode = from->stx_mode;
> -  to->st_nlink = from->stx_nlink;
> -  to->st_uid = from->stx_uid;
> -  to->st_gid = from->stx_gid;
> -  to->st_rdev = ((from->stx_rdev_minor & 0xff) | (from->stx_rdev_major << 8)
> -		 | ((from->stx_rdev_minor & ~0xff) << 12));
> -  to->st_size = from->stx_size;
> -  to->st_blksize = from->stx_blksize;
> -  to->st_blocks = from->stx_blocks;
> -
> -  to->st_atime = from->stx_atime.tv_sec;
> -  to->st_atim.tv_nsec = from->stx_atime.tv_nsec;
> -  to->st_mtime = from->stx_mtime.tv_sec;
> -  to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec;
> -  to->st_ctime = from->stx_ctime.tv_sec;
> -  to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec;
> -}
> -#endif
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/5] linux: Use statx for MIPSn64
  2021-03-19 18:31 ` [PATCH 3/5] linux: Use statx for MIPSn64 Adhemerval Zanella
  2021-03-29 12:48   ` Adhemerval Zanella
@ 2021-04-01  0:07   ` Maciej W. Rozycki
  2021-04-01 12:45     ` Adhemerval Zanella
  1 sibling, 1 reply; 18+ messages in thread
From: Maciej W. Rozycki @ 2021-04-01  0:07 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Fri, 19 Mar 2021, Adhemerval Zanella via Libc-alpha wrote:

> diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
> index c3a030af58..b9b8cd994b 100644
> --- a/sysdeps/unix/sysv/linux/fstatat64.c
> +++ b/sysdeps/unix/sysv/linux/fstatat64.c
> @@ -117,7 +137,8 @@ fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
>  }
>  
>  #if (__WORDSIZE == 32 \
> -     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
> +     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
> +     || defined STAT_HAS_TIME32

 Weird indentation here (which made me wonder how the ordering between && 
and || has been resolved so that GCC does not complain before I realised 
it's simply misindented parenthesisation).  Only caught as I saw the GIT 
commit message though.

  Maciej

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/5] linux: Use statx for MIPSn64
  2021-04-01  0:07   ` Maciej W. Rozycki
@ 2021-04-01 12:45     ` Adhemerval Zanella
  2021-04-01 18:00       ` Maciej W. Rozycki
  0 siblings, 1 reply; 18+ messages in thread
From: Adhemerval Zanella @ 2021-04-01 12:45 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: libc-alpha



On 31/03/2021 21:07, Maciej W. Rozycki wrote:
> On Fri, 19 Mar 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
>> index c3a030af58..b9b8cd994b 100644
>> --- a/sysdeps/unix/sysv/linux/fstatat64.c
>> +++ b/sysdeps/unix/sysv/linux/fstatat64.c
>> @@ -117,7 +137,8 @@ fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
>>  }
>>  
>>  #if (__WORDSIZE == 32 \
>> -     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
>> +     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
>> +     || defined STAT_HAS_TIME32
> 
>  Weird indentation here (which made me wonder how the ordering between && 
> and || has been resolved so that GCC does not complain before I realised 
> it's simply misindented parenthesisation).  Only caught as I saw the GIT 
> commit message though.

The preprocessor indentation is confusing sometimes, but I think it should
adjusted only slight to follow other usages:

diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index f968e4ef05..ab25f64187 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -137,7 +137,7 @@ fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
 
 #if (__WORDSIZE == 32 \
      && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
-     || defined STAT_HAS_TIME32
+    || defined STAT_HAS_TIME32
 # define FSTATAT_USE_STATX 1
 #else

Am I missing something here?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/5] linux: Use statx for MIPSn64
  2021-04-01 12:45     ` Adhemerval Zanella
@ 2021-04-01 18:00       ` Maciej W. Rozycki
  0 siblings, 0 replies; 18+ messages in thread
From: Maciej W. Rozycki @ 2021-04-01 18:00 UTC (permalink / raw)
  To: Adhemerval Zanella; +Cc: libc-alpha

On Thu, 1 Apr 2021, Adhemerval Zanella via Libc-alpha wrote:

> >  Weird indentation here (which made me wonder how the ordering between && 
> > and || has been resolved so that GCC does not complain before I realised 
> > it's simply misindented parenthesisation).  Only caught as I saw the GIT 
> > commit message though.
> 
> The preprocessor indentation is confusing sometimes, but I think it should
> adjusted only slight to follow other usages:
> 
> diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
> index f968e4ef05..ab25f64187 100644
> --- a/sysdeps/unix/sysv/linux/fstatat64.c
> +++ b/sysdeps/unix/sysv/linux/fstatat64.c
> @@ -137,7 +137,7 @@ fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
>  
>  #if (__WORDSIZE == 32 \
>       && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
> -     || defined STAT_HAS_TIME32
> +    || defined STAT_HAS_TIME32
>  # define FSTATAT_USE_STATX 1
>  #else
> 
> Am I missing something here?

 No, that's what I meant.

 While using outer parentheses seems to be what the GNU Coding Standards 
suggest for Emacs to indent properly, but I'm no Emacs user and we have 
cases with preprocessor statements missing those, and otherwise there is 
no indentation ambiguity here, so I guess this will be OK with your 
amendment above.

  Maciej

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2021-04-01 18:00 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-19 18:31 [PATCH 0/5] More stat fixes Adhemerval Zanella
2021-03-19 18:31 ` [PATCH 1/5] linux: Implement fstatat with __fstatat64_time64 Adhemerval Zanella
2021-03-23 16:13   ` Stefan Liebler
2021-03-26  9:24   ` Stefan Liebler
2021-03-26 19:32     ` Adhemerval Zanella
2021-03-19 18:31 ` [PATCH 2/5] linux: Disable fstatat64 fallback if __ASSUME_STATX is defined Adhemerval Zanella
2021-03-26  9:24   ` Stefan Liebler
2021-03-26 19:38     ` Adhemerval Zanella
2021-03-19 18:31 ` [PATCH 3/5] linux: Use statx for MIPSn64 Adhemerval Zanella
2021-03-29 12:48   ` Adhemerval Zanella
2021-04-01  0:07   ` Maciej W. Rozycki
2021-04-01 12:45     ` Adhemerval Zanella
2021-04-01 18:00       ` Maciej W. Rozycki
2021-03-19 18:31 ` [PATCH 4/5] support: Add support_path_support_time64_value Adhemerval Zanella
2021-03-26  9:24   ` Stefan Liebler
2021-03-19 18:31 ` [PATCH 5/5] linux: Add y2106 support on utimensat tests Adhemerval Zanella
2021-03-26  9:24   ` Stefan Liebler
2021-03-26 19:40     ` Adhemerval Zanella

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).