Skip to content
Published on

[オペレーティングシステム] 15. ファイルシステム内部構造

Authors

ファイルシステム内部構造

ファイルシステム実装の基本原理を見た後、実際のファイルシステムの内部構造とパフォーマンス最適化技法をさらに深く解説します。ext4、APFSなど現代のファイルシステムの構造やNFSを含むネットワークファイルシステムも扱います。


1. ファイルシステムのマウント

オペレーティングシステムはファイルシステムを使用する前にマウントする必要があります。マウントとは、ファイルシステムをディレクトリツリーの特定の地点(マウントポイント)に接続することです。

マウント前:                    マウント後:
     / (ルート)                     / (ルート)
    ╱    ╲                       ╱    ╲
  home   mnt                   home   mnt
 ()                │      │
 user1                        user1  ┌──────────────┐
USBドライブ   │
                                      (ext4)                                     │  photos/                                     │  docs/                                     └──────────────┘
                              /mnt/photos でアクセス可能
# 마운트 명령어 예시
# 장치를 마운트 포인트에 연결
mount /dev/sdb1 /mnt

# 특정 파일 시스템 타입 지정
mount -t ext4 /dev/sdb1 /mnt

# 읽기 전용 마운트
mount -o ro /dev/sdb1 /mnt

# 현재 마운트 목록 확인
mount | column -t

# 언마운트
umount /mnt

/etc/fstabファイル

ブート時に自動マウントするファイルシステムを定義します。

# /etc/fstab 예시
# 장치            마운트포인트  타입   옵션            덤프 패스
/dev/sda1         /            ext4   defaults         0    1
/dev/sda2         /home        ext4   defaults         0    2
/dev/sdb1         /data        xfs    noatime          0    2
tmpfs             /tmp         tmpfs  size=2G          0    0

2. パーティションとブロックグループ

ディスクパーティション構造

┌──────────────────────────────────────────────────┐
│                物理ディスク                        │
│                                                  │
│  ┌─────┬────────────┬────────────┬────────────┐  │
│  │ MBRPartition 1Partition 2Partition 3│  │
│  │      (ext4)      (swap)      (ext4)     │  │
│  │     │ /          │            │ /home      │  │
│  └─────┴────────────┴────────────┴────────────┘  │
│                                                  │
GPT (GUID Partition Table):│  ┌─────┬──────┬──────┬──────┬───────┬─────┐     │
│  │ MBRGPT  │Part 1│Part 2...GPT │     │
│  │保護用│ヘッダ│      │      │       │バックアップ││
│  └─────┴──────┴──────┴──────┴───────┴─────┘     │
└──────────────────────────────────────────────────┘

ブロックグループ(ext4)

ext4はディスクを複数のブロックグループに分けて管理します。

┌────────────────────────────────────────────────────┐
│              ext4 ファイルシステムレイアウト          │
│                                                    │
│ ┌──────┬──────────┬──────────┬──────────┬────────┐ │
│ │Group │ Group 0Group 1Group 2...    │ │
│ │  0   │          │          │          │        │ │
│ └──────┴──────────┴──────────┴──────────┴────────┘ │
│                                                    │
│ 各ブロックグループ内部:│ ┌────────┬────────┬────────┬────────┬────────────┐ │
│ │ SuperGroupBlock  │ inode  │ Data       │ │
│ │ BlockDesc.   BitmapTableBlocks     │ │
 (バックアップ)Table+ inode │      │          │ │
│ │        │        │ Bitmap │        │            │ │
│ └────────┴────────┴────────┴────────┴────────────┘ │
└────────────────────────────────────────────────────┘

ブロックグループの利点:

  • 局所性(Locality): 関連データを近くに配置してディスクシークを最小化
  • 並列処理: 異なるブロックグループへの操作を並列で実行可能
  • 信頼性: スーパーブロックとグループディスクリプタのバックアップで復旧可能

3. ext4ファイルシステムの内部構造

ext4はLinuxで最も広く使われているファイルシステムです。

ext4の主要特徴

特性
最大ファイルサイズ16 TiB
最大ボリュームサイズ1 EiB
最大ファイル名長255バイト
最大ディレクトリ深度無制限
ジャーナリングサポート(ordered)
エクステントサポート

エクステント(Extent)ベースの割り当て

ext4は従来の間接ブロックポインタの代わりにエクステントを使用します。

従来の方式(ext2/ext3):         ext4エクステント:
inode → 直接ポインタ 12個       inode → エクステントツリー
     → 単一間接ポインタ
     → 二重間接ポインタ         エクステント: (開始ブロック, 長さ)
     → 三重間接ポインタ         1つのエクステントで連続ブロックを表現

: 100個の連続ブロック          例: 100個の連続ブロック
100個のポインタが必要         → 1つのエクステント (start=50, len=100)
// ext4 익스텐트 구조체 (간단화)
struct ext4_extent {
    uint32_t ee_block;     // 논리 블록 번호
    uint16_t ee_len;       // 블록 수 (최대 32768)
    uint16_t ee_start_hi;  // 물리 블록 상위 16비트
    uint32_t ee_start_lo;  // 물리 블록 하위 32비트
};

// 익스텐트 트리 헤더
struct ext4_extent_header {
    uint16_t eh_magic;     // 매직 넘버 (0xF30A)
    uint16_t eh_entries;   // 유효한 엔트리 수
    uint16_t eh_max;       // 최대 엔트리 수
    uint16_t eh_depth;     // 트리 깊이 (0 = 리프)
    uint32_t eh_generation;
};

ext4の遅延割り当て(Delayed Allocation)

従来の方式:                      遅延割り当て:
write() 呼び出し                 write() 呼び出し
  │                                │
  ├→ ブロック割り当て(即座)       ├→ ページキャッシュにデータ保存
  ├→ ディスクに書き込み            │   (ブロックはまだ未割り当て)
  └→ 完了                         │
                                   ├→ フラッシュ時点
                                   │   ├→ 連続ブロックを一括割り当て
                                   │   └→ ディスクに書き込み
                                   └→ 完了

利点: 連続ブロック割り当ての可能性向上、パフォーマンス向上

4. Apple File System(APFS)

APFSはAppleがHFS+を置き換えるために開発したファイルシステムです。

APFSの主要特徴

┌──────────────────────────────────────────┐
APFSコンテナ                 │
│                                          │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│  │ Volume 1 │ │ Volume 2 │ │ Volume 3 │ │
 (macOS) (Data) (Preboot)│ │
│  └──────────┘ └──────────┘ └──────────┘ │
│                                          │
│  空間共有: ボリュームがコンテナ内の       │
│  空き領域を動的に共有                     │
└──────────────────────────────────────────┘
  • Copy-on-Write(CoW): データ変更時に原本を保存し新しい位置に記録
  • スナップショット: CoWを活用した時点復旧サポート
  • 空間共有: 1つのコンテナ内の複数ボリュームが空間を動的に共有
  • 暗号化: ファイル/ボリュム単位のネイティブ暗号化サポート
  • クローン: ファイル/ディレクトリの即時コピー(メタデータのみコピー、変更時に実際コピー)

Copy-on-Write動作

初期状態:
Block A[Original Data]

変更時(CoW):
Block A[Original Data]  (保存)
Block B[Modified Data]  (新しい位置に記録)
メタデータポインタがBlock Bを指すように更新

スナップショットがある場合:
スナップショット → Block A(原本参照維持)
現在           → Block B(変更版参照)

5. パフォーマンス最適化

バッファキャッシュ(Buffer Cache)

アプリケーション read() 要求
┌──────────────────┐
│   バッファキャッシュ│
│ (カーネルメモリ) │
│                  │
[ブロック42: data]│ ← キャッシュヒット: 即座に返却
[ブロック88: data][ブロック15: data][ブロック7:  data]└────────┬─────────┘
         │ キャッシュミス
    ┌─────────┐
    │ ディスク│ → 読み取り後キャッシュに保存
    └─────────┘

先読み(Read-Ahead)

順次アクセスパターンを検知すると、次のブロックを先に読んでキャッシュに保存します。

要求パターン: ブロック1 → ブロック2 → ブロック3...

ブロック3要求時:
カーネルが順次パターン検知 → ブロック4, 5, 6, 7も先読み

┌────┬────┬────┬────┬────┬────┬────┐
B1B2B3B4B5B6B7│要求│要求│要求│先  │先  │先  │先  │
│完了│完了│返却│読み│読み│読み│読み│
└────┴────┴────┴────┴────┴────┴────┘

Free-Behind

順次読み取り時に使用済みのページをキャッシュから除去してキャッシュ空間を確保します。

順次読み取り進行方向 →

キャッシュ状態:
[B1] [B2] [B3] [B4] [B5]  ← 通常のLRU
 ↑ 古いページもキャッシュに残る

[--] [--] [B3] [B4] [B5]Free-Behind適用
 ↑ 読み取り後すぐ解放 → 新データ用の空間確保

ページキャッシュとバッファキャッシュの統合(Unified Buffer Cache)

過去(分離):                   現在(統合):
┌──────────┐ ┌──────────┐      ┌──────────────────────┐
│ ページ    │ │ バッファ  │      │    統合ページキャッシュ │
│ キャッシュ │ │ キャッシュ │      │                      │
(mmap用)(read用)   │      │  mmapとread/write    │
│           │ │           │      │  が同じキャッシュ使用  │
└──────────┘ └──────────┘      └──────────────────────┘
 同じデータの重複キャッシュ      重複排除、一貫性保証

6. NFS(Network File System)

NFSはネットワークを通じてリモートファイルシステムにアクセスする分散ファイルシステムプロトコルです。

NFSアーキテクチャ

クライアント                       サーバー
┌──────────────────┐            ┌──────────────────┐
│ ユーザープロセス  │            │                  │
open("/mnt/f")  │            │                  │
├──────────────────┤            │                  │
VFS         │            │                  │
├──────────────────┤            ├──────────────────┤
NFSクライアント  │            │  NFSサーバーデーモン│
  (nfsd)          │ ← RPC/XDR →│  (nfsd)├──────────────────┤            ├──────────────────┤
│    ネットワーク   │            │    ローカル       │
    (TCP/UDP)     │            │    ファイルシステム│
└──────────────────┘            └──────────────────┘

NFSマウント

# NFS 서버에서 공유 디렉토리 설정
# /etc/exports
/data  192.168.1.0/24(rw,sync,no_subtree_check)

# NFS 서비스 시작
sudo systemctl start nfs-server

# 클라이언트에서 마운트
sudo mount -t nfs server:/data /mnt/nfs

# /etc/fstab에 추가하여 부팅 시 자동 마운트
# server:/data  /mnt/nfs  nfs  defaults  0  0

NFSのステートレス(Stateless)設計

NFS v3はステートレスプロトコルとして設計されました。

ステートレスの利点:
- サーバークラッシュ後の再起動時にクライアント再接続不要
- サーバーがクライアント別状態を管理しないためスケーラビリティ優秀

ステートレスの実装:
- ファイルハンドル(file handle)でファイルを識別
- 各要求が独立的(オフセット等必要な情報をすべて含む)
- キャッシングはクライアント側で処理

NFS v4の変化:
- ステートフル(stateful)プロトコルに転換
- ファイルロック、委任(delegation)等の高度な機能サポート
- セキュリティ強化(Kerberos認証)

7. まとめ

  • マウント: ファイルシステムをディレクトリツリーに接続する過程
  • ブロックグループ: データの局所性を高めシーク時間を削減する構造
  • ext4: エクステント、遅延割り当て、ジャーナリングでパフォーマンスと信頼性を確保
  • APFS: Copy-on-Write、スナップショット、空間共有など現代的な機能
  • パフォーマンス最適化: バッファキャッシュ、先読み、Free-Behind、統合ページキャッシュ
  • NFS: RPCベースのネットワークファイルシステム、v3ステートレス / v4ステートフル
クイズ:ファイルシステム内部構造

Q1. ext4のエクステント(extent)が従来の間接ブロックポインタより優れている理由は何ですか?

A1. エクステントは連続した物理ブロックを(開始ブロック、長さ)で表現するため、大容量ファイルで数千個の個別ブロックポインタの代わりに少数のエクステントで管理できます。これによりメタデータオーバーヘッドが減り、連続ブロックを1回のI/Oで読めるためパフォーマンスが向上します。

Q2. Copy-on-Write(CoW)の利点と欠点は何ですか?

A2. 利点:原本データを保存するためスナップショット実装が容易で、クラッシュ時に一貫性を維持します。またファイル複製(clone)がO(1)で高速です。 欠点:変更時に常に新しい位置に記録するため、順次書き込みがランダム書き込みに変わる可能性があり、断片化が発生する可能性があります。

Q3. NFS v3がステートレスプロトコルである理由とv4でステートフルに転換した理由は?

A3. v3のステートレス設計はサーバークラッシュ後の再起動が簡単でスケーラビリティが良いです。しかしファイルロックやキャッシュ一貫性等の高度な機能実装が困難です。v4は状態を維持してファイルロック、委任(delegation)、セキュリティ等のより豊富な機能をサポートするよう発展しました。