From: Pádraig Brady
Date: Tue, 15 May 2012 11:52:36 +0000 (+0100)
Subject: fsusage: fix block size returned on older Linux 2.6
X-Git-Tag: v0.1~669
X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=b1fac377605c0eef8844fc8d3818d360f37d6fa4;p=gnulib.git
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.
---
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,