# 機能設計書 14-msdosfs（FAT）

## 概要

本ドキュメントは、FreeBSDにおけるMS-DOS FAT形式ファイルシステム（msdosfs）のサポート機能の設計を記載する。FAT12/FAT16/FAT32フォーマットのメディアの読み書き、およびVFAT（長いファイル名）をサポートする。

### 本機能の処理概要

**業務上の目的・背景**：msdosfsはWindows、Linux等の他OSとのデータ交換において広く使用されるFATファイルシステムをFreeBSD上で利用可能にする。USBメモリ、SDカード、外部ハードディスク等のリムーバブルメディアで最も一般的なファイルシステム形式である。

**機能の利用シーン**：USBメモリのマウント・データアクセス、Windows環境とのデュアルブートにおけるデータ交換パーティション、EFIシステムパーティション（ESP）のアクセス、組み込みシステムのストレージアクセスなど。

**主要な処理内容**：
1. FAT12/FAT16/FAT32ファイルシステムのマウント・アンマウント
2. FATテーブル（File Allocation Table）の読み書き・管理
3. ディレクトリエントリの作成・検索・削除
4. VFAT（長いファイル名）のサポート
5. 8.3形式短いファイル名の自動生成
6. 文字コード変換（iconv連携）
7. ファイルシステム整合性チェック（fsck_msdosfs）
8. ファイルシステム作成（newfs_msdos）

**関連システム・外部連携**：GEOMストレージフレームワーク経由でディスクデバイスにアクセス。iconvカーネルモジュールによる文字コード変換。

**権限による制御**：マウント時にuid/gid/maskオプションで所有者とパーミッションを指定。FAT自体にはUNIXパーミッションの概念がないため、マウントオプションで一律設定。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに直接関連する画面なし |

## 機能種別

CRUD操作 / ファイルシステムアクセス / 相互運用性

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| デバイスパス | char* | Yes | FATファイルシステムのブロックデバイス | デバイスファイルの存在確認 |
| マウントポイント | char* | Yes | マウント先ディレクトリパス | ディレクトリの存在確認 |
| uid | uid_t | No | ファイル所有者UID | 有効なUID |
| gid | gid_t | No | ファイル所有者GID | 有効なGID |
| mask | mode_t | No | ファイルパーミッションマスク | 有効なモード値 |
| charset | char* | No | 文字コード（デフォルト: locale依存） | iconvサポート文字コード |

### 入力データソース

- mount_msdosfs(8) コマンドからのユーザ入力
- /etc/fstab設定ファイル
- ブロックデバイス上のBPB（BIOS Parameter Block）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ファイルデータ | バイトストリーム | FAT上のファイル内容 |
| ファイル属性 | struct vattr | FATメタデータから変換されたファイル属性 |
| ディレクトリエントリ | struct dirent | ディレクトリ内のファイル一覧 |

### 出力先

- VFS層を介したユーザ空間アプリケーション

## 処理フロー

### 処理シーケンス

```
1. マウント処理（msdosfs_mount）
   └─ BPB読み込み → FAT種別判定（12/16/32） → msdosfsmount構造体初期化
2. ファイルアクセス
   └─ ディレクトリエントリ検索 → FATチェーン追跡 → データクラスタ読み取り
3. ファイル作成
   └─ ディレクトリエントリ作成 → FATエントリ割り当て → データ書き込み
4. アンマウント
   └─ ダーティバッファフラッシュ → FAT更新 → リソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[mount要求] --> B[msdosfs_mount]
    B --> C[BPB読み込み]
    C --> D{FAT種別判定}
    D -->|FAT12| E[FAT12初期化]
    D -->|FAT16| F[FAT16初期化]
    D -->|FAT32| G[FAT32初期化]
    E --> H[マウント完了]
    F --> H
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-14-01 | FAT種別判定 | クラスタ総数に基づきFAT12(<4085)/FAT16(<65525)/FAT32を判定 | マウント時 |
| BR-14-02 | 8.3ファイル名 | 長いファイル名はVFATエントリとして格納し、8.3短縮名を自動生成 | ファイル作成時 |
| BR-14-03 | クラスタチェーン | FATテーブルでクラスタの連結リストを管理 | ファイルI/O時 |
| BR-14-04 | 大文字小文字 | FAT16以前は大文字のみ、VFATでは大文字小文字を保持 | ファイル名処理時 |

### 計算ロジック

- クラスタ開始セクタ = データ領域開始セクタ + (クラスタ番号 - 2) * セクタ/クラスタ
- ファイルサイズ制限: FAT32で最大4GB - 1バイト

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ファイル作成 | FATテーブル / ディレクトリエントリ | INSERT | FATエントリ割り当てとディレクトリエントリ作成 |
| ファイル読み取り | FATテーブル | SELECT | FATチェーン追跡によるクラスタ特定 |
| ファイル削除 | FATテーブル / ディレクトリエントリ | DELETE | FATエントリ解放とディレクトリエントリ無効化 |

### テーブル別操作詳細

#### FATテーブル（File Allocation Table）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | クラスタエントリ | 次クラスタ番号取得 | チェーン追跡 |
| UPDATE | クラスタエントリ | 次クラスタ番号 or EOF | ファイル拡張時 |
| UPDATE | クラスタエントリ | FREE(0x0000) | ファイル削除時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EINVAL | バリデーション | 不正なBPBまたはFATシグネチャ | fsck_msdosfで修復 |
| ENOSPC | リソース不足 | 空きクラスタ不足 | 不要ファイル削除 |
| ENAMETOOLONG | ファイル名エラー | ファイル名が255文字超過 | 短いファイル名を使用 |
| EFBIG | ファイルサイズ | FAT32で4GB超のファイル作成試行 | ファイル分割 |

### リトライ仕様

ディスクI/Oエラー時はGEOM層でリトライが行われる。ファイルシステム層ではリトライを行わない。

## トランザクション仕様

FATファイルシステムにはジャーナリング機能がないため、トランザクション保証はない。書き込み途中でのクラッシュ時はfsck_msdosfによる整合性修復が必要。

## パフォーマンス要件

- FATテーブルのインメモリキャッシュによるクラスタチェーン追跡の高速化
- 大規模ディレクトリではリニアサーチとなるため性能低下の可能性
- バッファキャッシュによる読み取り性能の向上

## セキュリティ考慮事項

- FAT自体にはアクセス制御機構がないため、マウントオプション（uid/gid/mask）で制御
- nosuidマウントオプションによるsetuid/setgidの無効化推奨
- リムーバブルメディアからの自動実行を防止する設定が必要

## 備考

- EFIシステムパーティション（ESP）はFAT32形式のため、msdosfsで管理される
- exFATはmsdosfsではサポートされない（別途fusefs-exfatが必要）
- newfs_msdos(8)によりFATファイルシステムの新規作成が可能
- fsck_msdosfs(8)による整合性チェック・修復が可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | bpb.h | `sys/fs/msdosfs/bpb.h` | BIOS Parameter Block構造体（ブートセクタ情報） |
| 1-2 | denode.h | `sys/fs/msdosfs/denode.h` | ディレクトリエントリノード構造体（FAT版inode） |
| 1-3 | direntry.h | `sys/fs/msdosfs/direntry.h` | ディレクトリエントリ形式（8.3 + VFAT） |
| 1-4 | fat.h | `sys/fs/msdosfs/fat.h` | FATテーブル操作定義 |
| 1-5 | msdosfsmount.h | `sys/fs/msdosfs/msdosfsmount.h` | マウント情報構造体 |

**読解のコツ**: msdosfsではdenodeがUFSのinodeに相当する。FATテーブルはクラスタの連結リストとして機能し、fat.hで定義されたマクロでアクセスする。

#### Step 2: エントリーポイントを理解する（VFS操作）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | msdosfs_vfsops.c | `sys/fs/msdosfs/msdosfs_vfsops.c` | VFS操作実装 |

**主要処理フロー**:
1. **231行目**: msdosfs_mount() - マウント処理、BPB読み込みとFAT種別判定
2. **891行目**: msdosfs_unmount() - アンマウント処理
3. **1195行目**: msdosfs_vfsops構造体定義
4. **1205行目**: VFS_SET登録

#### Step 3: vnode操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | msdosfs_vnops.c | `sys/fs/msdosfs/msdosfs_vnops.c` | vnode操作（read, write, create, remove等） |
| 3-2 | msdosfs_lookup.c | `sys/fs/msdosfs/msdosfs_lookup.c` | ディレクトリ検索 |

#### Step 4: FATテーブル操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | msdosfs_fat.c | `sys/fs/msdosfs/msdosfs_fat.c` | FATテーブルの読み書き・クラスタ割り当て |
| 4-2 | msdosfs_denode.c | `sys/fs/msdosfs/msdosfs_denode.c` | denode管理 |

#### Step 5: ユーザ空間ツール

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | mount_msdosfs.c | `sbin/mount_msdosfs/mount_msdosfs.c` | mount_msdosfsコマンド |
| 5-2 | - | `sbin/fsck_msdosfs/` | fsck_msdosfs（整合性チェック） |
| 5-3 | - | `sbin/newfs_msdos/` | newfs_msdos（FAT作成） |

### プログラム呼び出し階層図

```
mount_msdosfs(8)
    │
    └─ kernel: msdosfs_mount()
           │
           ├─ BPB解析 → FAT種別判定
           ├─ FATテーブル読み込み
           └─ msdosfsmount構造体初期化

VFS I/O要求
    │
    ├─ msdosfs_vnops.c（vnode操作）
    │      ├─ msdosfs_read() / msdosfs_write()
    │      └─ msdosfs_create() / msdosfs_remove()
    │
    ├─ msdosfs_lookup.c（ディレクトリ検索）
    │
    ├─ msdosfs_fat.c（FATテーブル操作）
    │      ├─ クラスタ割り当て
    │      └─ クラスタチェーン追跡
    │
    └─ msdosfs_denode.c（denode管理）
```

### データフロー図

```
[入力]                    [処理]                           [出力]

ブロックデバイス ───────▶ BPB解析                     ──▶ マウント情報
                          ↓
ユーザI/O要求    ───────▶ msdosfs_vnops              ──▶ ファイルデータ
                          ↓
                          msdosfs_fat.c
                          （FATチェーン追跡）
                          ↓
                          クラスタデータ読み書き
                          ↓
                          GEOM層 → ディスクI/O
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bpb.h | `sys/fs/msdosfs/bpb.h` | ヘッダ | BIOS Parameter Block定義 |
| bootsect.h | `sys/fs/msdosfs/bootsect.h` | ヘッダ | ブートセクタ定義 |
| denode.h | `sys/fs/msdosfs/denode.h` | ヘッダ | denode構造体 |
| direntry.h | `sys/fs/msdosfs/direntry.h` | ヘッダ | ディレクトリエントリ形式 |
| fat.h | `sys/fs/msdosfs/fat.h` | ヘッダ | FATテーブル操作定義 |
| msdosfsmount.h | `sys/fs/msdosfs/msdosfsmount.h` | ヘッダ | マウント情報構造体 |
| msdosfs_vfsops.c | `sys/fs/msdosfs/msdosfs_vfsops.c` | ソース | VFS操作 |
| msdosfs_vnops.c | `sys/fs/msdosfs/msdosfs_vnops.c` | ソース | vnode操作 |
| msdosfs_lookup.c | `sys/fs/msdosfs/msdosfs_lookup.c` | ソース | ディレクトリ検索 |
| msdosfs_fat.c | `sys/fs/msdosfs/msdosfs_fat.c` | ソース | FATテーブル管理 |
| msdosfs_denode.c | `sys/fs/msdosfs/msdosfs_denode.c` | ソース | denode管理 |
| msdosfs_conv.c | `sys/fs/msdosfs/msdosfs_conv.c` | ソース | 文字コード変換 |
| msdosfs_iconv.c | `sys/fs/msdosfs/msdosfs_iconv.c` | ソース | iconv連携 |
| mount_msdosfs.c | `sbin/mount_msdosfs/mount_msdosfs.c` | ソース | mountコマンド |
