# 機能設計書 102-ファイルシステム情報取得

## 概要

本ドキュメントは、libuvが提供するファイルシステム情報取得機能（uv_fs_statfs）の設計仕様を記載する。

### 本機能の処理概要

指定パスが所属するファイルシステムの統計情報（総ブロック数、空きブロック数、iノード数等）を非同期で取得する機能を提供する。

**業務上の目的・背景**：ディスク使用量の監視、空き容量の確認、ファイルシステムタイプの判定などを行う際に必要な機能である。アプリケーションが大量のデータを書き込む前にディスク空き容量を確認したり、ファイルシステムの種類に応じた処理分岐を行う場合に利用される。

**機能の利用シーン**：ディスク空き容量チェック、ファイルシステムタイプの判定、ストレージ監視ツール、ディスクフルの事前検知、運用監視ダッシュボードへのメトリクス提供など。

**主要な処理内容**：
1. リクエスト構造体を初期化し、対象パスを設定する
2. コールバック有無で同期/非同期を切り替える
3. プラットフォームに応じてstatfs()またはstatvfs()を呼び出す
4. 結果をuv_statfs_t構造体に変換して動的確保メモリに格納する
5. req->ptrに結果へのポインタを設定する

**関連システム・外部連携**：POSIXのstatfs()/statvfs()システムコール。

**権限による制御**：対象パスの各ディレクトリに対する検索権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | ファイルシステム操作 | 主機能 | uv_fs_statfs()によるファイルシステム情報取得のAPI定義 |

## 機能種別

データ取得処理（ファイルシステムメタデータの読み取り）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loop | uv_loop_t* | Yes | イベントループ | - |
| req | uv_fs_t* | Yes | FSリクエスト構造体 | NULLの場合UV_EINVAL |
| path | const char* | Yes | 対象パス | NULLでないことをassert |
| cb | uv_fs_cb | No | 完了コールバック | NULLで同期実行 |

### 入力データソース

ユーザーがAPI呼び出し時に指定するファイルパス。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| f_type | uint64_t | ファイルシステムタイプ（一部OSでは0） |
| f_bsize | uint64_t | ブロックサイズ |
| f_blocks | uint64_t | 総ブロック数 |
| f_bfree | uint64_t | 空きブロック数 |
| f_bavail | uint64_t | 非特権ユーザーが利用可能な空きブロック数 |
| f_files | uint64_t | 総iノード数 |
| f_ffree | uint64_t | 空きiノード数 |
| f_frsize | uint64_t | フラグメントサイズ（Linuxではf_frsizeから、他ではf_bsizeから取得） |
| f_spare[3] | uint64_t[3] | 予約フィールド |

### 出力先

uv_statfs_t構造体が動的に確保され、req->ptrに格納される。uv_fs_req_cleanup()で解放が必要。

## 処理フロー

### 処理シーケンス

```
1. INITマクロによるリクエスト初期化（fs_type = UV_FS_STATFS）
2. PATHマクロによるパス設定
3. POSTマクロによる実行
   └─ 非同期: スレッドプールにuv__fs_workを投入
   └─ 同期: uv__fs_workを直接呼び出し
4. uv__fs_statfs()実行
   └─ Sun/MVS/NetBSD/HAIKU/QNX: statvfs()呼び出し
   └─ その他: statfs()呼び出し
5. uv_statfs_t構造体を動的確保し結果を格納
6. req->ptrに結果ポインタを設定
```

### フローチャート

```mermaid
flowchart TD
    A[uv_fs_statfs呼び出し] --> B[INIT: リクエスト初期化]
    B --> C[PATH: パス設定]
    C --> D{cb != NULL?}
    D -->|Yes| E[スレッドプールに投入]
    D -->|No| F[同期実行]
    E --> G[uv__fs_statfs実行]
    F --> G
    G --> H{プラットフォーム}
    H -->|Sun/MVS等| I[statvfs呼び出し]
    H -->|その他| J[statfs呼び出し]
    I --> K[uv_statfs_t確保・格納]
    J --> K
    K --> L[req->ptr設定]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-201 | プラットフォーム別API使用 | Sun/MVS/NetBSD/HAIKU/QNXではstatvfs()、その他ではstatfs()を使用 | 常時 |
| BR-202 | f_type非サポート | Sun/MVS/OpenBSD/NetBSD/HAIKU/QNXではf_typeは0を設定 | 該当プラットフォーム |
| BR-203 | f_frsizeのソース | Linuxではbuf.f_frsizeから、その他ではbuf.f_bsizeから取得 | 常時 |
| BR-204 | メモリ確保 | 結果はuv__mallocで動的確保。失敗時はerrno=ENOMEMで-1返却 | 常時 |

### 計算ロジック

特に複雑な計算ロジックはなし。システムコールの結果をuv_statfs_t構造体にマッピングするのみ。

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

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

該当なし（ファイルシステムメタデータの読み取りのみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EINVAL | パラメータエラー | reqがNULL | 有効なリクエスト構造体を渡す |
| UV_ENOENT | パス不在 | 指定パスが存在しない | パスの正当性を確認する |
| UV_EACCES | 権限エラー | パスの途中ディレクトリに検索権限がない | 権限を確認する |
| UV_ENOMEM | メモリ不足 | uv_statfs_t構造体の確保に失敗 | メモリを解放する |

### リトライ仕様

EINTRで中断された場合、uv__fs_work内のdo-whileループで自動リトライされる。

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

該当なし（読み取り専用操作）

## パフォーマンス要件

同期モードではシステムコール1回で完了するため、特にパフォーマンス上の問題はない。非同期モードではスレッドプールのスレッドを1つ消費する。

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

- 対象パスの検索権限のみが必要
- 返却されるファイルシステム情報はセンシティブではないが、ディスク容量情報がサイドチャネル攻撃に利用される可能性がある

## 備考

- uv_fs_req_cleanup()で動的確保されたuv_statfs_tが解放される
- f_spare配列は将来の拡張用であり、現在は使用されていない

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | uv_statfs_t構造体の定義（1255-1265行目）。f_type/f_bsize/f_blocks等の全フィールド |
| 1-2 | uv.h | `include/uv.h` | uv_fs_t構造体の定義（1450-1460行目）。ptrフィールドにuv_statfs_tが格納される |

**読解のコツ**: uv_statfs_tはPOSIXのstruct statfs/struct statvfsを統一的に扱うための構造体。f_spareは予約領域。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | uv.h | `include/uv.h` | uv_fs_statfs()宣言（1680-1683行目） |
| 2-2 | fs.c | `src/unix/fs.c` | uv_fs_statfs()実装（2294-2301行目）。INIT(STATFS)/PATH/POSTの標準パターン |

**主要処理フロー**:
1. **2298行目**: INIT(STATFS) -- fs_typeをUV_FS_STATFSに設定
2. **2299行目**: PATH -- パス設定
3. **2300行目**: POST -- 実行

#### Step 3: 内部実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fs.c | `src/unix/fs.c` | uv__fs_statfs()実装（675-721行目）。プラットフォーム別のstatfs/statvfs呼び出しと結果変換 |

**主要処理フロー**:
- **677-689行目**: プラットフォーム別のstatvfs()/statfs()呼び出し
- **692-696行目**: uv_statfs_t構造体の動的確保とENOMEMチェック
- **698-718行目**: プラットフォーム別のフィールドマッピング（f_type、f_frsize等）
- **719行目**: req->ptr = stat_fs で結果ポインタ設定

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

```
uv_fs_statfs()
    |
    +-- INIT(STATFS)
    +-- PATH
    +-- POST
         |
         +-- uv__fs_work()
                +-- uv__fs_statfs()
                       +-- statvfs() / statfs()
                       +-- uv__malloc() -- uv_statfs_t確保
                       +-- req->ptr = stat_fs
```

### データフロー図

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

path (const char*)  --> uv_fs_statfs()
                         |
                         v
                    uv__fs_statfs()
                         |
                    +----+----+
                    v         v
              statvfs()   statfs()            --> uv_statfs_t (動的確保)
                    |         |                    |
                    +----+----+                    +-- f_type, f_bsize
                         v                         +-- f_blocks, f_bfree
                    uv_statfs_t構造体に変換         +-- f_bavail, f_files
                         v                         +-- f_ffree, f_frsize
                    req->ptr に格納
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | uv_statfs_t構造体定義、API宣言 |
| fs.c | `src/unix/fs.c` | ソース | Unix系のstatfs実装 |
| fs.c | `src/win/fs.c` | ソース | Windows版のstatfs実装 |
