vfs | |
普通に下層レイヤのlookup関数を呼び出せばいい気がするけれど、どうも駄目らしい。
static struct dentry *myiop_lookup(struct inode *dir, struct dentry *dentry, struct nameidata nd)
このとき、dirは存在するファイルを指しているので、データは全て設定されている。
dentryは、d_alloc()直後に渡されているので、探索するファイル名など最低限のものだけが設定されている。だから下層レイヤのlookupを呼び出すためには、下層レイヤのdentryの確保やエラーチェックなどを行う必要がある。それを行う関数がlookup_one_len()ということになる。
実際、lookup_one_len() → __lookup_hash() → i_op->lookup() と順に呼び出されている。
で、ちょっと気になったのが
では次に、NFS マウントしたディレクトリの上に重ねあわせを行なってみる。残念なことに現在の Linux カーネルのパス名ルックアップ関数 lookup_one_len には、少々問題があるらしい。この関数は引数のファイル名からハッシュ値を算出し、ファイルシステムのハッシュリストを検索して、ファイル名に対応する dentry 構造体を返すのであるが、その際、そのファイルに至るディレクトリの dentry 構造体の参照カウンタを +1 してしまう。この挙動が NFS に混乱をもたらす (らしい ^^;)。
NFS に影響を及ぼさない形で参照カウンタを元に戻すには、 nameidata 構造体を独自に設定した上でルックアップを行なう必要があるが、現在の Linux カーネルにはそのようなインタフェースが無い。そこで aufs では、カーネル内の関数を一つ (__lookup_hash 関数) モジュールから呼び出せるようにするべく、 EXPORT_SYMBOL(__lookup_hash) するパッチ (lhash.patch) をあてている。このパッチをあててカーネルを再構築した後に、 aufs の AUFS_LHASH_PATCH オプションを y に設定すればよい。
http://blog.gcd.org/archives/51063220.html
この記事。
ソースを見ても参照カウンタを上げているところが見つからない。もしかしてバージョンが古いのか?と思ってkernel2.6.24をダウンロードしてみた。lookup関連の関数が増えているが、基本的な動作は変わっていないと思う。
そもそもVFSの中で、__lookup_hash()にnameidataをNULLで渡している。これもよくわからない。そんなことして大丈夫なの?
一応aufsのソースも流し読みしたけど、こっちは複雑でぱっと見じゃ分からなかった。
取り敢えず保留にしてlookup_one_lenを使うことにする。
もしかしてd_alloc()で確保したときのことを指しているんだろうか?でもそれは__lookup_hash()関数の中で行われているから、lookup_one_len()を使わなかったとしても関係ない。と思う。わからん・・。