ℹ️本記事は古いコンテンツを変換して表示しています。
表示が崩れたり、リンクが正しくない可能性があります。ご了承ください。
ℹ️本記事は古いコンテンツを変換して表示しています。
表示が崩れたり、リンクが正しくない可能性があります。ご了承ください。
2016/12/31 08:12 : panic: ufs_direnter: compact2
この前から続けてunionfsをいじってたらpanicにやられた。panicの中身からは分かりづらかったけど、VOP_CREATE
に先んじてVOP_LOOKUP
を呼んでいなかったことが問題らしい。
1ヶ月以上はまっていたので記録を残しておくことにした。きっと誰の役にも立たないけど。
この前から続けてunionfsをいじってたらpanicにやられた。panicの中身からは分かりづらかったけど、VOP_CREATE
に先んじてVOP_LOOKUP
を呼んでいなかったことが問題らしい。
1ヶ月以上はまっていたので記録を残しておくことにした。きっと誰の役にも立たないけど。
panic時のbacktraceはこんな感じ。
kdb_backtrace+0x8d vpanic+0x1df kproc_shutdown+0 ufs_direnter+0xbb2 ufs_makeinode+0x786 ufs_create+0x4a VOP_CREATE_APV+0x16b VOP_CREATE+0x51 (以下略)
ufs_direnter
はsys/ufs/ufs/ufs_lookup.cで定義されていて、panicの条件はこうなっている。
if (spacefree < newentrysize) panic("ufs_direnter: compact2");
ファイルを作る場合は、新しいファイルそのものに対応するエントリを生成するほか、それを配置するディレクトリも更新する。ディレクトリの更新を行っているのがufs_direnter
。そしてspacefree
はinode(?)の空き領域、newentrysize
は更新後の書き込みたいディレクトリ情報のサイズを表す。
さて、普通のメモリの管理(mallocとか)を考えると、newentrysize
を格納できる空き領域を探す処理があって、続けてその領域を使う(使用中フラグを立てるとか)処理があるはずだ。しかし、ufsの場合この2つは遠く離れていて、前者がufs_lookup_ino
(ufs_lookup
)をCREATEモードで呼んだ場合、後者がufs_direnter
にいる。
ufsのコードはまだあまり読んでないので、正直なところ理由は良く分からない。とにかく、正しくVOP_LOOKUP
を呼ばないでVOP_CREATE
すると、楽しくないことが起きるということだ。
ちなみに、過去にunionfsで似たようなバグがあった模様。(FreeBSD unionfsの改善提案および修正状況のpatch13)unionfsはrename時にファイルを生成する場合がある。が、その後再度VOP_LOOKUP
をせずにVOP_RENAME
していたのが問題らしいように見える。LOOKUP
し忘れたという意味では完全に同じ事象といえる。