[v5,1/1] Add statx conditionals for wordsize-32 *xstat.c

Message ID d16b1c88d9af66f145a3b3d488d02accd3cb6d6f.1544151722.git.han_mao@c-sky.com
State New, archived
Headers

Commit Message

毛晗 Dec. 10, 2018, 1:26 a.m. UTC
  Linux kernel have remove stat64 family from default syscall set, new
implementations with statx is needed when __ARCH_WANT_STAT64 is not
define. This patch add conditionals for relevant functions, using statx
system call to get information and then copy to the return buf, ref to
include/linux/fs.h from linux kernel.

	* sysdeps/unix/sysv/linux/Makefile: Add statx_cp.c.
	* sysdeps/unix/sysv/linux/fxstat64.c: Add conditionals for kernel
	without stat64 system call support.
	* sysdeps/unix/sysv/linux/fxstatat64.c: Likewise.
	* sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c: Likewise.
	* sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c: Likewise.
	* sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c: Likewise.
	* sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c: Likewise.
	* sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c: Likewise.
	* sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c: New file.
	* sysdeps/unix/sysv/linux/statx_cp.c: Likewise.
	* sysdeps/unix/sysv/linux/statx_cp.h: Likewise.
	* sysdeps/unix/sysv/linux/wordsize-64/statx_cp.c: Likewise.
---
 sysdeps/unix/sysv/linux/Makefile                   |  3 +-
 sysdeps/unix/sysv/linux/fxstat64.c                 | 12 +++++-
 sysdeps/unix/sysv/linux/fxstatat64.c               | 11 +++++
 .../unix/sysv/linux/generic/wordsize-32/fxstat.c   | 10 +++++
 .../unix/sysv/linux/generic/wordsize-32/fxstatat.c | 10 +++++
 .../unix/sysv/linux/generic/wordsize-32/lxstat.c   | 10 +++++
 .../unix/sysv/linux/generic/wordsize-32/lxstat64.c | 19 ++++++++-
 .../unix/sysv/linux/generic/wordsize-32/xstat.c    |  9 ++++
 .../unix/sysv/linux/generic/wordsize-32/xstat64.c  | 14 ++++++-
 sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c     |  3 ++
 sysdeps/unix/sysv/linux/statx_cp.c                 | 49 ++++++++++++++++++++++
 sysdeps/unix/sysv/linux/statx_cp.h                 | 23 ++++++++++
 sysdeps/unix/sysv/linux/wordsize-64/statx_cp.c     |  3 ++
 13 files changed, 171 insertions(+), 5 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c
 create mode 100644 sysdeps/unix/sysv/linux/statx_cp.c
 create mode 100644 sysdeps/unix/sysv/linux/statx_cp.h
 create mode 100644 sysdeps/unix/sysv/linux/wordsize-64/statx_cp.c
  

Comments

Joseph Myers Dec. 14, 2018, 8:58 p.m. UTC | #1
On Mon, 10 Dec 2018, Mao Han wrote:

> diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c

> +    {
> +#ifdef __NR_fstatat64
>      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
> -

As this statement is moving inside braces, it also needs to be reindented 
two more columns to the right.

> +extern void __cp_stat_statx (struct stat *to, struct statx *from)
> +  attribute_hidden;

There's no such function any more, so this declaration should be removed.

This patch is OK with those changes.  Please complete the form 
https://sourceware.org/cgi-bin/pdw/ps_form.cgi for write access, listing 
me as sponsor.  Please also create an account on the glibc wiki if you 
don't already have one, and post the username so that you can be given 
write access to that.
  
毛晗 Dec. 15, 2018, 12:12 p.m. UTC | #2
On Fri, Dec 14, 2018 at 08:58:29PM +0000, Joseph Myers wrote:
> On Mon, 10 Dec 2018, Mao Han wrote:
> 
> > diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
> > +#ifdef __NR_fstatat64
> >      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
> > -
> As this statement is moving inside braces, it also needs to be reindented 
> two more columns to the right.

OK, I'll fix the style.

> > +extern void __cp_stat_statx (struct stat *to, struct statx *from)
> > +  attribute_hidden;
> 
> There's no such function any more, so this declaration should be removed.

OK, I'll remove it.

> This patch is OK with those changes.  Please complete the form 
> https://sourceware.org/cgi-bin/pdw/ps_form.cgi for write access, listing 
> me as sponsor.  Please also create an account on the glibc wiki if you 
> don't already have one, and post the username so that you can be given 
> write access to that.

I'v completed the form to request a sourceware account. The glibc wiki
account is also created and the username is: HanMao

Thanks,
Mao Han
  
毛晗 Dec. 17, 2018, 6:37 a.m. UTC | #3
On Sat, Dec 15, 2018 at 08:12:03PM +0800, Mao Han wrote:
> On Fri, Dec 14, 2018 at 08:58:29PM +0000, Joseph Myers wrote:
> > On Mon, 10 Dec 2018, Mao Han wrote:
> > 
> > > diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
> > > +#ifdef __NR_fstatat64
> > >      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
> > > -
> > As this statement is moving inside braces, it also needs to be reindented 
> > two more columns to the right.
> 
> OK, I'll fix the style.
> 
> > > +extern void __cp_stat_statx (struct stat *to, struct statx *from)
> > > +  attribute_hidden;
> > 
> > There's no such function any more, so this declaration should be removed.
> 
> OK, I'll remove it.

Committed. with fixes above.
Did a make check for mips, nios2 and x86.

> > This patch is OK with those changes.  Please complete the form 
> > https://sourceware.org/cgi-bin/pdw/ps_form.cgi for write access, listing 
> > me as sponsor.  Please also create an account on the glibc wiki if you 
> > don't already have one, and post the username so that you can be given 
> > write access to that.
> 
> I'v completed the form to request a sourceware account. The glibc wiki
> account is also created and the username is: HanMao

Some one can help add me to the wiki editor group? My account was purged
yesterday. I've just recreated it.

Thanks,
Mao Han
  
Joseph Myers Dec. 17, 2018, 1:41 p.m. UTC | #4
On Sat, 15 Dec 2018, Mao Han wrote:

> I'v completed the form to request a sourceware account. The glibc wiki
> account is also created and the username is: HanMao

Thanks, I've added you to EditorGroup.

There is one thing to watch on this patch for future reference (no action 
required at present).  statx always uses 64-bit timestamps, so for 32-bit 
systems __cp_stat64_statx will quietly set the timestamps to just the low 
32 bits of the timestamps provided by the kernel.  Now, this currently 
matches what the Linux kernel does for the stat syscalls on 32-bit systems 
that have them, when using a filesystem that supports timestamps outside 
the 32-bit time_t range.  But if the Linux kernel changes its handling of 
such out-of-range timestamps in future (whether producing EOVERFLOW 
errors, saturating or anything else - there has been past discussion, see 
<https://bugzilla.redhat.com/show_bug.cgi?id=1419736> and linux-fsdevel 
link therein, but I'm not sure there was any conclusion), the stat 
emulation using statx should change to match.
  
毛晗 Dec. 20, 2018, 3:09 a.m. UTC | #5
On Mon, Dec 17, 2018 at 01:41:49PM +0000, Joseph Myers wrote:
> There is one thing to watch on this patch for future reference (no action 
> required at present).  statx always uses 64-bit timestamps, so for 32-bit 
> systems __cp_stat64_statx will quietly set the timestamps to just the low 
> 32 bits of the timestamps provided by the kernel.  Now, this currently 
> matches what the Linux kernel does for the stat syscalls on 32-bit systems 
> that have them, when using a filesystem that supports timestamps outside 
> the 32-bit time_t range.  But if the Linux kernel changes its handling of 
> such out-of-range timestamps in future (whether producing EOVERFLOW 
> errors, saturating or anything else - there has been past discussion, see 
> <https://bugzilla.redhat.com/show_bug.cgi?id=1419736> and linux-fsdevel 
> link therein, but I'm not sure there was any conclusion), the stat 
> emulation using statx should change to match.

Ok, I'll pay attention to the linux timestamps handling changes.

Thanks,
Mao Han
  

Patch

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 362cf3b..532e15b 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -180,7 +180,8 @@  sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
 		   close_nocancel fcntl_nocancel nanosleep_nocancel \
 		   open_nocancel open64_nocancel \
 		   openat_nocancel openat64_nocancel \
-		   pause_nocancel read_nocancel waitpid_nocancel write_nocancel
+		   pause_nocancel read_nocancel waitpid_nocancel \
+		   write_nocancel statx_cp
 
 sysdep_headers += bits/fcntl-linux.h
 
diff --git a/sysdeps/unix/sysv/linux/fxstat64.c b/sysdeps/unix/sysv/linux/fxstat64.c
index 0d05389..b0c5271 100644
--- a/sysdeps/unix/sysv/linux/fxstat64.c
+++ b/sysdeps/unix/sysv/linux/fxstat64.c
@@ -1,4 +1,4 @@ 
-/* fxstat64 using Linux fstat64 system call.
+/* fxstat64 using Linux fstat64/statx system call.
    Copyright (C) 1997-2018 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -18,6 +18,7 @@ 
 
 #include <errno.h>
 #include <stddef.h>
+#include <fcntl.h>
 #include <sys/stat.h>
 #include <kernel_stat.h>
 
@@ -25,6 +26,7 @@ 
 #include <sys/syscall.h>
 
 #include <kernel-features.h>
+#include <statx_cp.h>
 
 /* Get information about the file FD in BUF.  */
 
@@ -32,7 +34,15 @@  int
 ___fxstat64 (int vers, int fd, struct stat64 *buf)
 {
   int result;
+#ifdef __NR_fstat64
   result = INLINE_SYSCALL (fstat64, 2, fd, buf);
+#else
+  struct statx tmp;
+  result = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS,
+                           &tmp);
+  if (result == 0)
+    __cp_stat64_statx (buf, &tmp);
+#endif
 #if defined _HAVE_STAT64___ST_INO && !__ASSUME_ST_INO_64_BIT
   if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino)
     buf->st_ino = buf->__st_ino;
diff --git a/sysdeps/unix/sysv/linux/fxstatat64.c b/sysdeps/unix/sysv/linux/fxstatat64.c
index baa9a60..767d55c 100644
--- a/sysdeps/unix/sysv/linux/fxstatat64.c
+++ b/sysdeps/unix/sysv/linux/fxstatat64.c
@@ -26,6 +26,8 @@ 
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include <statx_cp.h>
+
 /* Get information about the file NAME in BUF.  */
 
 int
@@ -37,7 +39,16 @@  __fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
   int result;
   INTERNAL_SYSCALL_DECL (err);
 
+#ifdef __NR_fstatat64
   result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
+#else
+  struct statx tmp;
+
+  result = INTERNAL_SYSCALL (statx, err, 5, fd, file, AT_NO_AUTOMOUNT | flag,
+                             STATX_BASIC_STATS, &tmp);
+  if (result == 0)
+    __cp_stat64_statx (st, &tmp);
+#endif
   if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
     return 0;
   else
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
index b5c766d..9e9df5d 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c
@@ -18,6 +18,7 @@ 
 
 #include <errno.h>
 #include <stddef.h>
+#include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <kernel_stat.h>
@@ -27,6 +28,7 @@ 
 
 #if !XSTAT_IS_XSTAT64
 #include "overflow.h"
+#include <statx_cp.h>
 
 /* Get information about the file FD in BUF.  */
 int
@@ -34,7 +36,15 @@  __fxstat (int vers, int fd, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
+# ifdef __NR_fstat64
       int rc = INLINE_SYSCALL (fstat64, 2, fd, buf);
+# else
+      struct statx tmp;
+      int rc = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH,
+                               STATX_BASIC_STATS, &tmp);
+      if (rc == 0)
+        __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# endif
       return rc ?: stat_overflow (buf);
     }
 
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
index 0bda8f7..62e9ce3 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c
@@ -28,6 +28,7 @@ 
 
 #if !XSTAT_IS_XSTAT64
 #include "overflow.h"
+#include <statx_cp.h>
 
 /* Get information about the file NAME in BUF.  */
 int
@@ -35,7 +36,16 @@  __fxstatat (int vers, int fd, const char *file, struct stat *buf, int flag)
 {
   if (vers == _STAT_VER_KERNEL)
     {
+# ifdef __NR_fstatat64
       int rc = INLINE_SYSCALL (fstatat64, 4, fd, file, buf, flag);
+# else
+      struct statx tmp;
+      int rc = INLINE_SYSCALL (statx, 5, fd, file,
+                               AT_NO_AUTOMOUNT | flag,
+                               STATX_BASIC_STATS, &tmp);
+      if (rc == 0)
+        __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# endif
       return rc ?: stat_overflow (buf);
     }
 
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
index c278a4d..e16c441 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c
@@ -27,6 +27,7 @@ 
 
 #if !XSTAT_IS_XSTAT64
 #include "overflow.h"
+#include <statx_cp.h>
 
 /* Get information about the file NAME in BUF.  */
 int
@@ -34,8 +35,17 @@  __lxstat (int vers, const char *name, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
+#ifdef __NR_fstatat64
       int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
                                AT_SYMLINK_NOFOLLOW);
+#else
+      struct statx tmp;
+      int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name,
+                               AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
+                               STATX_BASIC_STATS, &tmp);
+      if (rc == 0)
+        __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+#endif
       return rc ?: stat_overflow (buf);
     }
   errno = EINVAL;
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
index 761dd16..86b7a98 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat64.c
@@ -32,13 +32,28 @@ 
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include <statx_cp.h>
+
 /* Get information about the file NAME in BUF.  */
 int
 __lxstat64 (int vers, const char *name, struct stat64 *buf)
 {
   if (vers == _STAT_VER_KERNEL)
-    return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
-                           AT_SYMLINK_NOFOLLOW);
+    {
+#ifdef __NR_fstatat64
+      return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
+                             AT_SYMLINK_NOFOLLOW);
+#else
+      struct statx tmp;
+      int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name,
+                               AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW,
+                               STATX_BASIC_STATS, &tmp);
+      if (rc == 0)
+        __cp_stat64_statx (buf, &tmp);
+      return rc;
+#endif
+    }
+
   errno = EINVAL;
   return -1;
 }
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
index 1fd57ff..bd3f3a4 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c
@@ -27,6 +27,7 @@ 
 
 #if !XSTAT_IS_XSTAT64
 #include "overflow.h"
+#include <statx_cp.h>
 
 /* Get information about the file NAME in BUF.  */
 int
@@ -34,7 +35,15 @@  __xstat (int vers, const char *name, struct stat *buf)
 {
   if (vers == _STAT_VER_KERNEL)
     {
+# ifdef __NR_fstatat64
       int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
+# else
+      struct statx tmp;
+      int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT,
+                               STATX_BASIC_STATS, &tmp);
+      if (rc == 0)
+        __cp_stat64_statx ((struct stat64 *)buf, &tmp);
+# endif
       return rc ?: stat_overflow (buf);
     }
 
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
index ae70495..8b38926 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c
@@ -32,13 +32,25 @@ 
 #include <sysdep.h>
 #include <sys/syscall.h>
 
+#include <statx_cp.h>
+
 /* Get information about the file NAME in BUF.  */
 int
 __xstat64 (int vers, const char *name, struct stat64 *buf)
 {
   if (vers == _STAT_VER_KERNEL)
+    {
+#ifdef __NR_fstatat64
     return INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
-
+#else
+      struct statx tmp;
+      int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, name, AT_NO_AUTOMOUNT,
+                               STATX_BASIC_STATS, &tmp);
+      if (rc == 0)
+        __cp_stat64_statx (buf, &tmp);
+      return rc;
+#endif
+    }
   errno = EINVAL;
   return -1;
 }
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c b/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c
new file mode 100644
index 0000000..260cda9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c
@@ -0,0 +1,3 @@ 
+/* Override the generic statx_cp.c which is only needed for new 32-bit arch
+   without stat64 family support.
+ */
diff --git a/sysdeps/unix/sysv/linux/statx_cp.c b/sysdeps/unix/sysv/linux/statx_cp.c
new file mode 100644
index 0000000..04a13fa
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/statx_cp.c
@@ -0,0 +1,49 @@ 
+/* Struct statx to stat/stat64 conversion for Linux.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <statx_cp.h>
+
+#if !defined(__NR_fstat64) || !defined(__NR_fstatat64)
+void
+__cp_stat64_statx (struct stat64 *to, struct statx *from)
+{
+  memset (to, 0, sizeof (struct stat64));
+  to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major << 8)
+		| ((from->stx_dev_minor & ~0xff) << 12));
+  to->st_rdev = ((from->stx_rdev_minor & 0xff) | (from->stx_rdev_major << 8)
+		 | ((from->stx_rdev_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_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;
+  to->st_size = from->stx_size;
+  to->st_blocks = from->stx_blocks;
+  to->st_blksize = from->stx_blksize;
+}
+#endif
diff --git a/sysdeps/unix/sysv/linux/statx_cp.h b/sysdeps/unix/sysv/linux/statx_cp.h
new file mode 100644
index 0000000..7e411a7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/statx_cp.h
@@ -0,0 +1,23 @@ 
+/* Struct statx to stat/stat64 conversion for Linux.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+extern void __cp_stat_statx (struct stat *to, struct statx *from)
+  attribute_hidden;
+
+extern void __cp_stat64_statx (struct stat64 *to, struct statx *from)
+  attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/statx_cp.c b/sysdeps/unix/sysv/linux/wordsize-64/statx_cp.c
new file mode 100644
index 0000000..260cda9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/wordsize-64/statx_cp.c
@@ -0,0 +1,3 @@ 
+/* Override the generic statx_cp.c which is only needed for new 32-bit arch
+   without stat64 family support.
+ */