バグの修正と、EMLINK に対応2006年09月14日 10時18分44秒

バグが見つかった。fision-20060913.tar.bz2 を公開。まだ、開発版なのは相変わらず。


inode_x* find_inode(domain_x *domain, ino_t st_ino)
{
    inode_x *inode = domain->inode;
    while(inode != NULL)
        if(st_ino == inode->st_ino)
           return inode;
        else
           inode = inode->next;
    return NULL;
}

ファイルの内容は i-node 毎にまとめて保持しているのだが、inode->st_ino を設定するのを忘れていた。かなり、ショックなバグだ。構造体を分割していた時に忘れたのだろう。テストは何回も繰り返したが、問題は表面化しなかった。*inode は calloc で割り当てられるため、st_ino がゼロになっている。もし、i-node がゼロのファイルがあったら、危険なことになる。それ以外の問題としては、同じ i-node のファイルも何度も読み込むことだ。ただ、実験したときの様子だと、少なくても cache はよく効いていたらしい。

また、「実運用していて分かったのは、同じファイルがそこかしこに存在する場合にハードリンク作りすぎてEMLINKで失敗しちゃう可能性があるって事ですな。」との助言を頂いたので、-m link_max のオプションを追加した。-m でこのプログラムが作成するハードリンクの上限を指定する。

FreeBSD では EMLINK の上限は LINK_MAX によって制限されている。他の UNIX でも同じ様だ。なぜ、このように -m link_max を指定するかというと、LINK_MAX までハードリンクを作ると、その後にやる pdumpfs 等で悲惨な事になることが容易に予想できるからだ。-m link_max の初期値は LINK_MAX から適当に算出している。

現時点での副作用としては、ディレクトリの走査の順によっては、この上限以上のファイルがリンクされている時に、このリンクの数が変更されることである。

分かりづらいので例を上げる。A、B、C という同一の inode をファイルがあるとする。そして、a という i-node は違うが、内容は同じファイルがあるとする。-m2 を使うと、最大の i-node 数は 2 ということになる。そのため、A B C a の順で走査すると、B と C は同じ i-node の為に無視し、A と a をハードリンクを試みようとするが、既に A の st_nlink は 3 なので、結果的に何もしない。逆に a A B C の場合は、A を a のリンクにする。そして、a と B を比べたときに同一の内容だと判断するが、既に a の st_nlink が 2 になるためにハードリンクは行なわない。

これに関しては、どの様な動作がいいのか、もう一度考え直す必要がある。他にも、デバッグの出力を調整を始めたが、まだ終わっていない。

前回次回不具合が見つかっています。このバージョンは使わないで下さい。追記

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://uyota.asablo.jp/blog/2006/09/14/523396/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。