[PATCH 2/7] df: Use statvfs instead of non-standard statfs

Ralf Friedl Ralf.Friedl at online.de
Sat Oct 28 18:17:12 UTC 2017


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)
  {



More information about the busybox mailing list