IO#statfs and File::Statfs

Issue #9772 has been updated by Motohiro KOSAKI.

2014-04-24 19:11 GMT-04:00 [email protected]:

Issue #9772 has been updated by Akira T…

こういうときは先人の知恵ということで探してみると coreutils の src/stat.h になにかそれっぽいコメントがありました。

 212 /* Return the type of the specified file system.
 213    Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, 

and Solaris).

214 Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0).
215 Others have statfs.f_fstypename[MFSNAMELEN] (NetBSD 1.5.2).
216 Still others have neither and have to get by with f_type
(GNU/Linux).
217 But f_type may only exist in statfs (Cygwin). */



http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/stat.c;h=7d43eb55510372e18cc1129db269586710d28229;hb=HEAD#l212

仮に proprietary なのは気にしないとしても、NetBSD はどうなのかなぁ。

ああ、statvfsにメンバ追加のほうが世の中で主流なのですね。じゃあ、わたしの主張は取り下げます


Feature #9772: IO#statfs and File::Statfs

  • Author: Yui NARUSE
  • Status: Assigned
  • Priority: Normal
  • Assignee: Yukihiro M.
  • Category:
  • Target version:

IO#statfs and File::Statfs を追加しませんか。
(テストで statfs.f_type が必要だったのでとりあえず追加してしまっていますが)

statfs(2) は Unix 系 OS
でそこそこ普及している、あるパスが属するファイルシステムについての情報を得るためのシステムコールです。
OS によって多少差がありますが、だいたい以下の様な情報が得られます。

 struct statfs {
 uint32_t f_type;                /* type of filesystem */
 uint64_t f_bsize;               /* filesystem fragment size */
 uint64_t f_blocks;              /* total data blocks in filesystem 

/
uint64_t f_bfree; /
free blocks in filesystem /
int64_t f_bavail; /
free blocks avail to
non-superuser /
uint64_t f_files; /
total file nodes in filesystem
/
int64_t f_ffree; /
free nodes avail to
non-superuser /
char f_fstypename[MFSNAMELEN]; /
filesystem type name */
};

f_type の値が OS 依存だったり、Linux 以外だとそもそもどれがどの値かきちんと定義されていないとか
ツッコミどころの多い API ではあるのですが、他では得られない情報が得られます。

たとえば、以前から CRuby で使われている用途としては、あるファイルの乗っているファイルシステムが、
HFS+ かどうかがわかります。言い換えると、ファイル名が正規化されているかどうかがわかります。
ありがちな反論として、書き込めば正規化されるかわかるだろうというのがありえますが、
目当てのファイルと同じディレクトリに書き込めるとは限りません。
違うディレクトリだと別のファイルシステムがマウントされている可能性があります。

なお今回の用途は、SEEK_DATA/SEEK_HOLEができるか否かを、実際にやってみる以外の方法で知りたかった、というものです。
(Rubyのテストなのにやってみて調べるではテストにあまりならない)