# 機能設計書 19-FUSE

## 概要

本ドキュメントは、FreeBSDのFUSE（Filesystem in Userspace）サポート機能の設計を記載する。FUSEはユーザ空間プログラムによるファイルシステムの実装を可能にするフレームワークであり、カーネルモジュール（fusefs）とユーザ空間ライブラリの組み合わせで動作する。

### 本機能の処理概要

**業務上の目的・背景**：FUSEはカーネルモジュールの開発を必要とせずにカスタムファイルシステムを実装できる仕組みを提供する。NTFSやSSHFS、exFAT等のサードパーティファイルシステムをユーザ空間で安全に動作させることが主要な目的である。

**機能の利用シーン**：NTFS-3G（NTFSアクセス）、SSHFS（SSH経由のリモートファイルアクセス）、exFAT（exFATファイルシステム）、各種クラウドストレージクライアント、暗号化ファイルシステムなど。

**主要な処理内容**：
1. FUSEカーネルモジュール（fusefs）によるVFS-ユーザ空間ブリッジ
2. /dev/fuseデバイスを介したカーネル-ユーザ空間通信
3. FUSEプロトコルによるリクエスト/レスポンス処理
4. ユーザ空間ファイルシステムデーモンへの操作転送
5. マウント・アンマウント処理
6. キャッシュ管理（カーネル側バッファキャッシュ）

**関連システム・外部連携**：VFS層とユーザ空間デーモンをブリッジする。/dev/fuseデバイスファイルを通じて通信する。

**権限による制御**：マウントにはroot権限が必要（allow_other/default_permissionsオプションで非root利用を制御）。ファイルアクセス権限はユーザ空間デーモンの実装に依存。

## 関連画面

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

## 機能種別

ファイルシステムブリッジ / ユーザ空間ファイルシステム

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| デバイスソース | char* | Yes | FUSEデーモンが使用するデバイス/パス | デーモン固有 |
| マウントポイント | char* | Yes | マウント先ディレクトリ | ディレクトリの存在確認 |
| FUSEオプション | char* | No | allow_other, default_permissions等 | 有効なオプション |
| サブタイプ | char* | No | ファイルシステムのサブタイプ名 | 任意の文字列 |

### 入力データソース

- mount_fusefs(8) コマンドからのユーザ入力
- FUSEユーザ空間デーモンからの初期化リクエスト
- /dev/fuseデバイスファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ファイルデータ | バイトストリーム | ユーザ空間デーモンから返されたファイル内容 |
| ファイル属性 | struct vattr | ユーザ空間デーモンから返されたメタデータ |
| ディレクトリエントリ | struct dirent | ユーザ空間デーモンから返されたディレクトリ一覧 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. マウント処理（fuse_vfsop_mount）
   └─ /dev/fuseオープン → FUSEセッション初期化 → FUSE_INIT交換 → マウント完了
2. ファイルI/O
   └─ VFS要求受信 → FUSEリクエスト生成 → /dev/fuse書き込み → デーモン処理 → レスポンス読み取り
3. アンマウント（fuse_vfsop_unmount）
   └─ FUSE_DESTROY送信 → セッション終了 → リソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[VFS I/O要求] --> B[FUSEカーネルモジュール]
    B --> C[FUSEリクエスト生成]
    C --> D[/dev/fuseキューに追加]
    D --> E[ユーザ空間デーモンread]
    E --> F[デーモンが処理実行]
    F --> G[レスポンスwrite]
    G --> H[カーネルがレスポンス受信]
    H --> I[VFSに結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-19-01 | プロトコルネゴシエーション | マウント時にFUSE_INITでプロトコルバージョンをネゴシエーション | マウント時 |
| BR-19-02 | 同期通信 | VFS要求はFUSEデーモンの応答を待ってブロック | I/O時 |
| BR-19-03 | タイムアウト | デーモン無応答時はタイムアウトでエラー返却 | I/O時 |
| BR-19-04 | カーネルキャッシュ | default_permissionsオプションでカーネル側権限チェックを有効化 | マウントオプション設定時 |

### 計算ロジック

特別な計算ロジックはない。全てのファイルシステム操作はユーザ空間デーモンに委譲される。

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

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

FUSEカーネルモジュールはブリッジとして機能し、データの実体はユーザ空間デーモンが管理する。

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

直接のデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EIO | I/Oエラー | デーモンが異常終了 | デーモン再起動 |
| ETIMEDOUT | タイムアウト | デーモン無応答 | デーモン状態確認 |
| ENOTCONN | 接続切断 | FUSEセッション切断 | 再マウント |
| ENODEV | デバイス不在 | /dev/fuseが存在しない | カーネルモジュールロード |

### リトライ仕様

デーモン応答のタイムアウト後、一定回数のリトライが行われる場合がある（実装依存）。デーモンが終了した場合はリトライ不可。

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

トランザクション管理はユーザ空間デーモンの実装に依存する。FUSEカーネルモジュール自体はトランザクション機能を提供しない。

## パフォーマンス要件

- カーネル-ユーザ空間間のコンテキストスイッチによるオーバーヘッド
- /dev/fuseを介した通信の遅延
- カーネル側バッファキャッシュにより繰り返しアクセスの性能を向上
- 大きなI/Oサイズ（max_read/max_write）設定により転送効率を改善

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

- allow_otherオプションなしでは、マウントしたユーザのみがアクセス可能
- default_permissionsオプションでカーネル側のパーミッションチェックを強制
- ユーザ空間デーモンの脆弱性がファイルシステムの安全性に影響
- FUSEデーモンはマウントユーザの権限で動作

## 備考

- fusefs カーネルモジュールは kldload fuse で読み込み
- FreeBSDのFUSE実装はLinux FUSEプロトコルとの互換性を提供
- libfuse（ユーザ空間ライブラリ）はportsから提供される
- FUSE プロトコルバージョン7.xに対応

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fuse.h | `sys/fs/fuse/fuse.h` | FUSE全体の構成定義 |
| 1-2 | fuse_kernel.h | `sys/fs/fuse/fuse_kernel.h` | FUSEプロトコル定義（リクエスト/レスポンス形式） |
| 1-3 | fuse_node.h | `sys/fs/fuse/fuse_node.h` | FUSEノード構造体 |
| 1-4 | fuse_ipc.h | `sys/fs/fuse/fuse_ipc.h` | カーネル-ユーザ空間IPC構造体 |
| 1-5 | fuse_file.h | `sys/fs/fuse/fuse_file.h` | FUSEファイルハンドル構造体 |

**読解のコツ**: FUSEプロトコルはfuse_kernel.hに定義されており、Linux FUSEプロジェクトとヘッダを共有している。fuse_in_header/fuse_out_headerがリクエスト/レスポンスのヘッダ構造体。

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

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

**主要処理フロー**:
1. **115-116行目**: fuse_vfsop_mount / fuse_vfsop_unmount の宣言
2. **123-124行目**: vfsops構造体の定義
3. **296行目**: fuse_vfsop_mount() - マウント処理（/dev/fuseオープン、FUSE_INIT）
4. **480行目**: fuse_vfsop_unmount() - アンマウント処理

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fuse_vnops.c | `sys/fs/fuse/fuse_vnops.c` | vnode操作のFUSEリクエスト変換 |

#### Step 4: IPC通信を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | fuse_ipc.c | `sys/fs/fuse/fuse_ipc.c` | カーネル-ユーザ空間メッセージング |
| 4-2 | fuse_device.c | `sys/fs/fuse/fuse_device.c` | /dev/fuseデバイス操作（read/write/poll） |

#### Step 5: 内部処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | fuse_internal.c | `sys/fs/fuse/fuse_internal.c` | 内部ヘルパー関数 |
| 5-2 | fuse_io.c | `sys/fs/fuse/fuse_io.c` | I/O処理 |
| 5-3 | fuse_node.c | `sys/fs/fuse/fuse_node.c` | ノード管理 |

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

```
mount_fusefs(8) / FUSEデーモン
    │
    └─ kernel: fuse_vfsop_mount()（fuse_vfsops.c:296）
           │
           ├─ /dev/fuseオープン（fuse_device.c）
           ├─ FUSE_INITメッセージ交換（fuse_ipc.c）
           └─ マウント完了

VFS I/O要求
    │
    ├─ fuse_vnops.c（vnode操作）
    │      └─ FUSEリクエスト生成
    │
    ├─ fuse_ipc.c（メッセージング）
    │      ├─ リクエストをキューに追加
    │      └─ レスポンスを待機
    │
    ├─ fuse_device.c（/dev/fuse）
    │      ├─ デーモンがread()でリクエスト取得
    │      └─ デーモンがwrite()でレスポンス送信
    │
    └─ fuse_internal.c / fuse_io.c（内部処理）

ユーザ空間デーモン:
    /dev/fuse read → リクエスト処理 → /dev/fuse write
```

### データフロー図

```
[ユーザアプリ]         [カーネル FUSE]              [FUSEデーモン]

VFS I/O    ────▶  fuse_vnops.c          ────▶  /dev/fuse read()
                   ↓                              ↓
                   fuse_ipc.c                     処理実行
                   （リクエスト生成）               ↓
                   ↓                              /dev/fuse write()
結果返却   ◀────  fuse_ipc.c            ◀────  （レスポンス）
                   （レスポンス受信）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fuse.h | `sys/fs/fuse/fuse.h` | ヘッダ | FUSE全体構成 |
| fuse_kernel.h | `sys/fs/fuse/fuse_kernel.h` | ヘッダ | FUSEプロトコル定義 |
| fuse_node.h | `sys/fs/fuse/fuse_node.h` | ヘッダ | ノード構造体 |
| fuse_ipc.h | `sys/fs/fuse/fuse_ipc.h` | ヘッダ | IPC構造体 |
| fuse_file.h | `sys/fs/fuse/fuse_file.h` | ヘッダ | ファイルハンドル構造体 |
| fuse_io.h | `sys/fs/fuse/fuse_io.h` | ヘッダ | I/O定義 |
| fuse_internal.h | `sys/fs/fuse/fuse_internal.h` | ヘッダ | 内部ヘルパー定義 |
| fuse_vfsops.c | `sys/fs/fuse/fuse_vfsops.c` | ソース | VFS操作 |
| fuse_vnops.c | `sys/fs/fuse/fuse_vnops.c` | ソース | vnode操作 |
| fuse_device.c | `sys/fs/fuse/fuse_device.c` | ソース | /dev/fuseデバイス |
| fuse_ipc.c | `sys/fs/fuse/fuse_ipc.c` | ソース | IPC通信 |
| fuse_internal.c | `sys/fs/fuse/fuse_internal.c` | ソース | 内部処理 |
| fuse_io.c | `sys/fs/fuse/fuse_io.c` | ソース | I/O処理 |
| fuse_node.c | `sys/fs/fuse/fuse_node.c` | ソース | ノード管理 |
| fuse_file.c | `sys/fs/fuse/fuse_file.c` | ソース | ファイル管理 |
| fuse_main.c | `sys/fs/fuse/fuse_main.c` | ソース | モジュール初期化 |
| mount_fusefs.c | `sbin/mount_fusefs/mount_fusefs.c` | ソース | mountコマンド |
