Waldemar Brodkorb wrote:
Ralf Friedl wrote,
I just want to point out that while uClibc statvfs does always set f_frsize,
currently on MIPS at least it doesn't use the value returned by the kernel,
instead it copies the value from f_bsize, thus negating commit 
https://git.busybox.net/busybox/commit/coreutils/df.c?id=8f4faa1e3db91fc7b50d633e6f9b2f04bf978bb2
Additionally, the uClibc implementation always calls stat() on the supplied
argument and for older kernel at least reads /proc/mounts, calls stat() on
the entries and tries to determine the mount flags that statvfs returns but
df doesn't use.

What about using statfs and adding a define to platform.h to determine
whether the value returned by statfs contains f_frsize?
To support the buggy implementation in uClic, f_frsize must be set to zero
before the call and tested later, because it is left unmodified.
May be somebody can suggest a patch to fix the bug in uClibc?
I am always open for bugfixes.
There are two problems with statfs64 in uClibc:

1. The first problem is that the MIPS version https://cgit.openadk.org/cgi/cgit/uclibc-ng.git/tree/libc/sysdeps/linux/mips/bits/statfs.h doesn't define _STATFS_F_FRSIZE, it claims in line 29 that Fragment size is unsupported. This is probably because the definition of struct statfs is copied from the kernel file arch/mips/include/uapi/asm/statfs.h, which contains exactly the same comment. I don't know where this comment originates, but it is not true. I have verified that MIPS kernels as old as 2.6.13 do return f_frsize. That doesn't mean that older versions don't, it's just the oldest running MIPS kernel I have access to. As there is nothing architecture dependent in the file system code, I see no reason why there should ever have been a kernel that contained the definition of f_frsize in struct statfs but didn't return a value for the field. And f_frsize is a field in the top part of the struct, not one appended later.

2. Originally, statfs64 called statfs and copied the values to a struct statfs64. In https://cgit.openadk.org/cgi/cgit/uclibc-ng.git/commit?id=08f8dd1e58f20be82477d37cfd12b7f14be33f9b a change was introduced to use the statfs64 syscall directly. But it tests for the definition of __NR_statfs. Is there an architecture where __NR_statfs is not defined? On MIPS 32 and x86 there is statfs and statfs64. On x64 there is only statfs, which of course returns 64-Bit values, so there is no need for a different call statfs64. So I think it should test on the presence of statfs64 and not statfs to decide whether to use the statfs64 syscall. Again I can confirm that the MIPS kernel 2.6.13 does support the statfs64 syscall, and also the f_frsize field. Using the statfs64 syscall has the additional benefit that it can return values larger than 32-Bit, and it uses less code.

Here are the patches:
- Define _STATFS_F_FRSIZE for MIPS.
- Only emulate statfs64 if __NR_statfs64 is not defined.

--- libc/sysdeps/linux/mips/bits/statfs.h
+++ libc/sysdeps/linux/mips/bits/statfs.h
@@ -70,3 +70,4 @@

 /* Tell code we have these members.  */
 #define _STATFS_F_NAMELEN
+#define _STATFS_F_FRSIZE

--- libc/misc/statfs/statfs64.c
+++ libc/misc/statfs/statfs64.c
@@ -26,7 +26,7 @@

 extern __typeof(statfs) __libc_statfs;

-#if defined __NR_statfs
+#if !defined __NR_statfs64
 /* Return information about the filesystem on which FILE resides. */
 int statfs64 (const char *file, struct statfs64 *buf)
 {

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to