[22/27,AARCH64] ILP32: support stat syscall family

Message ID 1466485631-3532-24-git-send-email-ynorov@caviumnetworks.com
State New, archived
Headers

Commit Message

Yury Norov June 21, 2016, 5:07 a.m. UTC
  From: Yury Norov <yury.norov@gmail.com>

stat and statfs structures has their layouts identical to lp64
after changing off_t, ino_t etc sizes to 64-bit. It means we can
pass it to kernel same way as lp64 does.

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 sysdeps/unix/sysv/linux/aarch64/bits/stat.h        | 195 +++++++++++++++++++++
 sysdeps/unix/sysv/linux/aarch64/bits/statfs.h      |  72 ++++++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c    |  29 +++
 sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c  |  72 ++++++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c     |  51 ++++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c   |  54 ++++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c   |  48 +++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c |  52 ++++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/lxstat.c     |  47 +++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c     |  30 ++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c   |  29 +++
 sysdeps/unix/sysv/linux/aarch64/ilp32/xstat.c      |  47 +++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/xstat64.c    |  47 +++++
 13 files changed, 773 insertions(+)
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/bits/stat.h
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/bits/statfs.h
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/lxstat.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/xstat.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/xstat64.c
  

Comments

Andreas Schwab June 21, 2016, 8:38 a.m. UTC | #1
Yury Norov <ynorov@caviumnetworks.com> writes:

> diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/statfs.h b/sysdeps/unix/sysv/linux/aarch64/bits/statfs.h
> new file mode 100644
> index 0000000..81a8626
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/aarch64/bits/statfs.h
> @@ -0,0 +1,72 @@
> +/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
> +
> +   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/>.  */
> +
> +#ifndef _SYS_STATFS_H
> +# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead."
> +#endif
> +
> +#include <endian.h>
> +#include <bits/types.h>
> +#include <bits/wordsize.h>
> +
> +/* 64-bit libc uses the kernel's 'struct statfs', accessed via the
> +   statfs() syscall; 32-bit libc uses the kernel's 'struct statfs64'
> +   and accesses it via the statfs64() syscall.  All the various
> +   APIs offered by libc use the kernel shape for their struct statfs
> +   structure; the only difference is that 32-bit programs not
> +   using __USE_FILE_OFFSET64 only see the low 32 bits of some
> +   of the fields (the __fsblkcnt_t and __fsfilcnt_t fields).  */

Is that comment accurate?

> diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c
> new file mode 100644
> index 0000000..d7b90bb
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c
> @@ -0,0 +1,72 @@
> +/* Return information about the filesystem on which FD resides.
> +   Copyright (C) 1996-2016 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 <errno.h>
> +#include <string.h>
> +#include <sys/statfs.h>
> +#include <stddef.h>
> +#include <sysdep.h>
> +#include <kernel-features.h>
> +
> +/* Defined in statfs64.c.  */
> +extern int __no_statfs64 attribute_hidden;

No need for probing, statfs64 is always available.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c
> new file mode 100644
> index 0000000..f651921
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c
> @@ -0,0 +1,54 @@
> +/* fxstat64 using Linux fstat64 system call.
> +   Copyright (C) 1997-2016 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 <errno.h>
> +#include <stddef.h>
> +#include <sys/stat.h>
> +#include <kernel_stat.h>
> +
> +#include <sysdep.h>
> +#include <sys/syscall.h>
> +
> +#include <kernel-features.h>
> +
> +/* Get information about the file FD in BUF.  */
> +
> +int
> +___fxstat64 (int vers, int fd, struct stat64 *buf)
> +{
> +  int result;
> +  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
> +  if (!result) {
> +	  conv_timespec(&buf->st_atim, &buf->__st_atim);
> +	  conv_timespec(&buf->st_mtim, &buf->__st_mtim);
> +	  conv_timespec(&buf->st_ctim, &buf->__st_ctim);
> +  }
> +  return result;
> +}
> +
> +#include <shlib-compat.h>
> +
> +#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)

No need for compat symbols in a new port.

Andreas.
  
Joseph Myers June 21, 2016, 10:46 a.m. UTC | #2
On Tue, 21 Jun 2016, Yury Norov wrote:

> From: Yury Norov <yury.norov@gmail.com>
> 
> stat and statfs structures has their layouts identical to lp64
> after changing off_t, ino_t etc sizes to 64-bit. It means we can
> pass it to kernel same way as lp64 does.

This should be implemented in a way suitable for future architectures to 
use without needing lots of new sysdeps files in every architecture.
  
Andreas Schwab June 27, 2016, 7:51 a.m. UTC | #3
Yury Norov <ynorov@caviumnetworks.com> writes:

> From: Yury Norov <yury.norov@gmail.com>
>
> stat and statfs structures has their layouts identical to lp64
> after changing off_t, ino_t etc sizes to 64-bit. It means we can
> pass it to kernel same way as lp64 does.
>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> ---
>  sysdeps/unix/sysv/linux/aarch64/bits/stat.h        | 195 +++++++++++++++++++++
>  sysdeps/unix/sysv/linux/aarch64/bits/statfs.h      |  72 ++++++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c    |  29 +++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c  |  72 ++++++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c     |  51 ++++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c   |  54 ++++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c   |  48 +++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c |  52 ++++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/lxstat.c     |  47 +++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c     |  30 ++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c   |  29 +++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/xstat.c      |  47 +++++
>  sysdeps/unix/sysv/linux/aarch64/ilp32/xstat64.c    |  47 +++++
>  13 files changed, 773 insertions(+)
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/bits/stat.h
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/bits/statfs.h
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/lxstat.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/xstat.c
>  create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/xstat64.c

This is missing lxstat64.  Without that the perl testsuite fails.

Andreas.
  

Patch

diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/stat.h b/sysdeps/unix/sysv/linux/aarch64/bits/stat.h
new file mode 100644
index 0000000..eec6789
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/stat.h
@@ -0,0 +1,195 @@ 
+/* Copyright (C) 1992-2015 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/>.  */
+
+#if !defined _SYS_STAT_H && !defined _FCNTL_H
+# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#ifndef _BITS_STAT_H
+#define _BITS_STAT_H	1
+
+/* Versions of the `struct stat' data structure.  */
+#define _STAT_VER_KERNEL	0
+#define _STAT_VER_LINUX		0
+#define _STAT_VER		_STAT_VER_KERNEL
+
+/* Versions of the `xmknod' interface.  */
+#define _MKNOD_VER_LINUX	0
+
+#ifdef __ILP32__
+#include <endian.h>
+struct __kernel_timespec
+  {
+    unsigned long long tv_sec;		/* Seconds.  */
+    long long tv_nsec;			/* Nanoseconds.  */
+  };
+#define conv_timespec(u, k) do {	\
+	(u)->tv_sec = (k)->tv_sec;	\
+	(u)->tv_nsec = (k)->tv_nsec;	\
+} while (0)
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define __type3264(type, name)	\
+	type (name); type name##_pad
+#else
+#define __type3264(type, name)	\
+	type name##_pad; type name
+#endif
+
+#else
+#define __kernel_timespec timespec
+#define conv_timespec(u, k)
+#define __type3264(type, name) type name
+#endif /* __ILP32__ */
+
+struct stat
+  {
+    __dev_t st_dev;			/* Device.  */
+    __ino_t st_ino;			/* File serial number.	*/
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
+    __dev_t __pad1;
+    __off_t st_size;			/* Size of file, in bytes.  */
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+    int __pad2;
+
+    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
+#ifdef __USE_XOPEN2K8
+    /* Nanosecond resolution timestamps are stored in a format
+       equivalent to 'struct timespec'.  This is the type used
+       whenever possible but the Unix namespace rules do not allow the
+       identifier 'timespec' to appear in the <sys/stat.h> header.
+       Therefore we have to handle the use of this header in strictly
+       standard-compliant sources special.  */
+    union {
+	    struct timespec st_atim;		/* Time of last access.  */
+	    struct __kernel_timespec __st_atim;
+    };
+    union {
+	    struct timespec st_mtim;		/* Time of last modification.  */
+	    struct __kernel_timespec __st_mtim;
+    };
+    union {
+	    struct timespec st_ctim;		/* Time of last status change.  */
+	    struct __kernel_timespec __st_ctim;
+    };
+# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+    __type3264(__time_t, st_atime);			/* Time of last access.  */
+    __type3264(unsigned long int, st_atimensec);	/* Nsecs of last access.  */
+    __type3264(__time_t, st_mtime);			/* Time of last modification.  */
+    __type3264(unsigned long int, st_mtimensec);	/* Nsecs of last modification.  */
+    __type3264(__time_t, st_ctime);			/* Time of last status change.  */
+    __type3264(unsigned long int, st_ctimensec);	/* Nsecs of last status change.  */
+#endif
+    int __glibc_reserved[2];
+  };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+  {
+    __dev_t st_dev;			/* Device.  */
+    __ino_t st_ino;			/* File serial number.	*/
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __dev_t st_rdev;			/* Device number, if device.  */
+    __dev_t __pad1;
+    __off_t st_size;			/* Size of file, in bytes.  */
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+    int __pad2;
+
+    __blkcnt_t st_blocks;		/* Number 512-byte blocks allocated. */
+#ifdef __USE_XOPEN2K8
+    /* Nanosecond resolution timestamps are stored in a format
+       equivalent to 'struct timespec'.  This is the type used
+       whenever possible but the Unix namespace rules do not allow the
+       identifier 'timespec' to appear in the <sys/stat.h> header.
+       Therefore we have to handle the use of this header in strictly
+       standard-compliant sources special.  */
+    union {
+	    struct timespec st_atim;		/* Time of last access.  */
+	    struct __kernel_timespec __st_atim;
+    };
+    union {
+	    struct timespec st_mtim;		/* Time of last modification.  */
+	    struct __kernel_timespec __st_mtim;
+    };
+    union {
+	    struct timespec st_ctim;		/* Time of last status.  */
+	    struct __kernel_timespec __st_ctim;
+    };
+# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+    __type3264(__time_t, st_atime);			/* Time of last access.  */
+    __type3264(unsigned long int, st_atimensec);	/* Nsecs of last access.  */
+    __type3264(__time_t, st_mtime);			/* Time of last modification.  */
+    __type3264(unsigned long int, st_mtimensec);	/* Nsecs of last modification.  */
+    __type3264(__time_t, st_ctime);			/* Time of last status change.  */
+    __type3264(unsigned long int, st_ctimensec);	/* Nsecs of last status change.  */
+#endif
+    int __glibc_reserved[2];
+  };
+#endif
+
+/* Tell code we have these members.  */
+#define	_STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported.  */
+#define _STATBUF_ST_NSEC
+
+/* Encoding of the file mode.  */
+
+#define	__S_IFMT	0170000	/* These bits determine file type.  */
+
+/* File types.  */
+#define	__S_IFDIR	0040000	/* Directory.  */
+#define	__S_IFCHR	0020000	/* Character device.  */
+#define	__S_IFBLK	0060000	/* Block device.  */
+#define	__S_IFREG	0100000	/* Regular file.  */
+#define	__S_IFIFO	0010000	/* FIFO.  */
+#define	__S_IFLNK	0120000	/* Symbolic link.  */
+#define	__S_IFSOCK	0140000	/* Socket.  */
+
+/* POSIX.1b objects.  Note that these macros always evaluate to zero.  But
+   they do it by enforcing the correct use of the macros.  */
+#define __S_TYPEISMQ(buf)  ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
+#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
+
+/* Protection bits.  */
+
+#define	__S_ISUID	04000	/* Set user ID on execution.  */
+#define	__S_ISGID	02000	/* Set group ID on execution.  */
+#define	__S_ISVTX	01000	/* Save swapped text after use (sticky).  */
+#define	__S_IREAD	0400	/* Read by owner.  */
+#define	__S_IWRITE	0200	/* Write by owner.  */
+#define	__S_IEXEC	0100	/* Execute by owner.  */
+
+#ifdef __USE_ATFILE
+# define UTIME_NOW	((1l << 30) - 1l)
+# define UTIME_OMIT	((1l << 30) - 2l)
+#endif
+
+#endif	/* bits/stat.h */
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/statfs.h b/sysdeps/unix/sysv/linux/aarch64/bits/statfs.h
new file mode 100644
index 0000000..81a8626
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/statfs.h
@@ -0,0 +1,72 @@ 
+/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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/>.  */
+
+#ifndef _SYS_STATFS_H
+# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead."
+#endif
+
+#include <endian.h>
+#include <bits/types.h>
+#include <bits/wordsize.h>
+
+/* 64-bit libc uses the kernel's 'struct statfs', accessed via the
+   statfs() syscall; 32-bit libc uses the kernel's 'struct statfs64'
+   and accesses it via the statfs64() syscall.  All the various
+   APIs offered by libc use the kernel shape for their struct statfs
+   structure; the only difference is that 32-bit programs not
+   using __USE_FILE_OFFSET64 only see the low 32 bits of some
+   of the fields (the __fsblkcnt_t and __fsfilcnt_t fields).  */
+
+struct statfs
+  {
+    unsigned long long f_type;
+    unsigned long long f_bsize;
+    __fsblkcnt_t f_blocks;
+    __fsblkcnt_t f_bfree;
+    __fsblkcnt_t f_bavail;
+    __fsfilcnt_t f_files;
+    __fsfilcnt_t f_ffree;
+    __fsid_t f_fsid;
+    unsigned long long f_namelen;
+    unsigned long long f_frsize;
+    unsigned long long f_flags;
+    unsigned long long f_spare[4];
+  };
+
+#ifdef __USE_LARGEFILE64
+struct statfs64
+  {
+    unsigned long long f_type;
+    unsigned long long f_bsize;
+    __fsblkcnt_t f_blocks;
+    __fsblkcnt_t f_bfree;
+    __fsblkcnt_t f_bavail;
+    __fsfilcnt_t f_files;
+    __fsfilcnt_t f_ffree;
+    __fsid_t f_fsid;
+    unsigned long long f_namelen;
+    unsigned long long f_frsize;
+    unsigned long long f_flags;
+    unsigned long long f_spare[4];
+  };
+#endif
+
+/* Tell code we have these members.  */
+#define _STATFS_F_NAMELEN
+#define _STATFS_F_FRSIZE
+#define _STATFS_F_FLAGS
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c
new file mode 100644
index 0000000..8e900fd
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c
@@ -0,0 +1,29 @@ 
+/* Copyright (C) 2011-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <errno.h>
+#include <sys/statfs.h>
+#include <stddef.h>
+
+/* Return information about the filesystem on which FD resides.  */
+int
+__fstatfs (int fd, struct statfs *buf)
+{
+  return INLINE_SYSCALL (fstatfs64, 2, fd, buf);
+}
+weak_alias (__fstatfs, fstatfs)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c
new file mode 100644
index 0000000..d7b90bb
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c
@@ -0,0 +1,72 @@ 
+/* Return information about the filesystem on which FD resides.
+   Copyright (C) 1996-2016 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 <errno.h>
+#include <string.h>
+#include <sys/statfs.h>
+#include <stddef.h>
+#include <sysdep.h>
+#include <kernel-features.h>
+
+/* Defined in statfs64.c.  */
+extern int __no_statfs64 attribute_hidden;
+
+/* Return information about the filesystem on which FD resides.  */
+int
+__fstatfs64 (int fd, struct statfs64 *buf)
+{
+#ifdef __NR_fstatfs64
+# if __ASSUME_STATFS64 == 0
+  if (! __no_statfs64)
+# endif
+    {
+      int result = INLINE_SYSCALL (fstatfs64, 2, fd, buf);
+
+# if __ASSUME_STATFS64 == 0
+      if (result == 0 || errno != ENOSYS)
+# endif
+	return result;
+
+# if __ASSUME_STATFS64 == 0
+      __no_statfs64 = 1;
+# endif
+    }
+#endif
+
+#if __ASSUME_STATFS64 == 0
+  struct statfs buf32;
+
+  if (__fstatfs (fd, &buf32) < 0)
+    return -1;
+
+  buf->f_type = buf32.f_type;
+  buf->f_bsize = buf32.f_bsize;
+  buf->f_blocks = buf32.f_blocks;
+  buf->f_bfree = buf32.f_bfree;
+  buf->f_bavail = buf32.f_bavail;
+  buf->f_files = buf32.f_files;
+  buf->f_ffree = buf32.f_ffree;
+  buf->f_fsid = buf32.f_fsid;
+  buf->f_namelen = buf32.f_namelen;
+  buf->f_frsize = buf32.f_frsize;
+  memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare));
+
+  return 0;
+#endif
+}
+weak_alias (__fstatfs64, fstatfs64)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
new file mode 100644
index 0000000..83df0e4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
@@ -0,0 +1,51 @@ 
+//#include <sysdeps/unix/sysv/linux/generic/wordsize-32/fxstat.c>
+/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <errno.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Get information about the file FD in BUF.  */
+int
+__fxstat (int vers, int fd, struct stat *buf)
+{
+  if (vers == _STAT_VER_KERNEL)
+    {
+      int rc = INLINE_SYSCALL (fstat64, 2, fd, buf);
+      if (!rc) {
+	      conv_timespec(&buf->st_atim, &buf->__st_atim);
+	      conv_timespec(&buf->st_mtim, &buf->__st_mtim);
+	      conv_timespec(&buf->st_ctim, &buf->__st_ctim);
+      }
+
+      return rc;
+
+    }
+
+  errno = EINVAL;
+  return -1;
+}
+
+hidden_def (__fxstat)
+weak_alias (__fxstat, _fxstat);
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c
new file mode 100644
index 0000000..f651921
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c
@@ -0,0 +1,54 @@ 
+/* fxstat64 using Linux fstat64 system call.
+   Copyright (C) 1997-2016 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 <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+#include <kernel-features.h>
+
+/* Get information about the file FD in BUF.  */
+
+int
+___fxstat64 (int vers, int fd, struct stat64 *buf)
+{
+  int result;
+  result = INLINE_SYSCALL (fstat64, 2, fd, buf);
+  if (!result) {
+	  conv_timespec(&buf->st_atim, &buf->__st_atim);
+	  conv_timespec(&buf->st_mtim, &buf->__st_mtim);
+	  conv_timespec(&buf->st_ctim, &buf->__st_ctim);
+  }
+  return result;
+}
+
+#include <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+versioned_symbol (libc, ___fxstat64, __fxstat64, GLIBC_2_2);
+strong_alias (___fxstat64, __old__fxstat64)
+compat_symbol (libc, __old__fxstat64, __fxstat64, GLIBC_2_1);
+hidden_ver (___fxstat64, __fxstat64)
+#else
+strong_alias (___fxstat64, __fxstat64)
+hidden_def (__fxstat64)
+#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c
new file mode 100644
index 0000000..fb03a7d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c
@@ -0,0 +1,48 @@ 
+//#include <sysdeps/unix/sysv/linux/generic/wordsize-32/fxstatat.c>
+/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Get information about the file NAME in BUF.  */
+int
+__fxstatat (int vers, int fd, const char *file, struct stat *buf, int flag)
+{
+  if (vers == _STAT_VER_KERNEL)
+    {
+      int rc = INLINE_SYSCALL (fstatat64, 4, fd, file, buf, flag);
+      if (!rc) {
+	      conv_timespec(&buf->st_atim, &buf->__st_atim);
+	      conv_timespec(&buf->st_mtim, &buf->__st_mtim);
+	      conv_timespec(&buf->st_ctim, &buf->__st_ctim);
+      }
+      return rc;
+    }
+
+  errno = EINVAL;
+  return -1;
+}
+libc_hidden_def (__fxstatat)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c
new file mode 100644
index 0000000..9d36ff4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c
@@ -0,0 +1,52 @@ 
+//#include <sysdeps/unix/sysv/linux/fxstatat64.c>
+/* Copyright (C) 2005-2016 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 <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Get information about the file NAME in BUF.  */
+
+int
+__fxstatat64 (int vers, int fd, const char *file, struct stat64 *st, int flag)
+{
+  if (__glibc_unlikely (vers != _STAT_VER_LINUX))
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  int result;
+  INTERNAL_SYSCALL_DECL (err);
+
+  result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
+  if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)) {
+      conv_timespec(&st->st_atim, &st->__st_atim);
+      conv_timespec(&st->st_mtim, &st->__st_mtim);
+      conv_timespec(&st->st_ctim, &st->__st_ctim);
+      return 0;
+  }
+  else
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result,
+								      err));
+}
+libc_hidden_def (__fxstatat64)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/lxstat.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/lxstat.c
new file mode 100644
index 0000000..e8de70e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/lxstat.c
@@ -0,0 +1,47 @@ 
+//#include <sysdeps/unix/sysv/linux/generic/wordsize-32/lxstat.c>
+/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <errno.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Get information about the file NAME in BUF.  */
+int
+__lxstat (int vers, const char *name, struct stat *buf)
+{
+  if (vers == _STAT_VER_KERNEL)
+    {
+      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf,
+                               AT_SYMLINK_NOFOLLOW);
+      if (!rc) {
+	      conv_timespec(&buf->st_atim, &buf->__st_atim);
+	      conv_timespec(&buf->st_mtim, &buf->__st_mtim);
+	      conv_timespec(&buf->st_ctim, &buf->__st_ctim);
+      }
+      return rc;
+    }
+  errno = EINVAL;
+  return -1;
+}
+hidden_def (__lxstat)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c
new file mode 100644
index 0000000..bf70a7a
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c
@@ -0,0 +1,30 @@ 
+/* Copyright (C) 2011-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <errno.h>
+#include <sys/statfs.h>
+#include <stddef.h>
+
+/* Return information about the filesystem on which FILE resides.  */
+int
+__statfs (const char *file, struct statfs *buf)
+{
+  return INLINE_SYSCALL (statfs64, 2, file, buf);
+}
+libc_hidden_def (__statfs)
+weak_alias (__statfs, statfs)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c
new file mode 100644
index 0000000..b99ab94
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c
@@ -0,0 +1,29 @@ 
+/* Copyright (C) 2011-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <errno.h>
+#include <sys/statfs.h>
+#include <stddef.h>
+
+/* Return information about the filesystem on which FILE resides.  */
+int
+__statfs64 (const char *file, struct statfs64 *buf)
+{
+  return INLINE_SYSCALL (statfs64, 2, file, buf);
+}
+weak_alias (__statfs64,statfs64)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/xstat.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/xstat.c
new file mode 100644
index 0000000..b4e8423
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/xstat.c
@@ -0,0 +1,47 @@ 
+//#include <sysdeps/unix/sysv/linux/generic/wordsize-32/xstat.c>
+/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <errno.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Get information about the file NAME in BUF.  */
+int
+__xstat (int vers, const char *name, struct stat *buf)
+{
+  if (vers == _STAT_VER_KERNEL)
+    {
+      int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
+      if (!rc) {
+	      conv_timespec(&buf->st_atim, &buf->__st_atim);
+	      conv_timespec(&buf->st_mtim, &buf->__st_mtim);
+	      conv_timespec(&buf->st_ctim, &buf->__st_ctim);
+      }
+      return rc;
+    }
+
+  errno = EINVAL;
+  return -1;
+}
+hidden_def (__xstat)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/xstat64.c b/sysdeps/unix/sysv/linux/aarch64/ilp32/xstat64.c
new file mode 100644
index 0000000..e4f4cd5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/xstat64.c
@@ -0,0 +1,47 @@ 
+//#include <sysdeps/unix/sysv/linux/generic/wordsize-32/xstat64.c>
+/* Copyright (C) 2011-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
+
+   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 <errno.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#include <sysdep.h>
+#include <sys/syscall.h>
+
+/* Get information about the file NAME in BUF.  */
+int
+__xstat64 (int vers, const char *name, struct stat64 *buf)
+{
+  if (vers == _STAT_VER_KERNEL) {
+    int rc = INLINE_SYSCALL (fstatat64, 4, AT_FDCWD, name, buf, 0);
+    if (!rc) {
+	    conv_timespec(&buf->st_atim, &buf->__st_atim);
+	    conv_timespec(&buf->st_mtim, &buf->__st_mtim);
+	    conv_timespec(&buf->st_ctim, &buf->__st_ctim);
+    }
+
+    return rc;
+  }
+
+  errno = EINVAL;
+  return -1;
+}
+hidden_def (__xstat64)