2つopenしたときにリンクカウントがどうなるか試してみた。
FreeBSD UFS2の場合:
koie@guriandgura% uname -sr
FreeBSD 9.0-CURRENT
koie@guriandgura% cat -n test.sh
1 #!/bin/sh
2 mkdir d || exit 1
3 cd d || exit 1
4
5 touch file
6
7 sleep 10 >>file &
8 sleep 1
9 ls -li file
10
11 sleep 10 >>file &
12 sleep 1
13 ls -li file
14
15 wait
16
17 cd .. || exit 1
18 rm -r d
koie@guriandgura% sh -x test.sh
+ mkdir d
+ cd d
+ touch file
+ sleep 10
+ sleep 1
+ ls -li file
33552 -rw-r--r-- 1 koie wheel 0 2月 18 00:26 file
+ sleep 10
+ sleep 1
+ ls -li file
33552 -rw-r--r-- 1 koie wheel 0 2月 18 00:26 file
+ wait
+ cd ..
+ rm -r d
koie@guriandgura%
Linux ext3の場合:
$ uname -sr Linux 2.6.18-164.11.1.el5 $ sh -x test.sh + mkdir d + cd d + touch file + sleep 10 + sleep 1 + ls -li file 19170211 -rw-rw-r-- 1 koie koie 0 Feb 18 00:33 file + sleep 10 + sleep 1 + ls -li file 19170211 -rw-rw-r-- 1 koie koie 0 Feb 18 00:33 file + wait + cd .. + rm -r d $
2つopenしたからといってリンクカウントが3にはならず1のまま。もしopen/closeのたびにリンクカウントを更新したとするとinodeのアップデートが頻発してパフォーマンスに問題がでるだろう。可能性としてはatime/mtimeのようにすぐに更新しないという戦略で逃げているかもしれない。
inodeを消すかはdinodeのlinkcountとvnodeのrefcountが両方0になったときだと予想。
$ mkdir d $ ls -lid d 19170210 drwxrwxr-x 2 koie koie 4096 Feb 18 00:42 d/ $ cd d $ ls -lid . 19170210 drwxrwxr-x 2 koie koie 4096 Feb 18 00:42 ./ $ rmdir . rmdir: .: Invalid argument $ rmdir ../d $ ls -lid . 19170210 drwxrwxr-x 0 koie koie 0 Feb 18 00:42 ./ $
リンクカウント0のディクトリができて、参照できることからinodeは消されてないことがわかる。















実際に削除する時の判断はメモリ上のdentry->d_count で行われているようです。dentryはdirectory entry cache です。
確かに高速化を考えて実装すればこのような情報はメモリ上にキャッシュすることになりますよね。
最後の例ではおそらくshellがカレントディレクトリをopenしているので
d_count > 0 になっているのでしょう。