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

From: Jim Meyering <[email-masked]>
Date: Wed, 16 Jun 2010 07:54:43 +0200

Miklos Szeredi wrote:
> On Thu, 03 Jun 2010, Miklos Szeredi wrote:
>> Hmm, actually "struct statfs" on linux does have f_frsize, only the
>> manpage doesn't document it.  So correct thing would be to use that,
>> no?
>
> Here's a patch that allows df(1) to correctly calculate the disk usage
> and displays f_frsize in stat(1).

Hi Miklos,

[Cc'ing bug-gnulib, since all but src/stat.c are from gnulib]

Thank you for the patch.
However, I'm not sure it's portable enough.
Do you know when the f_frsize member began to be useful?
Without knowing that, I cannot judge whether this introduces
a portability problem on older glibc, kernels or file systems.
Even merely knowing that is probably not enough.

Given the lack of documentation for that member, I suspect
that any safe change would involve a run-time check to verify
that infrastructure is new enough that the member is usable.

> ---
>  gnulib/lib/fsusage.c |    7 +++++++
>  m4/stat-prog.m4      |    2 +-
>  src/stat.c           |    6 +++++-
>  3 files changed, 13 insertions(+), 2 deletions(-)
>
> Index: coreutils/m4/stat-prog.m4
> ===================================================================
> --- coreutils.orig/m4/stat-prog.m4	2010-06-15 13:08:56.000000000 +0200
> +++ coreutils/m4/stat-prog.m4	2010-06-15 13:47:51.000000000 +0200
> @@ -71,7 +71,7 @@ AC_INCLUDES_DEFAULT
>        [AC_DEFINE([STRUCT_STATVFS_F_FSID_IS_INTEGER], [1],
>           [Define to 1 if the f_fsid member of struct statvfs is an integer.])])
>    else
> -    AC_CHECK_MEMBERS([struct statfs.f_namelen, struct statfs.f_type],,,
> +    AC_CHECK_MEMBERS([struct statfs.f_namelen, struct statfs.f_type, struct statfs.f_frsize],,,
>        [$statfs_includes])
>      if test $ac_cv_header_OS_h != yes; then
>        AC_COMPILE_IFELSE(
> Index: coreutils/src/stat.c
> ===================================================================
> --- coreutils.orig/src/stat.c	2010-06-15 13:08:56.000000000 +0200
> +++ coreutils/src/stat.c	2010-06-15 13:09:02.000000000 +0200
> @@ -118,7 +118,11 @@ statfs (char const *filename, struct fs_
>  # else
>  #  define STRUCT_STATVFS struct statfs
>  #  define STRUCT_STATXFS_F_FSID_IS_INTEGER STRUCT_STATFS_F_FSID_IS_INTEGER
> -#  define STATFS_FRSIZE(S) 0
> +#  if HAVE_STRUCT_STATFS_F_FRSIZE
> +#   define STATFS_FRSIZE(S) ((S)->f_frsize)
> +#  else
> +#   define STATFS_FRSIZE(S) 0
> +#  endif
>  # endif
>  #endif
>
> Index: coreutils/gnulib/lib/fsusage.c
> ===================================================================
> --- coreutils.orig/gnulib/lib/fsusage.c	2010-06-15 13:46:49.000000000 +0200
> +++ coreutils/gnulib/lib/fsusage.c	2010-06-15 13:46:56.000000000 +0200
> @@ -172,7 +172,14 @@ get_fs_usage (char const *file, char con
>    if (statfs (file, &fsd) < 0)
>      return -1;
>
> +#ifdef HAVE_STRUCT_STATFS_F_FRSIZE
> +  /* f_frsize isn't guaranteed to be supported.  */
> +  fsp->fsu_blocksize = (fsd.f_frsize
> +                        ? PROPAGATE_ALL_ONES (fsd.f_frsize)
> +                        : PROPAGATE_ALL_ONES (fsd.f_bsize));
> +#else
>    fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);
> +#endif
>
>  # ifdef STATFS_TRUNCATES_BLOCK_COUNTS
>