[2/2,AARCH64] ILP32: stat syscalls

Message ID 1473436199-3305-3-git-send-email-ynorov@caviumnetworks.com
State New, archived
Headers

Commit Message

Yury Norov Sept. 9, 2016, 3:49 p.m. UTC
  Implementation details:
 - struct stat, stat64, statfs, statfs64 layouts are taken from
   sysdeps/unix/sysv/linux/aarch64/bits.
 - statfs{,64} is identical to lp64, so corresponding syscalls are
   wired to lp64 handlers in kernel, and implemented in custom files in
   glibc.
 - struct stat has broken st_ino field (legacy from arm32), so it's
   handled in corresponding header in a way to make this structure
   identical to struct stat64.
 - xstat{,64} and lxstat{,64} are unified and taken from
   sysdeps/unix/sysv/linux/generic/wordsize32.
 - other syscalls are taken from sysdeps/unix/sysv/linux.
 - XSTAT_IS_XSTAT64 is defined to use the same implementations for
   syscalls.
 - STAT_IS_KERNEL_STAT is defined, and _STAT_VER is defined to
   _STAT_VER_KERNEL for ilp32 to bypass __xstat_conv().
 - __NR_stat, __NR_fstat, __NR_newfstatat and __NR_lstat are redefined
   to symbols that linux exports.

2016-09-09: Yury Norov  <ynorov@caviumnetworks.com>

	* sysdeps/unix/sysv/linux/aarch64/bits/stat.h: New file
	* sysdeps/unix/sysv/linux/aarch64/bits/statfs.h: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/kernel_stat.h: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c: Likewise
	* sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c: Likewise

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 sysdeps/unix/sysv/linux/aarch64/bits/stat.h        | 166 +++++++++++++++++++++
 sysdeps/unix/sysv/linux/aarch64/bits/statfs.h      |  60 ++++++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c    |   1 +
 sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c  |  35 +++++
 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c     |   1 +
 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c   |   1 +
 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c   |   1 +
 sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c |   1 +
 .../unix/sysv/linux/aarch64/ilp32/kernel_stat.h    |   7 +
 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c     |   1 +
 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c   |  38 +++++
 11 files changed, 312 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/kernel_stat.h
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c
 create mode 100644 sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c
  

Comments

Arnd Bergmann Sept. 9, 2016, 7:47 p.m. UTC | #1
On Friday, September 9, 2016 6:49:59 PM CEST Yury Norov wrote:
> Implementation details:
>  - struct stat, stat64, statfs, statfs64 layouts are taken from
>    sysdeps/unix/sysv/linux/aarch64/bits.

I was confused by the description for a moment. To clarify: 
the layout is added in that directory, not taken from an
existing file there.

>  - struct stat has broken st_ino field (legacy from arm32), so it's
>    handled in corresponding header in a way to make this structure
>    identical to struct stat64.

I think this is best, yes.

>  - statfs{,64} is identical to lp64, so corresponding syscalls are
>    wired to lp64 handlers in kernel, and implemented in custom files in
>    glibc.

During the discussion about stat64, we didn't really get to talk
about statfs64. I didn't expect to see an override here but simply
use the standard definition from
sysdeps/unix/sysv/linux/generic/bits/statfs.h or
sysdeps/unix/sysv/linux/bits/statfs.h together with the 32-bit
syscall emulation in the kernel, as we do for almost all other
syscalls now.

What's the motivation for using the aarch64 structure layout
in this case?

>  - XSTAT_IS_XSTAT64 is defined to use the same implementations for
>    syscalls.
>  - STAT_IS_KERNEL_STAT is defined, and _STAT_VER is defined to
>    _STAT_VER_KERNEL for ilp32 to bypass __xstat_conv().

Sounds good.

>  - __NR_stat, __NR_fstat, __NR_newfstatat and __NR_lstat are redefined
>    to symbols that linux exports.

Why is this in the architecture specific part? Isn't this the same
as all "generic" architectures now?

> 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..6fa13ad
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
> @@ -0,0 +1 @@
> +#include <sysdeps/unix/sysv/linux/fxstat.c>

Why not sysdeps/unix/sysv/linux/generic/xstat.c ?

Same question for the other xstat files.


	Arnd
  
Yury Norov Sept. 11, 2016, 10:17 p.m. UTC | #2
On Fri, Sep 09, 2016 at 09:47:16PM +0200, Arnd Bergmann wrote:
> On Friday, September 9, 2016 6:49:59 PM CEST Yury Norov wrote:
> > Implementation details:
> >  - struct stat, stat64, statfs, statfs64 layouts are taken from
> >    sysdeps/unix/sysv/linux/aarch64/bits.
> 
> I was confused by the description for a moment. To clarify: 
> the layout is added in that directory, not taken from an
> existing file there.

It should be sysdeps/unix/sysv/linux/bits of course. Thanks for catch.

> >  - struct stat has broken st_ino field (legacy from arm32), so it's
> >    handled in corresponding header in a way to make this structure
> >    identical to struct stat64.
> 
> I think this is best, yes.
> 
> >  - statfs{,64} is identical to lp64, so corresponding syscalls are
> >    wired to lp64 handlers in kernel, and implemented in custom files in
> >    glibc.
> 
> During the discussion about stat64, we didn't really get to talk
> about statfs64. I didn't expect to see an override here but simply
> use the standard definition from
> sysdeps/unix/sysv/linux/generic/bits/statfs.h or
> sysdeps/unix/sysv/linux/bits/statfs.h together with the 32-bit
> syscall emulation in the kernel, as we do for almost all other
> syscalls now.
> 
> What's the motivation for using the aarch64 structure layout
> in this case?

I turned __FSWORD_T_TYPE to 64-bit type, as other stat fields.  I think
this is correct. With that, struct statfs{,64} is not identical to arm32
(taken from sysdeps/unix/sysv/linux/generic/bits/statfs.h) anyway. I take
struct statfs from sysdeps/unix/sysv/linux/bits/statfs.h, so it's
pretty standard.

Also notice that statfs syscalls are broken as wrong sizeof(struct
stat) is passed, and kernel has wrappers to handle it -
compat_sys_statfs64_wrapper and compat_sys_fstatfs64_wrapper.

So for me it's more logical and correct to wire this syscalls to lp64.
By similar reasons I wire sys_getrlimit and sys_setrlimit to lp64.

> >  - XSTAT_IS_XSTAT64 is defined to use the same implementations for
> >    syscalls.
> >  - STAT_IS_KERNEL_STAT is defined, and _STAT_VER is defined to
> >    _STAT_VER_KERNEL for ilp32 to bypass __xstat_conv().
> 
> Sounds good.
> 
> >  - __NR_stat, __NR_fstat, __NR_newfstatat and __NR_lstat are redefined
> >    to symbols that linux exports.
> 
> Why is this in the architecture specific part? Isn't this the same
> as all "generic" architectures now?
  
I don't understand it. Some of this defines are needed because arm64
takes syscalls from sysdeps/unix/sysv/linux, not from
sysdeps/unix/sysv/linux/generic/worsize-32. I don't think it's
generic. Though, if it's generic, could you explain it in details, and
I'll change it.

> > 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..6fa13ad
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
> > @@ -0,0 +1 @@
> > +#include <sysdeps/unix/sysv/linux/fxstat.c>
> 
> Why not sysdeps/unix/sysv/linux/generic/xstat.c ?
> 
> Same question for the other xstat files.

sysdeps/unix/sysv/linux/generic has only lxstat.c and 
xstat.c files. Both are taken from
sysdeps/unix/sysv/linux/generic/wordsize-32. Other files are
taken from sysdeps/unix/sysv/linux. Is my understanding correct
that sysdeps/unix/sysv/linux is the default choice for new ports?

Yury
  
Arnd Bergmann Sept. 12, 2016, 9:43 a.m. UTC | #3
On Monday, September 12, 2016 1:17:48 AM CEST Yury Norov wrote:
> On Fri, Sep 09, 2016 at 09:47:16PM +0200, Arnd Bergmann wrote:
> > On Friday, September 9, 2016 6:49:59 PM CEST Yury Norov wrote:
> > >  - struct stat has broken st_ino field (legacy from arm32), so it's
> > >    handled in corresponding header in a way to make this structure
> > >    identical to struct stat64.
> > 
> > I think this is best, yes.
> > 
> > >  - statfs{,64} is identical to lp64, so corresponding syscalls are
> > >    wired to lp64 handlers in kernel, and implemented in custom files in
> > >    glibc.
> > 
> > During the discussion about stat64, we didn't really get to talk
> > about statfs64. I didn't expect to see an override here but simply
> > use the standard definition from
> > sysdeps/unix/sysv/linux/generic/bits/statfs.h or
> > sysdeps/unix/sysv/linux/bits/statfs.h together with the 32-bit
> > syscall emulation in the kernel, as we do for almost all other
> > syscalls now.
> > 
> > What's the motivation for using the aarch64 structure layout
> > in this case?
> 
> I turned __FSWORD_T_TYPE to 64-bit type, as other stat fields.  I think
> this is correct.

I don't see why: For the other syscalls, we decided to follow the
generic/wordsize-32 mode, so why not for this one?

> With that, struct statfs{,64} is not identical to arm32
> (taken from sysdeps/unix/sysv/linux/generic/bits/statfs.h) anyway. I take
> struct statfs from sysdeps/unix/sysv/linux/bits/statfs.h, so it's
> pretty standard.

I don't see the difference, can you be more specific? The only thing
I see is that the "struct statfs" layout in the arm32 case is
different, but we don't use that as the kernel only has the statfs64
syscall interface, which is identical.

> Also notice that statfs syscalls are broken as wrong sizeof(struct
> stat) is passed, and kernel has wrappers to handle it -
> compat_sys_statfs64_wrapper and compat_sys_fstatfs64_wrapper.

I was sure we had this discussion before, and found this in the
archives: https://lkml.org/lkml/2015/12/23/377

Did something change after that?
 
> By similar reasons I wire sys_getrlimit and sys_setrlimit to lp64.

I don't see that one making sense either.
 
> > >  - XSTAT_IS_XSTAT64 is defined to use the same implementations for
> > >    syscalls.
> > >  - STAT_IS_KERNEL_STAT is defined, and _STAT_VER is defined to
> > >    _STAT_VER_KERNEL for ilp32 to bypass __xstat_conv().
> > 
> > Sounds good.
> > 
> > >  - __NR_stat, __NR_fstat, __NR_newfstatat and __NR_lstat are redefined
> > >    to symbols that linux exports.
> > 
> > Why is this in the architecture specific part? Isn't this the same
> > as all "generic" architectures now?
>   
> I don't understand it. Some of this defines are needed because arm64
> takes syscalls from sysdeps/unix/sysv/linux, not from
> sysdeps/unix/sysv/linux/generic/worsize-32. I don't think it's
> generic. Though, if it's generic, could you explain it in details, and
> I'll change it.

I didn't realize we took syscalls from sysdeps/unix/sysv/linux instead
of sysdeps/unix/sysv/linux/generic/wordsize-32. Why is that? Changing
this seems like the easiest fix.

> > > 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..6fa13ad
> > > --- /dev/null
> > > +++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
> > > @@ -0,0 +1 @@
> > > +#include <sysdeps/unix/sysv/linux/fxstat.c>
> > 
> > Why not sysdeps/unix/sysv/linux/generic/xstat.c ?
> > 
> > Same question for the other xstat files.
> 
> sysdeps/unix/sysv/linux/generic has only lxstat.c and 
> xstat.c files. Both are taken from
> sysdeps/unix/sysv/linux/generic/wordsize-32. Other files are
> taken from sysdeps/unix/sysv/linux. Is my understanding correct
> that sysdeps/unix/sysv/linux is the default choice for new ports?

Maybe I'm the one who is misunderstanding it, but I thought the
opposite was the case: From what I can tell, sysdeps/unix/sysv/linux
is used on "old-style" architectures like arm32 or x86-32 that
have the full set of syscalls, while the generic/wordsize-32
directory is for modern architectures that have a reduced set
of syscalls e.g. leaving out the 32-bit off_t interfaces.

	Arnd
  
Yury Norov Sept. 12, 2016, 3:37 p.m. UTC | #4
On Mon, Sep 12, 2016 at 11:43:08AM +0200, Arnd Bergmann wrote:
> On Monday, September 12, 2016 1:17:48 AM CEST Yury Norov wrote:
> > On Fri, Sep 09, 2016 at 09:47:16PM +0200, Arnd Bergmann wrote:
> > > On Friday, September 9, 2016 6:49:59 PM CEST Yury Norov wrote:
> > > >  - struct stat has broken st_ino field (legacy from arm32), so it's
> > > >    handled in corresponding header in a way to make this structure
> > > >    identical to struct stat64.
> > > 
> > > I think this is best, yes.
> > > 
> > > >  - statfs{,64} is identical to lp64, so corresponding syscalls are
> > > >    wired to lp64 handlers in kernel, and implemented in custom files in
> > > >    glibc.
> > > 
> > > During the discussion about stat64, we didn't really get to talk
> > > about statfs64. I didn't expect to see an override here but simply
> > > use the standard definition from
> > > sysdeps/unix/sysv/linux/generic/bits/statfs.h or
> > > sysdeps/unix/sysv/linux/bits/statfs.h together with the 32-bit
> > > syscall emulation in the kernel, as we do for almost all other
> > > syscalls now.
> > > 
> > > What's the motivation for using the aarch64 structure layout
> > > in this case?
> > 
> > I turned __FSWORD_T_TYPE to 64-bit type, as other stat fields.  I think
> > this is correct.
> 
> I don't see why: For the other syscalls, we decided to follow the
> generic/wordsize-32 mode, so why not for this one?
> 
> > With that, struct statfs{,64} is not identical to arm32
> > (taken from sysdeps/unix/sysv/linux/generic/bits/statfs.h) anyway. I take
> > struct statfs from sysdeps/unix/sysv/linux/bits/statfs.h, so it's
> > pretty standard.
> 
> I don't see the difference, can you be more specific? The only thing
> I see is that the "struct statfs" layout in the arm32 case is
> different, but we don't use that as the kernel only has the statfs64
> syscall interface, which is identical.
> 
> > Also notice that statfs syscalls are broken as wrong sizeof(struct
> > stat) is passed, and kernel has wrappers to handle it -
> > compat_sys_statfs64_wrapper and compat_sys_fstatfs64_wrapper.
> 
> I was sure we had this discussion before, and found this in the
> archives: https://lkml.org/lkml/2015/12/23/377
> 
> Did something change after that?
>  
> > By similar reasons I wire sys_getrlimit and sys_setrlimit to lp64.
> 
> I don't see that one making sense either.

It was suggested by Andreas:
https://lkml.org/lkml/2016/7/5/77

> > > >  - XSTAT_IS_XSTAT64 is defined to use the same implementations for
> > > >    syscalls.
> > > >  - STAT_IS_KERNEL_STAT is defined, and _STAT_VER is defined to
> > > >    _STAT_VER_KERNEL for ilp32 to bypass __xstat_conv().
> > > 
> > > Sounds good.
> > > 
> > > >  - __NR_stat, __NR_fstat, __NR_newfstatat and __NR_lstat are redefined
> > > >    to symbols that linux exports.
> > > 
> > > Why is this in the architecture specific part? Isn't this the same
> > > as all "generic" architectures now?
> >   
> > I don't understand it. Some of this defines are needed because arm64
> > takes syscalls from sysdeps/unix/sysv/linux, not from
> > sysdeps/unix/sysv/linux/generic/worsize-32. I don't think it's
> > generic. Though, if it's generic, could you explain it in details, and
> > I'll change it.
> 
> I didn't realize we took syscalls from sysdeps/unix/sysv/linux instead
> of sysdeps/unix/sysv/linux/generic/wordsize-32. Why is that? Changing
> this seems like the easiest fix.

Because syscalls under generic/wordsize-32 use stat_overflow(), and it
fails at compile time as struct stat has no pads:
../sysdeps/unix/sysv/linux/generic/wordsize-32/overflow.h:39:10: error: ‘struct stat’ has no member named      ‘__st_ino_pad’
    if (buf->__st_ino_pad == 0 && buf->__st_size_pad == 0 &&

GCC complains on stat_overflow() even when I try to build
sysdeps/unix/sysv/linux/generic/worsize-32/statfs.c

There's XSTAT_IS_XSTAT64 option to bypass stat_overflow() in stat
syscalls but there's no such option for statfs syscalls. The other
problem I see is that standard syscall files generate different
function bodies for 32- and 64-bit syscalls. And this is the
duplication I'd like to avoid.

So statfs syscalls under generic/wordsize-32:
 - are broken, and should be fixed in kernel. 
 - create duplicated function bodies in binaries.
 - make me do the deep rework for owerflow.h, probably introduce new
   option.
 - limit __FSWORD_T_TYPE, to 32 bit, which is probably makes troubles
   for big filesystems, which may be a case for servers.

That's why I took sysdeps/unix/sysv/linux version. It looks more
natural if I set __FSWORD_T_TYPE to 64-bit: I don't have to change
anything to make things work.

Yury.

> > > > 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..6fa13ad
> > > > --- /dev/null
> > > > +++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
> > > > @@ -0,0 +1 @@
> > > > +#include <sysdeps/unix/sysv/linux/fxstat.c>
> > > 
> > > Why not sysdeps/unix/sysv/linux/generic/xstat.c ?
> > > 
> > > Same question for the other xstat files.
> > 
> > sysdeps/unix/sysv/linux/generic has only lxstat.c and 
> > xstat.c files. Both are taken from
> > sysdeps/unix/sysv/linux/generic/wordsize-32. Other files are
> > taken from sysdeps/unix/sysv/linux. Is my understanding correct
> > that sysdeps/unix/sysv/linux is the default choice for new ports?
> 
> Maybe I'm the one who is misunderstanding it, but I thought the
> opposite was the case: From what I can tell, sysdeps/unix/sysv/linux
> is used on "old-style" architectures like arm32 or x86-32 that
> have the full set of syscalls, while the generic/wordsize-32
> directory is for modern architectures that have a reduced set
> of syscalls e.g. leaving out the 32-bit off_t interfaces.
> 
> 	Arnd
  
Arnd Bergmann Sept. 12, 2016, 7:56 p.m. UTC | #5
On Monday, September 12, 2016 6:37:18 PM CEST Yury Norov wrote:
> On Mon, Sep 12, 2016 at 11:43:08AM +0200, Arnd Bergmann wrote:
> > On Monday, September 12, 2016 1:17:48 AM CEST Yury Norov wrote:
> > > By similar reasons I wire sys_getrlimit and sys_setrlimit to lp64.
> > 
> > I don't see that one making sense either.
> 
> It was suggested by Andreas:
> https://lkml.org/lkml/2016/7/5/77

Ah, I think we just missed that with the addition of prlimit64, the old
getrlimit/setrlimit syscall entry points got obsolete.

I think we should handle this the same way as renameat, which got
superceded by renameat2: not define the syscall entry point from
the kernel and let glibc handle it by calling the replacement
syscall.

Overriding getrlimit/setrlimit to the 64-bit types in the kernel
is wrong, it just makes the ABI different from all other
architectures, and we should be able to handle this without
any architecture specific code.

> > > I don't understand it. Some of this defines are needed because arm64
> > > takes syscalls from sysdeps/unix/sysv/linux, not from
> > > sysdeps/unix/sysv/linux/generic/worsize-32. I don't think it's
> > > generic. Though, if it's generic, could you explain it in details, and
> > > I'll change it.
> > 
> > I didn't realize we took syscalls from sysdeps/unix/sysv/linux instead
> > of sysdeps/unix/sysv/linux/generic/wordsize-32. Why is that? Changing
> > this seems like the easiest fix.
> 
> Because syscalls under generic/wordsize-32 use stat_overflow(), and it
> fails at compile time as struct stat has no pads:
> ../sysdeps/unix/sysv/linux/generic/wordsize-32/overflow.h:39:10: error: ‘struct stat’ has no member named      ‘__st_ino_pad’
>     if (buf->__st_ino_pad == 0 && buf->__st_size_pad == 0 &&
> 
> GCC complains on stat_overflow() even when I try to build
> sysdeps/unix/sysv/linux/generic/worsize-32/statfs.c

Hmm, but this just tells me that the generic/wordsize-32 syscalls
currently assume that you want different implementations for
32-bit off_t and 64-bit off_t, which we don't want for new
architectures any more.

> There's XSTAT_IS_XSTAT64 option to bypass stat_overflow() in stat
> syscalls but there's no such option for statfs syscalls. The other
> problem I see is that standard syscall files generate different
> function bodies for 32- and 64-bit syscalls. And this is the
> duplication I'd like to avoid.

But with your patch 1/2, you are fixing this already: the
broken __lxstat/__xstat implementations don't get compiled any
more and instead redirect to the correct __lxstat64/__xstat64
functions that don't have this problem.

statfs can simply do the same thing.

> So statfs syscalls under generic/wordsize-32:
>  - are broken, and should be fixed in kernel. 

I don't see anything broken in the kernel.

>  - create duplicated function bodies in binaries.

Easily fixed by doing the respective "don't duplicate statfs if..."
patch the same way that you did "don't duplicate lxstat, xstat".

>  - make me do the deep rework for owerflow.h, probably introduce new
>    option.

No, that file simply never gets included when we know we have 64-bit
off_t etc.

>  - limit __FSWORD_T_TYPE, to 32 bit, which is probably makes troubles
>    for big filesystems, which may be a case for servers.
>
> That's why I took sysdeps/unix/sysv/linux version. It looks more
> natural if I set __FSWORD_T_TYPE to 64-bit: I don't have to change
> anything to make things work.

If you think that __FSWORD_T_TYPE is not enough, we should change
it for all architectures and introduce a new statfs64 replacement.

Given the fields that use it, I don't see what could possibly
overflow though:

    __fsword_t f_type;
    __fsword_t f_bsize;
    __fsword_t f_namelen;
    __fsword_t f_frsize;
    __fsword_t f_flags;

I certainly don't want to see arm64 diverge from the generic syscall
ABI just because you think that one of those fields might overflow
in the future.

	Arnd
  

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..adf8f4e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/stat.h
@@ -0,0 +1,166 @@ 
+/* Structs stat and stat64
+   Copyright (C) 1992-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/>.  */
+
+#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_LINUX_OLD	1
+#define _STAT_VER_KERNEL	1
+#define _STAT_VER_SVR4		2
+#define _STAT_VER_LINUX		3
+# ifdef __ILP32__
+#  define _STAT_VER		_STAT_VER_KERNEL
+# else
+#  define _STAT_VER		_STAT_VER_LINUX	/* The one defined below.  */
+# endif
+
+/* Versions of the `xmknod' interface.  */
+#define _MKNOD_VER_LINUX	1
+#define _MKNOD_VER_SVR4		2
+#define _MKNOD_VER		_MKNOD_VER_LINUX /* The bits defined below.  */
+
+
+struct stat
+  {
+    __dev_t st_dev;			/* Device.  */
+#ifdef __LP64__
+    __ino_t st_ino;			/* File serial number.	*/
+#else
+    unsigned short int __pad1;
+    unsigned int __st_ino;		/* 32bit file serial number.	*/
+#endif
+    __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.  */
+    unsigned short int __pad2;
+    __off_t st_size;			/* Size of file, in bytes.  */
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+
+    __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.  */
+    struct timespec st_atim;		/* Time of last access.  */
+    struct timespec st_mtim;		/* Time of last modification.  */
+    struct timespec st_ctim;		/* Time of last status change.  */
+# define st_atime st_atim.tv_sec	/* Backward compatibility.  */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
+    __time_t st_atime;			/* Time of last access.  */
+    unsigned long int st_atimensec;	/* Nscecs of last access.  */
+    __time_t st_mtime;			/* Time of last modification.  */
+    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
+    __time_t st_ctime;			/* Time of last status change.  */
+    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+#endif
+#ifdef __LP64__
+    int __glibc_reserved[2];
+#else
+    __ino64_t st_ino;			/* File serial number.	*/
+#endif
+  };
+
+struct stat64
+  {
+    __dev_t st_dev;			/* Device.  */
+    unsigned int __pad1;
+
+    unsigned int __st_ino;		/* 32bit 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.  */
+    unsigned int __pad2;
+    __off64_t st_size;			/* Size of file, in bytes.  */
+    __blksize_t st_blksize;		/* Optimal block size for I/O.  */
+
+    __blkcnt64_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.  */
+    struct timespec st_atim;		/* Time of last access.  */
+    struct timespec st_mtim;		/* Time of last modification.  */
+    struct timespec st_ctim;		/* Time of last status change.  */
+# else
+    __time_t st_atime;			/* Time of last access.  */
+    unsigned long int st_atimensec;	/* Nscecs of last access.  */
+    __time_t st_mtime;			/* Time of last modification.  */
+    unsigned long int st_mtimensec;	/* Nsecs of last modification.  */
+    __time_t st_ctime;			/* Time of last status change.  */
+    unsigned long int st_ctimensec;	/* Nsecs of last status change.  */
+# endif
+    __ino64_t st_ino;			/* File serial number.		*/
+  };
+
+/* 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..c37dc6d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/statfs.h
@@ -0,0 +1,60 @@ 
+/* Structures statfs and statfs64
+   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/>.  */
+
+#ifndef _SYS_STATFS_H
+# error "Never include <bits/statfs.h> directly; use <sys/statfs.h> instead."
+#endif
+
+#include <bits/types.h>
+
+struct statfs
+  {
+    __fsword_t f_type;
+    __fsword_t 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;
+    __fsword_t f_namelen;
+    __fsword_t f_frsize;
+    __fsword_t f_flags;
+    __fsword_t f_spare[4];
+  };
+
+struct statfs64
+  {
+    __fsword_t f_type;
+    __fsword_t f_bsize;
+    __fsblkcnt64_t f_blocks;
+    __fsblkcnt64_t f_bfree;
+    __fsblkcnt64_t f_bavail;
+    __fsfilcnt64_t f_files;
+    __fsfilcnt64_t f_ffree;
+    __fsid_t f_fsid;
+    __fsword_t f_namelen;
+    __fsword_t f_frsize;
+    __fsword_t f_flags;
+    __fsword_t f_spare[4];
+  };
+
+/* 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..d213179
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs.c
@@ -0,0 +1 @@ 
+/* See sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c */
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..ad5675d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fstatfs64.c
@@ -0,0 +1,35 @@ 
+/* 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/>.  */
+#define __fstatfs __statfs_disable
+#define fstatfs statfs_disable
+
+#include <errno.h>
+#include <sys/statfs.h>
+#include <stddef.h>
+
+int
+__fstatfs64 (int fd, struct statfs64 *buf)
+{
+  return INLINE_SYSCALL (fstatfs64, 2, fd, buf);
+}
+
+#undef __fstatfs
+#undef fstatfs
+strong_alias (__fstatfs64, __fstatfs)
+weak_alias (__fstatfs64, fstatfs64)
+weak_alias (__fstatfs64, fstatfs)
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..6fa13ad
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c
@@ -0,0 +1 @@ 
+#include <sysdeps/unix/sysv/linux/fxstat.c>
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..ec28959
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat64.c
@@ -0,0 +1 @@ 
+/* See sysdeps/unix/sysv/linux/aarch64/ilp32/fxstat.c */
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..72806b9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c
@@ -0,0 +1 @@ 
+#include <sysdeps/unix/sysv/linux/fxstatat.c>
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..0bc494f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat64.c
@@ -0,0 +1 @@ 
+/* See sysdeps/unix/sysv/linux/aarch64/ilp32/fxstatat.c  */
diff --git a/sysdeps/unix/sysv/linux/aarch64/ilp32/kernel_stat.h b/sysdeps/unix/sysv/linux/aarch64/ilp32/kernel_stat.h
new file mode 100644
index 0000000..ff80758
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/kernel_stat.h
@@ -0,0 +1,7 @@ 
+#define __NR_stat		__NR_stat64
+#define __NR_fstat		__NR_fstat64
+#define __NR_newfstatat		__NR_fstatat64
+#define __NR_lstat		__NR_lstat64
+
+#define XSTAT_IS_XSTAT64	1
+#define STAT_IS_KERNEL_STAT
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..69d7336
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/statfs.c
@@ -0,0 +1 @@ 
+/* See sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c  */
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..66772a8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/ilp32/statfs64.c
@@ -0,0 +1,38 @@ 
+/* Return information about the filesystem on which FILE resides.
+
+   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/>.  */
+#define __statfs __statfs_disable
+#define statfs statfs_disable
+
+#include <errno.h>
+#include <sys/statfs.h>
+#include <stddef.h>
+
+int
+__statfs64 (const char *file, struct statfs64 *buf)
+{
+  return INLINE_SYSCALL (statfs64, 2, file, buf);
+}
+
+#undef __statfs
+#undef statfs
+weak_alias (__statfs64, statfs64)
+strong_alias (__statfs64, __statfs)
+libc_hidden_ver (__statfs64, __statfs)
+weak_alias (__statfs64, statfs)