[2/2,AARCH64] ILP32: stat syscalls
diff mbox

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

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 mbox

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)