# 機能設計書 17-nullfs

## 概要

本ドキュメントは、FreeBSDのnullfsファイルシステムの機能設計を記載する。nullfsはファイルシステムのループバックマウント機能を提供し、既存のディレクトリツリーを別のマウントポイントに再マウントすることで、同じデータを異なるパスからアクセス可能にする。

### 本機能の処理概要

**業務上の目的・背景**：nullfsはファイルシステムの特定部分を別のパスから参照する必要がある場面で利用される。jail環境でホストのディレクトリを共有する、chroot環境にファイルを提供する、複数のパスから同じデータにアクセスするなどの用途に対応する。

**機能の利用シーン**：jail(8)内でホストファイルシステムの特定ディレクトリを共有する、chroot環境に必要なライブラリやバイナリを提供する、NFSエクスポートのための仮想パス構成など。

**主要な処理内容**：
1. 既存ディレクトリの別パスへのループバックマウント
2. 下層ファイルシステムへのvnode操作の透過的転送
3. vnode相互変換（nullfs vnode ⇔ 下層vnode）
4. ファイルマウント（単一ファイルのマウント）のサポート

**関連システム・外部連携**：jail(8)環境での利用が主要ユースケース。VFS層と密接に連携し、下層ファイルシステムのvnodeをラップする。

**権限による制御**：マウントにはroot権限が必要。アクセス権限は下層ファイルシステムの権限設定に従う。

## 関連画面

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

## 機能種別

ファイルシステムリダイレクト / ループバックマウント

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ターゲットパス | char* | Yes | マウント元ディレクトリ/ファイル | パスの存在確認 |
| マウントポイント | char* | Yes | マウント先ディレクトリ | ディレクトリの存在確認 |

### 入力データソース

- mount_nullfs(8) コマンドからのユーザ入力
- /etc/fstab設定ファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ファイルデータ | バイトストリーム | 下層ファイルシステムと同一のデータ |
| ファイルメタデータ | struct vattr | 下層ファイルシステムと同一のメタデータ |

### 出力先

- VFS層を介したユーザ空間アプリケーション（下層FSへ透過的に転送）

## 処理フロー

### 処理シーケンス

```
1. マウント処理
   └─ ターゲットパスのvnode取得 → null_mount構造体初期化 → マウント完了
2. ファイルアクセス
   └─ nullfs vnode受信 → 下層vnode取得 → 下層FSのvnode操作呼び出し → 結果返却
3. アンマウント
   └─ null_mount構造体解放
```

### フローチャート

```mermaid
flowchart TD
    A[mount_nullfs要求] --> B[null_mount初期化]
    B --> C[ターゲットvnode取得]
    C --> D[マウント完了]
    D --> E[VFS I/O要求]
    E --> F[nullfs vnode操作]
    F --> G[下層vnode取得]
    G --> H[下層FS vnode操作呼び出し]
    H --> I[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-17-01 | 透過的転送 | 全てのvnode操作は下層ファイルシステムに透過的に転送される | 常時 |
| BR-17-02 | vnodeラッピング | nullfs vnodeは下層vnodeをラップし、1対1の対応関係を維持 | vnode操作時 |
| BR-17-03 | jail対応 | VFCF_JAILフラグにより jail環境内でのマウントに対応 | jail使用時 |
| BR-17-04 | ファイルマウント | VFCF_FILEMOUNTフラグにより単一ファイルのマウントに対応 | ファイルマウント時 |

### 計算ロジック

特別な計算ロジックはなし。全ての操作は下層ファイルシステムに委譲される。

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

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

nullfsはスタッキングファイルシステムであり、データの実体は下層ファイルシステムに存在する。全ての操作は下層FSに委譲される。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ENOENT | パス不在 | ターゲットパスが存在しない | パス確認 |
| ELOOP | ループ検出 | nullfsの循環マウント | マウント構成見直し |
| その他 | 下層FSエラー | 下層ファイルシステムのエラー | 下層FSのエラー処理に従う |

### リトライ仕様

nullfs自体ではリトライを行わない。エラーは下層ファイルシステムのものがそのまま返却される。

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

nullfsはスタッキングFSであるため、トランザクション管理は下層ファイルシステムに依存する。

## パフォーマンス要件

- vnode操作の転送オーバーヘッドは最小限
- 下層ファイルシステムの性能がそのまま反映される
- nullfs固有のキャッシュは持たない

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

- アクセス権限は下層ファイルシステムのものが適用される
- jail環境での使用時は、必要最小限のディレクトリのみをマウントすること
- 読み取り専用マウントオプションにより書き込みを制限可能

## 備考

- nullfsはスタッキングファイルシステムの一種（Wrapfs由来）
- VFS_SET登録時にVFCF_LOOPBACK | VFCF_JAIL | VFCF_FILEMOUNTフラグが設定される
- シンボリックリンクとは異なりファイルシステムレベルでの透過的リダイレクト

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | null.h | `sys/fs/nullfs/null.h` | null_mount構造体、null_node構造体の定義 |

**読解のコツ**: nullfsは非常にシンプルなスタッキングFSである。null_nodeは下層vnodeへの参照（null_lowervp）を保持するだけの構造。NULLVPTOLOWERVP()マクロで下層vnodeを取得する。

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

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

**主要処理フロー**:
1. **177行目**: null_mount構造体のメモリ割り当て
2. **490行目**: null_vfsops構造体定義
3. **506行目**: VFS_SET登録（VFCF_LOOPBACK | VFCF_JAIL | VFCF_FILEMOUNT）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | null_vnops.c | `sys/fs/nullfs/null_vnops.c` | vnode操作の下層FSへの転送（bypass機構） |

#### Step 4: vnode変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | null_subr.c | `sys/fs/nullfs/null_subr.c` | nullfs vnode ⇔ 下層vnode の変換サブルーチン |

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

```
mount_nullfs(8)
    │
    └─ kernel: null_mount（null_vfsops.c）
           │
           ├─ ターゲットvnode取得（VFS namei）
           └─ null_mount構造体初期化

VFS I/O要求
    │
    └─ null_vnops.c（vnode操作）
           │
           ├─ null_bypass()（汎用転送）
           │      └─ 下層vnode操作呼び出し
           │
           └─ null_subr.c（vnode変換）
                  ├─ null_node_find()
                  └─ null_node_create()
```

### データフロー図

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

VFS I/O要求     ──────▶ null_vnops                 ──▶ 結果データ
                          ↓
                          下層vnode取得（null_subr.c）
                          ↓
                          下層FS vnode操作
                          ↓
                          結果をそのまま上位に返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| null.h | `sys/fs/nullfs/null.h` | ヘッダ | データ構造定義 |
| null_vfsops.c | `sys/fs/nullfs/null_vfsops.c` | ソース | VFS操作 |
| null_vnops.c | `sys/fs/nullfs/null_vnops.c` | ソース | vnode操作（bypass） |
| null_subr.c | `sys/fs/nullfs/null_subr.c` | ソース | vnode変換サブルーチン |
| mount_nullfs.c | `sbin/mount_nullfs/mount_nullfs.c` | ソース | mountコマンド |
