Message ID | 1473436199-3305-3-git-send-email-ynorov@caviumnetworks.com |
---|---|
State | New |
Headers | show |
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
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
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
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
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
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)
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