about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--sysdeps/unix/sysv/linux/fstatat64.c29
-rw-r--r--sysdeps/unix/sysv/linux/mips/kernel_stat.h4
-rw-r--r--sysdeps/unix/sysv/linux/statx_cp.c29
3 files changed, 29 insertions, 33 deletions
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index 4d936ee0bb..31d3253044 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 \
@@ -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
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