Mímisbrunnr知恵の泉

← コンピュータ基礎 一覧

🎓 レベル:標準 | 重要度:A(必須)

📎 前提:OSの役割とカーネル | 関連:ディスクとストレージ階層バッファリング・キャッシュ・ジャーナリング

要点(BLUF)

概念 ── ディスクは「番号付きブロックの集まり」

ストレージ(ディスクとストレージ階層)は物理的には、固定サイズのブロック(典型4KB)に番号を振った巨大な配列です。「ファイル」「フォルダ」という概念はそこにありません。それをユーザに見せるのがファイルシステムの仕事(OSの役割とカーネル の抽象化)。

中核データ構造が inode(index node)。1ファイルに1つ対応し、次を持ちます。

注目すべきは、inodeにファイル名が入っていないこと。名前は別管理(ディレクトリ)です。

仕組み① ── 直接・間接ブロック(マルチレベルインデックス)

ファイルは小さいものも巨大なものもあります。inodeのポインタを全ファイル分の最大数だけ持つのは無駄。そこで階段状のインデックスを使います(古典Unix系の例)。

flowchart LR
    inode["inode"] -->|"直接 x12"| d["データブロック(直接)"]
    inode -->|"単間接 x1"| s["ポインタブロック"] --> sd["データブロック群"]
    inode -->|"二重間接 x1"| dd1["ポインタブロック"] --> dd2["ポインタブロック群"] --> dddata["データブロック群"]
    inode -->|"三重間接 x1"| t["…さらに1段深い…"]

この設計の最大ファイルサイズを計算します([[#対応ラボ]] の 05-01_inode_capacity.py。ブロック4KB・ポインタ4バイト=1ブロックに1024ポインタ)。

BLOCK, PTRS = 4096, 4096//4          # 1ブロックに1024ポインタ
total = (12 + PTRS + PTRS**2 + PTRS**3) * BLOCK

実行結果(実機):

直接(12)  :             12 ブロック ->         0.00 GB
単間接     :          1,024 ブロック ->         0.00 GB
二重間接    :      1,048,576 ブロック ->         4.00 GB
三重間接    :  1,073,741,824 ブロック ->      4096.00 GB
表せる最大ファイルサイズ = 約 4.00 TB

容量のほとんどを三重間接が稼ぐ一方、ほとんどのファイルは小さく直接ポインタだけで完結します。10KB のファイル -> 3 ブロック(直接で足りる)。つまりよくある小ファイルは速く、稀な巨大ファイルも表せるという、頻度に応じた賢い非対称設計です。

仕組み② ── ディレクトリは対応表

ディレクトリも実体はファイル(専用のinodeを持つ)で、中身は**「ファイル名 → inode番号」のエントリの並び**です。

flowchart LR
    dir["ディレクトリ(/home/zack)"] -->|"'memo.txt' -> inode 1287"| i1["inode 1287(メタ+ブロック)"]
    dir -->|"'photo.jpg' -> inode 9041"| i2["inode 9041"]

パス /home/zack/memo.txt を開く流れ:ルート / のinode → その中で home のinode番号を引く → home の中で zackzack の中で memo.txt のinode番号 → そのinodeのブロックを読む。名前解決はディレクトリを辿るルックアップの連鎖です。

名前とinodeが分離しているので、1つのinodeに複数の名前を付けられます(ハードリンク:別々のディレクトリエントリが同じinode番号を指す)。inodeの「リンク数」が0になって初めて実データが解放されます。rm がファイルでなくリンクの削除である理由がこれです。

仕組みの直観 ── なぜこの設計か

⚠️ よくある誤解・落とし穴

対応ラボ

cs-foundations-study/labs/05-01_inode_capacity.py(実行して最大ファイルサイズと小ファイルのブロック数を確認済み)。labs/05-01_inode_observe.md に Linux の stat/ls -i/ln でinode番号とリンクを観察する手順。

関連

第5章 ファイルシステムとI/O 目次