df とか du とか

仕事オーダで df だの du (ls) だのな調査依頼あり。優先度低めで対応せざるを得ないんですが、そう言いつつなんとなく色々確認中。
とりあえずそれらの根拠を確認してはいたんですがメモ取ってなかったので再確認。

df が statfs() 使ってる根拠なメモ

coreutils-5.97 より。get_fs_usage() 手続きにて statfs() を呼び出している模様。
df.c を main() から手繰って get_fs_usage() 手続きの呼び出しを確認。

main()
  show_entry()
    show_disk()
      show_dev()
        get_fs_usage() // lib/fsusage.c にて定義

または

main()
  show_all_entries()
    show_dev()
      get_fs_usage()

となっている。
又、get_fs_usage() 内は ifdef の嵐になってるので何が define されてるかを確認する必要あり。src 配下を grep 'STAT_STAT' * してみたところ、以下な模様。
# grep 出力の一部のみ

config.h:#define STAT_STATFS2_BSIZE 1
config.h:/* #undef STAT_STATFS2_FSIZE */
config.h:/* #undef STAT_STATFS2_FS_DATA */
config.h:/* #undef STAT_STATFS2_OSF1 */
config.h:/* #undef STAT_STATFS4 */
config.h:/* #undef STAT_STATVFS */

上記より get_fs_usage() は以下の部分が有効と思われる。

#ifdef STAT_STATFS2_BSIZE	/* 4.3BSD, SunOS 4, HP-UX, AIX */

  struct statfs fsd;

  if (statfs (file, &fsd) < 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);

# ifdef STATFS_TRUNCATES_BLOCK_COUNTS

  /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
     struct statfs are truncated to 2GB.  These conditions detect that
     truncation, presumably without botching the 4.1.1 case, in which
     the values are not truncated.  The correct counts are stored in
     undocumented spare fields.  */
  if (fsd.f_blocks == 0x7fffffff / fsd.f_bsize && fsd.f_spare[0] > 0)
    {
      fsd.f_blocks = fsd.f_spare[0];
      fsd.f_bfree = fsd.f_spare[1];
      fsd.f_bavail = fsd.f_spare[2];
    }
# endif /* STATFS_TRUNCATES_BLOCK_COUNTS */

#endif /* STAT_STATFS2_BSIZE */

これで df の statfs() 使用は確定と見て OK?
# ちなみに configure は linux 端末で実行してます

du の場合

これもコールグラフ作ってみる。

main()
  du _files()
    fts_read()

上記、fts_read() 内にて fts_stat() 手続きの呼び出しがある模様だが詳細不明。 一応 fts_stat() 手続き内で stat() 呼び出しは行なっている。
こちらはもう少しきちんと精査が必要。