diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 150dd14f9..b91f5bf57 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -174,9 +174,9 @@ int __fadvise64:fadvise64_64(int, off64_t, off64_t, int) x86 int __fadvise64:fadvise64(int, off64_t, off64_t, int) arm64,mips,mips64,x86_64 int __fstatfs64:fstatfs64(int, size_t, struct statfs*) arm,mips,x86 -int fstatfs64|fstatfs:fstatfs(int, struct statfs*) arm64,mips64,x86_64 +int __fstatfs:fstatfs(int, struct statfs*) arm64,mips64,x86_64 int __statfs64:statfs64(const char*, size_t, struct statfs*) arm,mips,x86 -int statfs64|statfs:statfs(const char*, struct statfs*) arm64,mips64,x86_64 +int __statfs:statfs(const char*, struct statfs*) arm64,mips64,x86_64 int fstat64|fstat:fstat64(int, struct stat*) arm,mips,x86 int fstat64|fstat:fstat(int, struct stat*) arm64,x86_64 diff --git a/libc/arch-arm64/syscalls/fstatfs64.S b/libc/arch-arm64/syscalls/__fstatfs.S similarity index 73% rename from libc/arch-arm64/syscalls/fstatfs64.S rename to libc/arch-arm64/syscalls/__fstatfs.S index 2ca2dcd7f..7e350d6c5 100644 --- a/libc/arch-arm64/syscalls/fstatfs64.S +++ b/libc/arch-arm64/syscalls/__fstatfs.S @@ -2,7 +2,7 @@ #include -ENTRY(fstatfs64) +ENTRY(__fstatfs) mov x8, __NR_fstatfs svc #0 @@ -11,7 +11,5 @@ ENTRY(fstatfs64) b.hi __set_errno_internal ret -END(fstatfs64) - - .globl fstatfs - .equ fstatfs, fstatfs64 +END(__fstatfs) +.hidden __fstatfs diff --git a/libc/arch-arm64/syscalls/statfs64.S b/libc/arch-arm64/syscalls/__statfs.S similarity index 74% rename from libc/arch-arm64/syscalls/statfs64.S rename to libc/arch-arm64/syscalls/__statfs.S index ec8c588df..962c59098 100644 --- a/libc/arch-arm64/syscalls/statfs64.S +++ b/libc/arch-arm64/syscalls/__statfs.S @@ -2,7 +2,7 @@ #include -ENTRY(statfs64) +ENTRY(__statfs) mov x8, __NR_statfs svc #0 @@ -11,7 +11,5 @@ ENTRY(statfs64) b.hi __set_errno_internal ret -END(statfs64) - - .globl statfs - .equ statfs, statfs64 +END(__statfs) +.hidden __statfs diff --git a/libc/arch-mips64/syscalls/fstatfs64.S b/libc/arch-mips64/syscalls/__fstatfs.S similarity index 81% rename from libc/arch-mips64/syscalls/fstatfs64.S rename to libc/arch-mips64/syscalls/__fstatfs.S index 12e885cf1..8766e22b5 100644 --- a/libc/arch-mips64/syscalls/fstatfs64.S +++ b/libc/arch-mips64/syscalls/__fstatfs.S @@ -2,7 +2,7 @@ #include -ENTRY(fstatfs64) +ENTRY(__fstatfs) .set push .set noreorder li v0, __NR_fstatfs @@ -22,7 +22,5 @@ ENTRY(fstatfs64) j t9 move ra, t0 .set pop -END(fstatfs64) - - .globl fstatfs - .equ fstatfs, fstatfs64 +END(__fstatfs) +.hidden __fstatfs diff --git a/libc/arch-mips64/syscalls/statfs64.S b/libc/arch-mips64/syscalls/__statfs.S similarity index 82% rename from libc/arch-mips64/syscalls/statfs64.S rename to libc/arch-mips64/syscalls/__statfs.S index 74351f7f5..52db4e2a8 100644 --- a/libc/arch-mips64/syscalls/statfs64.S +++ b/libc/arch-mips64/syscalls/__statfs.S @@ -2,7 +2,7 @@ #include -ENTRY(statfs64) +ENTRY(__statfs) .set push .set noreorder li v0, __NR_statfs @@ -22,7 +22,5 @@ ENTRY(statfs64) j t9 move ra, t0 .set pop -END(statfs64) - - .globl statfs - .equ statfs, statfs64 +END(__statfs) +.hidden __statfs diff --git a/libc/arch-x86_64/syscalls/fstatfs64.S b/libc/arch-x86_64/syscalls/__fstatfs.S similarity index 76% rename from libc/arch-x86_64/syscalls/fstatfs64.S rename to libc/arch-x86_64/syscalls/__fstatfs.S index f727350e1..b50e3553f 100644 --- a/libc/arch-x86_64/syscalls/fstatfs64.S +++ b/libc/arch-x86_64/syscalls/__fstatfs.S @@ -2,7 +2,7 @@ #include -ENTRY(fstatfs64) +ENTRY(__fstatfs) movl $__NR_fstatfs, %eax syscall cmpq $-MAX_ERRNO, %rax @@ -12,7 +12,5 @@ ENTRY(fstatfs64) call __set_errno_internal 1: ret -END(fstatfs64) - - .globl fstatfs - .equ fstatfs, fstatfs64 +END(__fstatfs) +.hidden __fstatfs diff --git a/libc/arch-x86_64/syscalls/statfs64.S b/libc/arch-x86_64/syscalls/__statfs.S similarity index 77% rename from libc/arch-x86_64/syscalls/statfs64.S rename to libc/arch-x86_64/syscalls/__statfs.S index 16f6bdd6b..607a809db 100644 --- a/libc/arch-x86_64/syscalls/statfs64.S +++ b/libc/arch-x86_64/syscalls/__statfs.S @@ -2,7 +2,7 @@ #include -ENTRY(statfs64) +ENTRY(__statfs) movl $__NR_statfs, %eax syscall cmpq $-MAX_ERRNO, %rax @@ -12,7 +12,5 @@ ENTRY(statfs64) call __set_errno_internal 1: ret -END(statfs64) - - .globl statfs - .equ statfs, statfs64 +END(__statfs) +.hidden __statfs diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp index 73f77bebf..50e4643ce 100644 --- a/libc/bionic/legacy_32_bit_support.cpp +++ b/libc/bionic/legacy_32_bit_support.cpp @@ -40,9 +40,7 @@ // System calls we need. extern "C" int __fcntl64(int, int, void*); -extern "C" int __fstatfs64(int, size_t, struct statfs*); extern "C" int __llseek(int, unsigned long, unsigned long, off64_t*, int); -extern "C" int __statfs64(const char*, size_t, struct statfs*); // For fcntl we use the fcntl64 system call to signal that we're using struct flock64. int fcntl(int fd, int cmd, ...) { @@ -55,18 +53,6 @@ int fcntl(int fd, int cmd, ...) { return __fcntl64(fd, cmd, arg); } -// For fstatfs we need to add the extra argument giving the kernel the size of the buffer. -int fstatfs(int fd, struct statfs* stat) { - return __fstatfs64(fd, sizeof(*stat), stat); -} -__strong_alias(fstatfs64, fstatfs); - -// For statfs we need to add the extra argument giving the kernel the size of the buffer. -int statfs(const char* path, struct statfs* stat) { - return __statfs64(path, sizeof(*stat), stat); -} -__strong_alias(statfs64, statfs); - // For lseek64 we need to use the llseek system call which splits the off64_t in two and // returns the off64_t result via a pointer because 32-bit kernels can't return 64-bit results. off64_t lseek64(int fd, off64_t off, int whence) { diff --git a/libc/bionic/statvfs.cpp b/libc/bionic/statvfs.cpp index f1e283316..39ffb640f 100644 --- a/libc/bionic/statvfs.cpp +++ b/libc/bionic/statvfs.cpp @@ -21,13 +21,17 @@ // Paper over the fact that 32-bit kernels use fstatfs64/statfs64 with an extra argument, // but 64-bit kernels don't have the "64" bit suffix or the extra size_t argument. #if __LP64__ -# define __fstatfs64(fd,size,buf) fstatfs(fd,buf) -# define __statfs64(path,size,buf) statfs(path,buf) +extern "C" int __fstatfs(int, struct statfs*); +extern "C" int __statfs(const char*, struct statfs*); +# define __fstatfs64(fd,size,buf) __fstatfs(fd,buf) +# define __statfs64(path,size,buf) __statfs(path,buf) #else extern "C" int __fstatfs64(int, size_t, struct statfs*); extern "C" int __statfs64(const char*, size_t, struct statfs*); #endif +// The kernel sets a private ST_VALID flag to signal to the C library whether the +// f_flags field is valid. This flag should not be exposed to users of the C library. #define ST_VALID 0x0020 static void __statfs_to_statvfs(const struct statfs& in, struct statvfs* out) { @@ -40,13 +44,33 @@ static void __statfs_to_statvfs(const struct statfs& in, struct statvfs* out) { out->f_ffree = in.f_ffree; out->f_favail = in.f_ffree; out->f_fsid = in.f_fsid.__val[0] | (static_cast(in.f_fsid.__val[1]) << 32); - out->f_flag = in.f_flags & ~ST_VALID; + out->f_flag = in.f_flags; out->f_namemax = in.f_namelen; } +int fstatfs(int fd, struct statfs* result) { + int rc = __fstatfs64(fd, sizeof(*result), result); + if (rc != 0) { + return rc; + } + result->f_flags &= ~ST_VALID; + return 0; +} +__strong_alias(fstatfs64, fstatfs); + +int statfs(const char* path, struct statfs* result) { + int rc = __statfs64(path, sizeof(*result), result); + if (rc != 0) { + return rc; + } + result->f_flags &= ~ST_VALID; + return 0; +} +__strong_alias(statfs64, statfs); + int statvfs(const char* path, struct statvfs* result) { struct statfs tmp; - int rc = __statfs64(path, sizeof(tmp), &tmp); + int rc = statfs(path, &tmp); if (rc != 0) { return rc; } @@ -57,7 +81,7 @@ __strong_alias(statvfs64, statvfs); int fstatvfs(int fd, struct statvfs* result) { struct statfs tmp; - int rc = __fstatfs64(fd, sizeof(tmp), &tmp); + int rc = fstatfs(fd, &tmp); if (rc != 0) { return rc; } diff --git a/tests/sys_statvfs_test.cpp b/tests/sys_statvfs_test.cpp index 6b19e13b8..bff9e2035 100644 --- a/tests/sys_statvfs_test.cpp +++ b/tests/sys_statvfs_test.cpp @@ -30,6 +30,11 @@ template void Check(StatVfsT& sb) { EXPECT_EQ(0U, sb.f_ffree); EXPECT_EQ(0U, sb.f_fsid); EXPECT_EQ(255U, sb.f_namemax); + + // The kernel sets a private bit to indicate that f_flags is valid. + // This flag is not supposed to be exposed to libc clients. + static const uint32_t ST_VALID = 0x0020; + EXPECT_TRUE((sb.f_flag & ST_VALID) == 0) << sb.f_flag; } TEST(sys_statvfs, statvfs) { @@ -51,6 +56,7 @@ TEST(sys_statvfs, fstatvfs) { close(fd); Check(sb); } + TEST(sys_statvfs, fstatvfs64) { struct statvfs64 sb; int fd = open("/proc", O_RDONLY); diff --git a/tests/sys_vfs_test.cpp b/tests/sys_vfs_test.cpp index 4b056607b..a521967bf 100644 --- a/tests/sys_vfs_test.cpp +++ b/tests/sys_vfs_test.cpp @@ -31,6 +31,11 @@ template void Check(StatFsT& sb) { EXPECT_EQ(0, sb.f_fsid.__val[0]); EXPECT_EQ(0, sb.f_fsid.__val[1]); EXPECT_EQ(255, static_cast(sb.f_namelen)); + + // The kernel sets a private bit to indicate that f_flags is valid. + // This flag is not supposed to be exposed to libc clients. + static const uint32_t ST_VALID = 0x0020; + EXPECT_TRUE((sb.f_flags & ST_VALID) == 0) << sb.f_flags; } TEST(sys_vfs, statfs) { @@ -52,6 +57,7 @@ TEST(sys_vfs, fstatfs) { close(fd); Check(sb); } + TEST(sys_vfs, fstatfs64) { struct statfs64 sb; int fd = open("/proc", O_RDONLY);