diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-02-05 20:13:58 +0000 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-02-11 07:58:31 -0300 |
commit | 1bfbaf7130133ae740c09e12dfdd87df26e03d39 (patch) | |
tree | 6ce35b86fe247629bf6bb2dcdf4413fbaaf5d0a6 /sysdeps/unix/sysv/linux/fstatfs.c | |
parent | e7702cb56ec99521124befba3c52903842a885c1 (diff) | |
download | glibc-1bfbaf7130133ae740c09e12dfdd87df26e03d39.tar glibc-1bfbaf7130133ae740c09e12dfdd87df26e03d39.tar.gz glibc-1bfbaf7130133ae740c09e12dfdd87df26e03d39.tar.bz2 glibc-1bfbaf7130133ae740c09e12dfdd87df26e03d39.zip |
linux: Consolidate fstatfs implementations
The __NR_fstatfs64 syscall is supported on all architectures but
aarch64, mips64, riscv64, and x86_64. And newer ABIs also uses
the new fstatfs64 interface (where the struct size is used as
first argument).
So the default implementation now uses:
1. __NR_fstatfs64 for non-LFS call and handle overflow directly
There is no need to handle __NR_fstatfs since all architectures
that only support are LFS only.
2. __NR_fstatfs if defined or __NR_fstatfs64 otherwise for LFS
call.
Alpha is the only outlier, it is a 64-bit architecture which
provides non-LFS interface and only provides __NR_fstatfs64 on
newer kernels (5.1+).
Checked on x86_64-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'sysdeps/unix/sysv/linux/fstatfs.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/fstatfs.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/fstatfs.c b/sysdeps/unix/sysv/linux/fstatfs.c new file mode 100644 index 0000000000..38d621967e --- /dev/null +++ b/sysdeps/unix/sysv/linux/fstatfs.c @@ -0,0 +1,62 @@ +/* Get filesystem statistics. Linux version. + Copyright (C) 2021 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 + <https://www.gnu.org/licenses/>. */ + +#include <sys/statfs.h> +#include <time.h> +#include <sysdep.h> +#include <kernel_stat.h> + +#if !STATFS_IS_STATFS64 + +/* Return information about the filesystem on which FILE resides. */ +int +__fstatfs (int fd, struct statfs *buf) +{ + struct statfs64 buf64; + int rc = INLINE_SYSCALL_CALL (fstatfs64, fd, sizeof (buf64), &buf64); + if (rc != 0) + return rc; + + buf->f_type = buf64.f_type; + buf->f_bsize = buf64.f_bsize; + buf->f_blocks = buf64.f_blocks; + buf->f_bfree = buf64.f_bfree; + buf->f_bavail = buf64.f_bavail; + buf->f_files = buf64.f_files; + buf->f_ffree = buf64.f_ffree; + buf->f_fsid = buf64.f_fsid; + buf->f_namelen = buf64.f_namelen; + buf->f_frsize = buf64.f_frsize; + buf->f_flags = buf64.f_flags; + memcpy (buf->f_spare, buf64.f_spare, sizeof (buf64.f_spare)); + + if ((fsblkcnt_t) buf64.f_blocks != buf64.f_blocks + || (fsblkcnt_t) buf64.f_bfree != buf64.f_bfree + || (fsblkcnt_t) buf64.f_bavail != buf64.f_bavail + || (fsblkcnt_t) buf64.f_files != buf64.f_files + || (fsblkcnt_t) buf64.f_ffree != buf64.f_ffree) + { + __set_errno (EOVERFLOW); + return -1; + } + + return 0; +} +libc_hidden_def (__fstatfs) +weak_alias (__fstatfs, fstatfs) +#endif |