From 8a73a967e18c55199785bae0f22dc94d9b2f8985 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 27 Nov 2018 15:41:37 +0100 Subject: statfs.h: sync generic header with glibc Fix issues with aarch64 and df with mismatching header between kernel and libc. --- libc/sysdeps/linux/common-generic/bits/statfs.h | 84 ++++++++++++------------- libc/sysdeps/linux/common/fstatfs.c | 9 --- libc/sysdeps/linux/common/statfs.c | 10 --- 3 files changed, 40 insertions(+), 63 deletions(-) diff --git a/libc/sysdeps/linux/common-generic/bits/statfs.h b/libc/sysdeps/linux/common-generic/bits/statfs.h index a2767b49a..23519a57e 100644 --- a/libc/sysdeps/linux/common-generic/bits/statfs.h +++ b/libc/sysdeps/linux/common-generic/bits/statfs.h @@ -11,65 +11,61 @@ #include #include #include +#include +/* 64-bit libc uses the kernel's 'struct statfs', accessed via the + statfs() syscall; 32-bit libc uses the kernel's 'struct statfs64' + and accesses it via the statfs64() syscall. All the various + APIs offered by libc use the kernel shape for their struct statfs + structure; the only difference is that 32-bit programs not + using __USE_FILE_OFFSET64 only see the low 32 bits of some + of the fields (the __fsblkcnt_t and __fsfilcnt_t fields). */ + +#if defined __USE_FILE_OFFSET64 +# define __field64(type, type64, name) type64 name +#elif __WORDSIZE == 64 +# define __field64(type, type64, name) type name +#elif __BYTE_ORDER == __LITTLE_ENDIAN +# define __field64(type, type64, name) \ + type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad +#else +# define __field64(type, type64, name) \ + int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name +#endif struct statfs { - __U32_TYPE f_type; - __U32_TYPE f_bsize; -#ifndef __USE_FILE_OFFSET64 -# if __BYTE_ORDER == __LITTLE_ENDIAN - __U32_TYPE f_blocks; - __U32_TYPE __pad1; - __U32_TYPE f_bfree; - __U32_TYPE __pad2; - __U32_TYPE f_bavail; - __U32_TYPE __pad3; - __U32_TYPE f_files; - __U32_TYPE __pad4; - __U32_TYPE f_ffree; - __U32_TYPE __pad5; -# else - __U32_TYPE __pad1; - __U32_TYPE f_blocks; - __U32_TYPE __pad2; - __U32_TYPE f_bfree; - __U32_TYPE __pad3; - __U32_TYPE f_bavail; - __U32_TYPE __pad4; - __U32_TYPE f_files; - __U32_TYPE __pad5; - __U32_TYPE f_ffree; -# endif /* __LITTLE_ENDIAN */ -#else - __U64_TYPE f_blocks; - __U64_TYPE f_bfree; - __U64_TYPE f_bavail; - __U64_TYPE f_files; - __U64_TYPE f_ffree; -#endif /* __USE_FILE_OFFSET64 */ + __SWORD_TYPE f_type; + __SWORD_TYPE f_bsize; + __field64(__fsblkcnt_t, __fsblkcnt64_t, f_blocks); + __field64(__fsblkcnt_t, __fsblkcnt64_t, f_bfree); + __field64(__fsblkcnt_t, __fsblkcnt64_t, f_bavail); + __field64(__fsfilcnt_t, __fsfilcnt64_t, f_files); + __field64(__fsfilcnt_t, __fsfilcnt64_t, f_ffree); __fsid_t f_fsid; - __U32_TYPE f_namelen; - __U32_TYPE f_frsize; - __U32_TYPE f_flags; - __U32_TYPE f_spare[4]; - } __ARCH_64BIT_ALIGNMENT__; + __SWORD_TYPE f_namelen; + __SWORD_TYPE f_frsize; + __SWORD_TYPE f_flags; + __SWORD_TYPE f_spare[4]; + }; + +#undef __field64 #ifdef __USE_LARGEFILE64 struct statfs64 { - __U32_TYPE f_type; - __U32_TYPE f_bsize; + __SWORD_TYPE f_type; + __SWORD_TYPE f_bsize; __U64_TYPE f_blocks; __U64_TYPE f_bfree; __U64_TYPE f_bavail; __U64_TYPE f_files; __U64_TYPE f_ffree; __fsid_t f_fsid; - __U32_TYPE f_namelen; - __U32_TYPE f_frsize; - __U32_TYPE f_flags; - __U32_TYPE f_spare[4]; + __SWORD_TYPE f_namelen; + __SWORD_TYPE f_frsize; + __SWORD_TYPE f_flags; + __SWORD_TYPE f_spare[4]; }; #endif diff --git a/libc/sysdeps/linux/common/fstatfs.c b/libc/sysdeps/linux/common/fstatfs.c index fcb0820eb..0b2709ce3 100644 --- a/libc/sysdeps/linux/common/fstatfs.c +++ b/libc/sysdeps/linux/common/fstatfs.c @@ -30,15 +30,6 @@ _syscall2(int, __libc_fstatfs, int, fd, struct statfs *, buf) int __libc_fstatfs (int __fildes, struct statfs *__buf) { int err = INLINE_SYSCALL(fstatfs64, 3, __fildes, sizeof(*__buf), __buf); - - if (err == 0) { - /* Did we overflow? */ - if (__buf->__pad1 || __buf->__pad2 || __buf->__pad3 || - __buf->__pad4 || __buf->__pad5) { - __set_errno(EOVERFLOW); - return -1; - } - } return err; }; /* Redefined fstatfs because we need it for backwards compatibility */ diff --git a/libc/sysdeps/linux/common/statfs.c b/libc/sysdeps/linux/common/statfs.c index ab9ec0e56..2990ff3e2 100644 --- a/libc/sysdeps/linux/common/statfs.c +++ b/libc/sysdeps/linux/common/statfs.c @@ -18,16 +18,6 @@ extern __typeof(statfs) __libc_statfs attribute_hidden; int __libc_statfs(const char *path, struct statfs *buf) { int err = INLINE_SYSCALL(statfs64, 3, path, sizeof(*buf), buf); - - if (err == 0) { - /* Did we overflow? */ - if (buf->__pad1 || buf->__pad2 || buf->__pad3 || - buf->__pad4 || buf->__pad5) { - __set_errno(EOVERFLOW); - return -1; - } - } - return err; } # if defined __UCLIBC_LINUX_SPECIFIC__ || defined __UCLIBC_HAS_THREADS_NATIVE__ -- cgit v1.2.3