Subject: bug#9140: Coreutils Bug on OSX 10.7 (Lion)

From: Bruno Haible <[email-masked]>
Date: Sat, 23 Jul 2011 15:53:57 +0200

Paul Eggert wrote:
> Subject: [PATCH 3/3] fsusage: port to MacOS X 10.7 with 4 TiB file systems
> 
> * m4/fsusage.m4 (gl_FILE_SYSTEM_USAGE): Reject statvfs
> implementations that use only 32 bits to count blocks.

But this change has also effects on other platforms than MacOS X 10.7:

- On glibc/Hurd, the type of f_blocks in 'struct statvfs' is __fsblkcnt64_t or
  __fsblkcnt_t, depending on __USE_FILE_OFFSET64.
  So fsusage.m4 ought to require AC_SYS_LARGEFILE.

- On MacOS X 10.5, the type of f_blocks is fsblkcnt_t, which is
  'unsigned int'. The configure test therefore now fails, STAT_STATFS2_BSIZE
  gets defined to 1, and fsusage.c calls statfs() instead of statvfs().
  And 'struct statfs' contains a f_blocks that has 64 bits if and only if
  __DARWIN_64_BIT_INO_T is defined.
  So fsusage.m4 ought to require AC_SYS_LARGEFILE, and a module dependency
  to 'largefile' is needed, so that it picks up your new AC_SYS_LARGEFILE code.

- On FreeBSD 6.4, NetBSD 3.0..5.0, OpenBSD 4.9, the type of f_blocks is
  fsblkcnt_t, which is already a 64-bit integer.
  So these platforms continue to use statvfs().

- On AIX 5.1..7.1, the type of f_blocks is fsblkcnt_t, which is 'unsigned long',
  hence usually 32-bit. The configure test therefore now fails,
  STAT_STATFS2_BSIZE gets defined to 1, and fsusage.c calls statfs() instead of
  statvfs(). But statfs() has a 'fsblkcnt_t f_blocks' as well, so the switch
  from statvfs() to statfs() buys us nothing.
  What would bring something (on AIX >= 5.2) is to use statvfs64 or statfs64,
  which both have a 64-bit f_blocks field.

- On HP-UX 11.00..11.31, the type of f_blocks is fsblkcnt_t, which is 64-bit
  if and only if _APP32_64BIT_OFF_T is defined. By default it is 32-bit, hence
  the configure test therefore now fails, STAT_STATFS2_BSIZE gets defined to 1,
  and fsusage.c calls statfs() instead of statvfs(). But statfs() has an
  'int32_t f_blocks', so the switch from statvfs() to statfs() buys us nothing.
  What would bring something is to define _FILE_OFFSET_BITS to 64, which has
  the effect of enabling _APP32_64BIT_OFF_T. Or alternatively, define
  _LARGEFILE64_SOURCE and use statvfs64 instead of statvfs.

- On IRIX 6.5, the type of f_blocks is fsblkcnt_t, which is already a 64-bit
  integer, so these platforms continue to use statvfs(). One could define
  _LARGEFILE64_SOURCE and use statvfs64, but that appears to be not necessary.

- On Solaris 7..10, the type of f_blocks is fsblkcnt_t, which is 64-bit in
  64-bit mode builds (_LP64) or if _FILE_OFFSET_BITS is 64. By default it
  usually is 32-bit, the configure test therefore now fails, STAT_STATFS4
  gets defined to 1, and fsusage.c calls statfs() instead of statvfs().
  But statfs() has a 'long f_blocks', so the switch from statvfs() to statfs()
  buys us nothing.
  What would bring something is to define _FILE_OFFSET_BITS to 64.

- On Cygwin (both 1.5.x and 1.7.5), the type of f_blocks is fsblkcnt_t, which
  is 'unsigned long', that is, 32-bit. The configure test therefore now fails,
  STAT_STATFS2_BSIZE gets defined to 1, and fsusage.c calls statfs() instead of
  statvfs(). But statfs() has a 'long f_blocks', so the switch from statvfs()
  to statfs() buys us nothing.
  I don't see an API that supports 64-bit f_blocks on Cygwin.

- On Interix 3.5, the type of f_blocks is 'unsigned long', which is 32-bit.
  The configure test therefore now fails, and I don't know which API gets used
  instead: Interix has no statfs. So it appears the patch is killing
  portability to Interix.

- On BeOS and Haiku, the type of f_blocks is fsblkcnt_t, which is 'long long',
  i.e. 64-bit, so these platforms continue to use statvfs().

I will therefore propose

1) To require AC_SYS_LARGEFILE, and a module dependency to 'largefile'.
   This will make statvfs() use a 64-bit f_blocks on
   glibc/Hurd, MacOS X >= 10.4, HP-UX, Solaris.

2) To undo the patch that introduces check_f_blocks_size, because
     - on MacOS X 10.7 it is not needed any more after 1),
     - on AIX and Cywin it causes non-POSIX API to be used for no reason,
     - it kills portability to Interix 3.5.

3) To make use of statvfs64 on AIX.

Bruno
-- 
In memoriam Adam Czerniaków <http://en.wikipedia.org/wiki/Adam_Czerniaków>