linux: Use statx for MIPSn64
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 19 Mar 2021 12:51:29 +0000 (09:51 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 29 Mar 2021 13:22:13 +0000 (10:22 -0300)
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
sysdeps/unix/sysv/linux/mips/kernel_stat.h
sysdeps/unix/sysv/linux/statx_cp.c

index 4d936ee..31d3253 100644 (file)
@@ -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 \
@@ -49,8 +49,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;
 }
 
@@ -116,7 +136,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
index e4b0f21..19524f7 100644 (file)
@@ -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
index 5306870..73405a9 100644 (file)
@@ -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