Linuxファイルシステムは、いかにしてディレクトリの内容を列挙するのか

ちょっと調査する必要に迫られまして。

まずはlsのソースコードから…… と思ったがlsのソースが見つからなかったのでやめ(しょぼい)

linuxのシステムコール/ライブラリルーチンをざっと眺めますと、opendir()というのが目に付きます。調べてみたところどうやらopendir,readdirで指定したディレクトリ内のファイルを列挙できる(参照)ということで、ここから追っていきましょう。

opendir,readdirのつかいかたですが、まずopendir()でDIRをゲット。それを引数にreaddir()を呼ぶたびに対象ディレクトリ内にあるファイルをdirent形式でひとつづつ返してくれます。

てきとーにぐぐってみると、opendir()の中身はopen()で、readdir()のほうではsys_getdentsでディレクトリエントリを取得しているもよう。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/getdents.2.html
これはあなたが興味を持つような関数ではないと言いながらちゃんと解説してあってしかも日本語訳までされているツンデレ感に萌えますね。

int getdents(unsigned int fd, struct dirent *dirp, unsigned int count);

こいつにopen()で取得したファイルデスクリプタを渡してやるとdirpになんか設定されると。
direntの中身はこんな。

struct dirent
{
    long d_ino;                 /* inode number */
    off_t d_off;                /* offset to next dirent */
    unsigned short d_reclen;    /* length of this dirent */
    char d_name [NAME_MAX+1];   /* filename (null-terminated) */
}

おっとここでinodeが登場。このへんを理解するために、Linuxファイルシステムを調べておこう。

http://www.linux.or.jp/JF/JFdocs/The-Linux-Kernel-10.html
linuxはいくつかのファイルシステムに対応している(ext2,vfat,iso9660,etc.)。これらを統一して扱うため、VFS(Virtual File System)というレイヤーがある。VFSアーキテクチャext2と似ていてinodeベースでファイルを管理する。inodeはファイルと一対一対応している。



で、getdentsを読んでみる。渡されたファイルデスクリプタからstruct fileをつくり、vfs_readdirを呼んでいるだけですね。


vfs_readdirでは、file->f_op->readdir()を呼んでいるだけのようですね。この先はファイルシステム依存、と。

えー、予想外の結果になってしまった。ファイル列挙はVFSのレイヤで完結してると思ってたのに……

とりあえずext2readdir()を追ってみましょう。
ギャー!いきなり難易度が上がった気がしますよ。とにかくこの階層が終着点であることは間違いなさそうなのですが(つづかない)