From b1fac377605c0eef8844fc8d3818d360f37d6fa4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Tue, 15 May 2012 12:52:36 +0100 Subject: [PATCH] fsusage: fix block size returned on older Linux 2.6 * lib/fsusage.c: Fall back to (struct statfs).f_frsize which is available since Linux 2.6. * m4/fsusage.m4 (STAT_STATFS2_FRSIZE): Always define when the member is available so it can be used as a fallback. * doc/posix-functions/statvfs.texi: Mention the hang issue on Linux < 2.6.36. --- ChangeLog | 11 +++++++++++ doc/posix-functions/statvfs.texi | 5 +++++ lib/fsusage.c | 11 ++++++++++- m4/fsusage.m4 | 31 +++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 12c39f62e..aeb3cf8d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2012-05-15 Pádraig Brady + + fsusage: fix block size returned on older Linux 2.6 + + * lib/fsusage.c: Fall back to (struct statfs).f_frsize + which is available since Linux 2.6. + * m4/fsusage.m4 (STAT_STATFS2_FRSIZE): Always define + when the member is available so it can be used as a fallback. + * doc/posix-functions/statvfs.texi: Mention the hang issue + on Linux < 2.6.36. + 2012-05-14 Paul Eggert bootstrap: suppress stderr chatter diff --git a/doc/posix-functions/statvfs.texi b/doc/posix-functions/statvfs.texi index 6d312618b..558bb3ac3 100644 --- a/doc/posix-functions/statvfs.texi +++ b/doc/posix-functions/statvfs.texi @@ -16,6 +16,11 @@ Portability problems not fixed by Gnulib: This function is missing on some platforms: MacOS X 10.3, OpenBSD 3.8, mingw, MSVC 9. @item +This function can hang if it stats all preceding +entries in /proc/mounts, and any of those file systems +are hard-mounted and not available. This affects +Linux < 2.6.36. +@item On platforms where @code{f_blocks} in @samp{struct statvfs} is a 32-bit value, this function may not work correctly on files systems larger than 4 TiB. The fix is to use the @code{AC_SYS_LARGEFILE} macro. This affects diff --git a/lib/fsusage.c b/lib/fsusage.c index 539f1a9a8..1e35d30e7 100644 --- a/lib/fsusage.c +++ b/lib/fsusage.c @@ -217,7 +217,16 @@ get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp) fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize); -#elif defined STAT_STATFS2_BSIZE /* glibc/Linux, 4.3BSD, SunOS 4, \ +#elif defined STAT_STATFS2_FRSIZE /* 2.6 < glibc/Linux < 2.6.36 */ + + struct statfs fsd; + + if (statfs (file, &fsd) < 0) + return -1; + + fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_frsize); + +#elif defined STAT_STATFS2_BSIZE /* glibc/Linux < 2.6, 4.3BSD, SunOS 4, \ MacOS X < 10.4, FreeBSD < 5.0, \ NetBSD < 3.0, OpenBSD < 4.4 */ diff --git a/m4/fsusage.m4 b/m4/fsusage.m4 index f87834eeb..90b41dfb9 100644 --- a/m4/fsusage.m4 +++ b/m4/fsusage.m4 @@ -128,6 +128,37 @@ if test $ac_fsusage_space = no; then fi fi +# Check for this unconditionally so we have a +# good fallback on glibc/Linux > 2.6 < 2.6.36 +AC_MSG_CHECKING([for two-argument statfs with statfs.f_frsize member]) +AC_CACHE_VAL([fu_cv_sys_stat_statfs2_frsize], +[AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif +#ifdef HAVE_SYS_VFS_H +#include +#endif + int + main () + { + struct statfs fsd; + fsd.f_frsize = 0; + return statfs (".", &fsd) != 0; + }]])], + [fu_cv_sys_stat_statfs2_frsize=yes], + [fu_cv_sys_stat_statfs2_frsize=no], + [fu_cv_sys_stat_statfs2_frsize=no])]) +AC_MSG_RESULT([$fu_cv_sys_stat_statfs2_frsize]) +if test $fu_cv_sys_stat_statfs2_frsize = yes; then + AC_DEFINE([STAT_STATFS2_FRSIZE], [1], +[ Define if statfs takes 2 args and struct statfs has a field named f_frsize. + (glibc/Linux > 2.6)]) +fi + if test $ac_fsusage_space = no; then # glibc/Linux, MacOS X, FreeBSD < 5.0, NetBSD < 3.0, OpenBSD < 4.4. # (glibc/{Hurd,kFreeBSD}, FreeBSD >= 5.0, NetBSD >= 3.0, -- 2.11.0