gitでシンボリックリンクを除外することはできないのかなあと思うことがあるのだが,シンボリックリンクは対象ファイルへのパスを書いたファイルみたいなものらしいということを知って,inodeとかdentryについて調べたときのメモ.
inode
Linuxではファイルはディレクトリに整然と並んでいるが,ディスク上やSSD上でもディレクトリの構造を反映してファイルが格納されているわけではない.ディレクトリ上でファイルを移動したとき,その実体のディスク上での位置は依然としてそのままである.
Linuxではinodeと呼ばれる構造体によって,以下の情報を管理している.
- ファイルの種類
- UIDとGID
- パーミッション
- バイト単位のファイルサイズ
- このファイルに割り当てたブロック数
- データブロックへのポインタ(ファイルの中身が書き込まれている)
詳細
SSDやHDDがどのように管理されているかについての詳細.ディスクの先頭には「ブートブロック」があり,その次に「スーパーブロック」がある.これは
- i-nodeテーブルのサイズ
- 論理ブロック数
- 論理ブロックサイズ
などの情報を保持している.i-nodeの個数の上限は決め打ちされており,
$ df -i
で確認できる(いくらデバイスに空きがあっても,これ以上の個数のファイルとディレクトリは作成できない).
その次にi-nodeテーブルの実体と,データブロックが続く.inode番号はinodesテーブルのエントリーの主キーであり,スーバーブロックのサイズなどもハードコードされているため,任意の番号のinodeのディスク上での位置を直接求められる(?).
dentry
Linuxにおけるディレクトリは以下のような情報などを格納した dentry
という構造体である.
struct inode* d_inode
このdentryのinodeエントリーへのポインターstruct qstr
このディレクトリの名前(多分1回層だけ?)struct list_head d_subdirs
サブディレクトリdentryのリストへのポインターstruct dentry* d_parent
親ディレクトリのdentryへのポインター
例として /
のinodeを0として, /home/hoge/Download/dl.png
のinodeを解決してみる.
- まず
/
のinodeは0だからinodes[0]
を参照する.そこには/
のブロックへのポインターがあり,それを参照すると/
のdentryを得る. - その中のサブディレクトリのリストのポインターを得る.
- その中に名前が"home"のものがあるか探す.見つかったら(それはdentryへのポインタなので)そのinodeを参照する.そこには
/home/
のブロックへのポインターがあるから,それを参照すると/home/
のdentryを得る. - その中のサブディレクトリのリストのポインターを得る.
- その中に名前が"hoge"のものがあるか探す.見つかったらその(それはdentryへのポインタなので)そのinodeを参照する.そこには
/home/hoge/
のブロックへのポインターがあるから,それを参照すると/home/hoge/
のdentryを得る. - その中のサブディレクトリのリストのポインターを得る.
- その中に名前が"Download"のものがあるか探す.見つかったらその(それはdentryへのポインタなので)そのinodeをを参照する.そこには
/home/hoge/Download
のブロックへのポインターがあるから,それを参照すると/home/hoge/Download
のdentryを得る. dl.png
が見つかる.
おそらくこういった感じで解決が可能だと思う(?).
ハードリンク
ハードリンクはあるinode番号を持つリソースに,別名のファイル名を持たせたdentryである.
ln original.txt alias.txt
これはoriginal.txt
のハードリンクalias.txt
を作成したことになるが,alias.txt
はoriginal.txt
と同一のinode番号を持っている.
rmコマンドの意味
inodeは参照カウントを持っている.そしてあるファイルをrmすると対応するinode番号のinodeの参照カウントがデクリメントされる.上の例では
rm original.txt
してもまだalias.txt
は残っているし,もちろんディスク上の実体も残っている.このようにrmコマンドはディレクトリエントリーを消去するだけであり,ディスク上の実体は消去しない.そのため使用中のファイルも(形式上)rmできる.inodeを参照するプロセスがなくなるまでファイルの実体の消去は遅延される.
遅延書き込み
dirtyリストの管理とかLRUとか.