Subject: Re: bug#6331: [sshfs] df reports wrong disk space usage on solaris

From: Jim Meyering <[email-masked]>
Date: Thu, 03 Jun 2010 10:26:03 +0200

Miklos Szeredi wrote:
...
> Notice that the real statfs syscall does have an f_frsize field, but
> for some historical reason it is not exported in the library API.
>
> Options to fix this behavior would be:
>
>  1) fix df and stat in coreutils to use statvfs
>  2) make sshfs set f_bsize to f_frsize
>  3) make sshfs set f_frsize to f_bsize and recalculate stats
>  4) change both f_frsize and f_bsize to a common value and
>     recalculate stats (this is what NFS appears to be doing)
>
> There is some difficulty with 1) as the libc implementation of statvfs
> has problems:
>
>  "Do not use statvfs on systems with GNU libc on Linux, because that function
>   stats all preceding entries in /proc/mounts, and that makes df hang if even
>   one of the corresponding file systems is hard-mounted, but not available.
>   statvfs in GNU libc on Hurd, BeOS, Haiku operates differently: it only makes
>   a system call."
>
> This might have been fixed in libc since, so it's possible that
> coreutils developers are willing to using statvfs on linux.

glibc's statvfs still appears to have this problem, so coreutils' df
must not use that function.  To demonstrate, I recompiled fsusage.c
with -DSTAT_STATVFS, relinked df, and ran this:

    $ strace -e open,stat ./df .
    ...
    open("/proc/mounts", O_RDONLY)          = 3
    stat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    stat(".", {st_mode=S_IFDIR|0755, st_size=65536, ...}) = 0
    stat("/", {st_mode=S_IFDIR|0555, st_size=4096, ...}) = 0
    stat("/boot", {st_mode=S_IFDIR|0555, st_size=3072, ...}) = 0
    stat("/full", {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0
    stat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

It still opens /proc/mounts and stats mount point directories
until it finds one with a matching dev/inode.  Note that it
does limit its search, when possible, to file systems that are known
to be of the same file system type, but that doesn't help when
the target is NFS mounted.