# 帳票設計書 25-du - ディスク使用量統計レポート

## 概要

本ドキュメントは、FreeBSDのduコマンドが出力するディスク使用量統計レポートの帳票設計書である。duはファイルおよびディレクトリのディスク使用量を再帰的に集計して表示する。

### 本帳票の処理概要

duコマンドは、fts(3)ライブラリを使用してディレクトリツリーを走査し、各ファイル/ディレクトリのディスク使用量（ブロック数またはバイト数）を集計してレポートする。ハードリンクの重複カウントを回避する仕組みを持つ。

**業務上の目的・背景**：ディスク容量管理において、どのディレクトリやファイルがどれだけのディスク容量を使用しているかを把握することは重要である。容量不足の原因特定、クリーンアップ対象の選定、クォータ設定の参考情報として使用される。

**帳票の利用シーン**：ディスク容量不足の原因調査、大容量ディレクトリの特定、バックアップサイズの見積もり、クォータ設定前の現状把握、定期的なディスク使用量監視などで使用される。

**主要な出力内容**：
1. サイズ: ディスク使用量（ブロック数、キロバイト、メガバイト等）
2. パス: ファイルまたはディレクトリのパス

**帳票の出力タイミング**：コマンドラインからduコマンドを実行した時点で即座に出力される。

**帳票の利用者**：システム管理者、ストレージ管理者、一般ユーザー

## 帳票種別

集計表（テキスト形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | コマンドライン | ターミナル | `du [オプション] [パス...]` 実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（標準出力） |
| 用紙サイズ | N/A（ターミナル出力） |
| 向き | N/A |
| ファイル名 | N/A（標準出力） |
| 出力方法 | 標準出力（stdout） |
| 文字コード | ロケール依存 |

## 帳票レイアウト

### レイアウト概要

```
┌──────────────────────────┐
│ サイズ    パス            │
│ 1024     ./src           │
│ 512      ./src/lib       │
│ 2048     ./doc           │
│ 3584     .               │
└──────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | なし | デフォルトではヘッダーなし | - | - |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | サイズ | ディスク使用量 | stat.st_blocks | タブ区切り | 可変 |
| 2 | パス | ファイル/ディレクトリパス | FTS走査結果 | 文字列 | 可変 |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 合計行 | -cオプション時のみ合計サイズ | 全サイズの合計 | サイズ + "total" |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| -a | 全ファイルを表示（ディレクトリだけでなく） | No |
| -s | サマリーのみ（指定パスの合計のみ） | No |
| -d depth | 指定深さまで表示 | No |
| -h | 人間可読形式（K, M, G） | No |
| -k | キロバイト単位 | No |
| -m | メガバイト単位 | No |
| -c | 総合計を表示 | No |
| -x | ファイルシステム境界を越えない | No |
| -L | シンボリックリンクを辿る | No |
| -H | コマンドライン引数のシンボリックリンクのみ辿る | No |
| -I pattern | 除外パターン | No |
| -t threshold | 閾値以上/以下のみ表示 | No |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | FTS走査順（深さ優先） | ボトムアップ |

### 改ページ条件

テキスト出力のため改ページなし。

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| ファイルシステム（stat/lstat） | ファイルサイズ・ブロック数取得 | パスで指定 |

### テーブル別参照項目詳細

#### ファイルシステム（stat構造体）

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| st_blocks | サイズ | FTS走査 | 512バイトブロック単位 |
| st_ino | (内部用) | FTS走査 | ハードリンク重複排除 |
| st_dev | (内部用) | FTS走査 | デバイスID（-x用） |
| st_nlink | (内部用) | FTS走査 | リンク数 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| ブロック数 | st_blocks * 512 / blocksize | 切り上げ | blocksizeはオプションに依存 |
| ディレクトリ合計 | 配下全ファイルのブロック数合計 | - | 再帰的に集計 |
| 人間可読形式 | humanize_number() | 小数1位 | -hオプション時 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[コマンド実行] --> B[getopt - オプション解析]
    B --> C[blocksize決定]
    C --> D[fts_open - ディレクトリツリーオープン]
    D --> E[fts_read - エントリ読み取りループ]
    E --> F{エントリタイプ判定}
    F -->|ディレクトリ| G[サイズ集計]
    F -->|ファイル| H[ブロック数加算]
    F -->|エラー| I[警告出力]
    G --> J[表示条件チェック]
    H --> J
    J -->|表示対象| K[サイズ + パス出力]
    J -->|非表示| E
    K --> E
    E -->|走査完了| L{-cオプション?}
    L -->|Yes| M[合計行出力]
    L -->|No| N[終了]
    M --> N
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| アクセス拒否 | 読み取り権限なし | warn()出力 | 適切な権限で実行 |
| シンボリックリンクループ | 循環参照 | FTS_DC検出で警告 | -Lオプション未使用で回避 |
| パス不存在 | 指定パスが存在しない | エラーメッセージ | 正しいパスを指定 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数千〜数百万ファイル |
| 目標出力時間 | ファイル数に比例（ファイルシステムI/Oがボトルネック） |
| 同時出力数上限 | 制限なし |

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

- 読み取り権限のないディレクトリはスキップされる
- Capsicumサンドボックスに対応（cap_enter()使用）
- ファイルパス情報が出力されるため、ディレクトリ構造が漏洩する可能性がある

## 備考

- duはPOSIX標準コマンドであり、BSD拡張オプションも多数持つ
- fts(3)ライブラリを使用しており、効率的なディレクトリ走査を行う
- ハードリンクの重複カウント回避のため、iノード番号とデバイスIDを記録する
- -Aオプション（見かけサイズ）はst_sizeを使用し、-A未指定時はst_blocksを使用する

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | du.c | `usr.bin/du/du.c` | グローバル変数群：listall（-a）、maxdepth（-d）、blocksize、threshold（-t）等のフラグ変数。ハードリンク追跡用のlinkchk()関数 |

**読解のコツ**: du.cは単一ファイルだが400行以上ある。fts(3)のFTSENT構造体の扱いを理解することが重要。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | du.c | `usr.bin/du/du.c` | main()関数で長大なgetopt()処理後、fts_open()でディレクトリ走査を開始し、fts_read()ループで各エントリを処理 |

**主要処理フロー**:
1. **行100付近**: getopt()による多数のオプション解析（-a, -c, -d, -h, -k, -m, -s, -x等）
2. **行180付近**: getbsize()またはオプション指定によるブロックサイズ決定
3. **行200付近**: fts_open()でファイルツリー走査開始
4. **行210-350付近**: fts_read()ループ。FTS_D（ディレクトリ進入）、FTS_DP（ディレクトリ完了）、FTS_F（通常ファイル）等で分岐処理
5. **行350付近**: ハードリンクチェック（linkchk関数）
6. **行380付近**: -cオプション時の合計出力

#### Step 3: 表示処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | du.c | `usr.bin/du/du.c` | prthumanval()関数: -hオプション時のhumanize_number()呼び出し。prstat()関数: 閾値チェック後にサイズとパスを出力 |

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

```
main() [du.c]
    │
    ├─ getopt() - オプション解析
    ├─ getbsize() - ブロックサイズ決定
    ├─ cap_enter() - Capsicumサンドボックス
    │
    ├─ fts_open() - ディレクトリツリーオープン
    │
    └─ fts_read()ループ
           │
           ├─ linkchk() - ハードリンク重複チェック
           │
           ├─ prstat() - サイズ+パス出力
           │      │
           │      ├─ prthumanval() - 人間可読形式出力
           │      └─ printf() - 通常出力
           │
           └─ ignorep() - 除外パターンチェック
```

### データフロー図

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

コマンドライン   ───▶ オプション解析        ───▶ フラグ設定
パス引数

ファイル        ───▶ fts_open/read         ───▶ FTSENT構造体
システム              │
                      ├─ stat情報取得
                      ├─ ハードリンクチェック
                      └─ サイズ集計
                           │
                           ▼
                      prstat()             ───▶ 標準出力
                                                (サイズ TAB パス)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| du.c | `usr.bin/du/du.c` | ソース | 全ロジック（単一ファイル） |
| Makefile | `usr.bin/du/Makefile` | ビルド | ビルド設定 |
