- kosaki55tea
- 63558
- 0
- 52
- 16
inotifyのIN_MODIFYみたいに、親に何かを通知したい場合に dentry の d_parent 使ってるけど、これってハードリンクされてたらどうなんの?
2013-06-26 20:03:26Linuxのinotifyは最初からdentry(BSDのnamecacheに相当)のd_parentを頼りにしてるので、何も考えてない感じ。ハードリンク何ソレ、よねこれ
2013-06-27 17:10:19inotifyで変更を監視する、みたいな話があるけど、ハードリンクがあると容易に検出漏れするわけだが、本当にそんなんでいいのか。
2013-06-28 15:17:09うん、 mkdir a b touch a/foo ln a/foo b/ して inotifywait -m -e modify a した状態で echo foo >> a/foo は検出するが echo foo >> b/foo は検出しない、という結果になりました
2013-06-28 15:56:03inotify(7)のどこにも「dentryベースの追跡なのでハードリンクしてると漏れる」みたいな注意がされてないけど、それでいいんかねえ
2013-06-28 15:59:20まあ、inode/vnodeベースの追跡ってのは、たとえばNFSなんかではstatdあたりにそのための機能を入れないといけなかったりするけど。
2013-06-28 16:06:21kqueueでNFSの監視とかどうしてるんだ、と思って nfs/nfs_kq.c を見たら nfs_kqpoll で「NFS_MINATTRTIMO/2秒(=2.5秒)ごとにポーリングするよ」とか書いてあって頭を抱えた
2013-06-28 16:13:50@AoiMoe CentOS6でも同じ結果だた。ソースを見ると inotifyはinodeで追跡してるように見えるので、さて原因はなんだろう
2013-06-28 16:17:06a/foo に対する書き込みがあると、 (1)writeシステムコールからfooのfileに対してfsnotify_modifyが呼ばる (2)fooのdentryにdget_parentしてaのdentryを取ってきて、こいつに通知する ってコードに見える
2013-06-28 16:27:10@AoiMoe あれ、fsnotify()のほうが本体だという認識だったのですが。勘違いだったかな
2013-06-28 16:38:15@kosaki55tea そっちは、さっきの例でいえば a/foo 自体のフックに通知する関数ですね。a/foo に対するイベントを a のフックに通知するところで、dentry 使ってヒエラルキーをさかのぼってる
2013-06-28 16:41:33@AoiMoe ああ、inotifywaitの引数が a/foo じゃなくて a/ だった。見落としてた。すいません
2013-06-28 16:43:41んー、というわけなので、kqueue的には、EVFILT_VNODEの「identがfdなので以下略」問題だけを解決して、変更の監視をしたいなら全部のファイルを明示的に見るようにしろ、でいいような気がしてきたがどうでしょう
2013-06-28 16:52:27BSD的には、真面目にやるなら新しいVOP追加して、ディレクトリにフックかけたときにdirentなめてinoテーブル見て以下略とかすることになるぜよ。
2013-06-28 16:57:41新しいVOP追加するまでもなくVOP_KQFILTERで頑張ればいいのか。いずれにしても頑張る羽目になるわけだが。
2013-06-28 17:02:11@AoiMoe inotify(7)エミュレーションは諦めるってことですね。ちょっと影響でかすぎるので、それかなあ。ディスクリプタのリミットも「広げろ!」でもいいのかも。Linuxでも fs.inotify.max_user_watches (8192)の制限はあるわけで
2013-06-28 17:03:17