# 通知設計書 20-Interop.Sys.INotify (IN_CREATE)

## 概要

本ドキュメントは、Linux の inotify サブシステムが提供する `IN_CREATE` 通知について、.NET ランタイムでの実装詳細と設計仕様を記述した通知設計書である。

### 本通知の処理概要

IN_CREATE は、監視対象ディレクトリ内に新しいファイルまたはディレクトリが作成された際に Linux カーネルの inotify サブシステムが生成する通知イベントである。.NET の FileSystemWatcher では、この通知を Created イベントに変換してアプリケーションに通知する。

**業務上の目的・背景**：新規ファイルの作成検知は、ファイル同期、自動バックアップ、ログ監視、データ取り込みパイプラインなど、多くのアプリケーションシナリオで中核的な役割を果たす。IN_CREATE は NotifyFilters に FileName または DirectoryName が設定されている場合に有効となり、ファイルやディレクトリの新規作成を検知するために使用される。

**通知の送信タイミング**：監視対象ディレクトリ内でファイルが open() + O_CREAT で作成された場合、または mkdir() でディレクトリが作成された場合に、カーネルが inotify イベントを生成する。このイベントは .NET の FileSystemWatcher.Linux 実装で処理され、Created イベントとしてアプリケーションに通知される。

**通知の受信者**：FileSystemWatcher インスタンスの Created イベントにハンドラを登録したアプリケーションコード。NotifyFilters に FileName または DirectoryName が含まれている必要がある。

**通知内容の概要**：inotify イベントとして、ウォッチ記述子（wd）、イベントマスク（IN_CREATE）、cookie（通常0）、ファイル名（name）が通知される。FileSystemWatcher は WatcherChangeTypes.Created としてアプリケーションに伝達する。

**期待されるアクション**：受信者は通知を受け取り後、ファイルの処理開始、同期先へのコピー、監視対象への追加（サブディレクトリの場合）、ログ記録などの処理を実行することが期待される。

## 通知種別

OSカーネル通知（inotify イベント）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（カーネルからの割り込み） |
| 優先度 | 通常（他の inotify イベントと同等） |
| リトライ | なし（カーネルは一度のみ通知） |

### 送信先決定ロジック

inotify_add_watch() で登録されたウォッチ記述子に対応する inotify ファイルディスクリプタに対してイベントが送信される。.NET では INotify クラスが全ての FileSystemWatcher で共有する単一の inotify インスタンスを管理する。

## 通知テンプレート

### inotify イベント構造

| 項目 | 内容 |
|-----|------|
| イベント型 | struct inotify_event |
| マスク値 | IN_CREATE (0x00000100) |
| cookie | 0（ペアイベントではない） |

### イベントデータ構造

```c
struct inotify_event {
    int      wd;       // ウォッチ記述子
    uint32_t mask;     // IN_CREATE = 0x00000100
    uint32_t cookie;   // 0
    uint32_t len;      // name の長さ
    char     name[];   // 作成されたファイル/ディレクトリ名（NULL終端）
};
```

### .NET での変換後

```csharp
// IN_CREATE は Created イベントに変換される
FileSystemEventArgs {
    ChangeType = WatcherChangeTypes.Created,
    FullPath = "監視ディレクトリ/ファイル名",
    Name = "ファイル名"
}
```

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| wd | ウォッチ記述子 | inotify_add_watch() の戻り値 | Yes |
| mask | イベントマスク | IN_CREATE (0x00000100) | Yes |
| cookie | イベント関連付け | 常に 0 | Yes |
| len | 名前長 | ファイル名のバイト長 + パディング | Yes |
| name | ファイル名 | 作成されたファイル/ディレクトリの名前 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| システムコール | open() + O_CREAT | ウォッチにIN_CREATEが設定されている | ファイル作成時 |
| システムコール | creat() | ウォッチにIN_CREATEが設定されている | ファイル作成時 |
| システムコール | mkdir() | ウォッチにIN_CREATEが設定されている | ディレクトリ作成時 |
| システムコール | mknod() | ウォッチにIN_CREATEが設定されている | 特殊ファイル作成時 |
| システムコール | link() | ウォッチにIN_CREATEが設定されている | ハードリンク作成時 |
| システムコール | symlink() | ウォッチにIN_CREATEが設定されている | シンボリックリンク作成時 |

### .NET での有効化条件

| 条件 | 説明 |
|-----|------|
| NotifyFilters.FileName | ファイルの作成検知（内部的に常に有効） |
| NotifyFilters.DirectoryName | ディレクトリの作成検知（内部的に常に有効） |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| NotifyFilters に FileName/DirectoryName なし | 作成イベントが通知されない |
| フィルタ不一致 | Filter/Filters パターンにマッチしない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[open O_CREAT / mkdir 実行] --> B[カーネル: inotify イベント生成]
    B --> C[inotify キューに追加]
    C --> D[.NET: ProcessEvents スレッド]
    D --> E[TryReadEvent でイベント読み取り]
    E --> F{mask & IN_CREATE?}
    F -->|Yes| G{isDir & IncludeSubdirectories?}
    F -->|No| H[他のイベント処理]
    G -->|Yes| I[新ディレクトリの監視追加]
    G -->|No| J[WatcherEvent.Created 生成]
    I --> J
    J --> K[_eventQueue に追加]
    K --> L[EmitEvent]
    L --> M[fsw.NotifyFileSystemEventArgs]
    M --> N[OnCreated 呼び出し]
    N --> O[終了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（OSカーネル通知のためデータベースを使用しない）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| IN_Q_OVERFLOW | inotify イベントキューが溢れた | Error イベント発生、監視再起動 |
| ENOSPC | ウォッチ数上限超過（サブディレクトリ追加時） | Error イベントで通知 |
| EBADF | 無効なファイルディスクリプタ | 監視を停止 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（カーネルイベントはリトライされない） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | カーネル設定依存（/proc/sys/fs/inotify/max_queued_events） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（24時間監視可能）

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

- 作成されたファイルのパスが通知に含まれる
- 監視対象ディレクトリへの読み取り権限が必要
- 他ユーザーによるファイル作成は、適切な権限がない限り監視できない

## 備考

- IN_CREATE は .NET の FileSystemWatcher で常に登録される（TranslateFilters で追加）
- IncludeSubdirectories が true の場合、新しく作成されたディレクトリに対しても監視が追加される
- 作成直後のファイルはまだ書き込み中の可能性があるため、処理前にファイルの完了を待つ必要がある場合がある
- 一時ファイルの作成と即座の削除ではイベントが欠落する可能性がある

---

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

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

### 推奨読解順序

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

まず、IN_CREATE の定義と関連する定数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Interop.INotify.cs | `src/libraries/Common/src/Interop/Linux/System.Native/Interop.INotify.cs` | IN_CREATE 定数の定義（0x00000100） |

**読解のコツ**: NotifyEvents enum で IN_CREATE = 0x00000100 として定義されている点に注目。

#### Step 2: フィルタマッピングを理解する

NotifyFilters から inotify イベントへの変換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FileSystemWatcher.Linux.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs` | TranslateFilters メソッドでの IN_CREATE の常時追加 |

**主要処理フロー**:
- **行 1255-1257 (Linux.cs)**: IN_CREATE は常にサブスクライブされる
- **行 642-652 (Linux.cs)**: ディレクトリ作成時の追加監視処理

#### Step 3: イベント処理を理解する

IN_CREATE イベントの処理フローを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | FileSystemWatcher.Linux.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs` | ProcessEvent での IN_CREATE 処理 |

**主要処理フロー**:
- **行 519-523 (Linux.cs)**: FileDirEvents に IN_CREATE が含まれる定義
- **行 679-681 (Linux.cs)**: IN_CREATE イベントで WatcherEvent.Created を生成
- **行 640-652 (Linux.cs)**: IncludeSubdirectories でのサブディレクトリ監視追加

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

```
[Linux カーネル]
inotify イベント (IN_CREATE)
    │
    ▼
[.NET FileSystemWatcher.Linux]
INotify.ProcessEvents()
    │
    ├─ TryReadEvent() → NotifyEvent 構造体
    │
    └─ ProcessEvent()
           │
           ├─ mask & IN_CREATE 判定
           │
           ├─ [isDir & IncludeSubdirectories]
           │      └─ WatchChildDirectories() → 新ディレクトリを監視に追加
           │
           └─ WatcherEvent.Created(dir, name)
                  │
                  ▼
           Watcher.QueueEvent()
                  │
                  ▼
           EmitEvent()
                  │
                  ▼
           fsw.NotifyFileSystemEventArgs(Created, name)
                  │
                  ▼
           OnCreated()
```

### データフロー図

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

open(O_CREAT)           カーネル inotify
システムコール  ───▶    イベント生成  ───▶   inotify キュー
                              │
                              ▼
                        .NET read() ───▶   NotifyEvent 構造体
                              │
                              ▼
                        ProcessEvent()
                              │
               ┌──────────────┴──────────────┐
               ▼                              ▼
        [ディレクトリ作成]              [ファイル作成]
               │                              │
               ▼                              │
        WatchChildDirectories()              │
        (IncludeSubdirectories時)            │
               │                              │
               └──────────────┬──────────────┘
                              ▼
                        WatcherEvent.Created
                              │
                              ▼
                        FileSystemEventArgs ───▶  Created イベント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Interop.INotify.cs | `src/libraries/Common/src/Interop/Linux/System.Native/Interop.INotify.cs` | ソース | IN_CREATE 定数定義 |
| FileSystemWatcher.Linux.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs` | ソース | IN_CREATE イベント処理、サブディレクトリ監視追加 |
| FileSystemWatcher.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs` | ソース | NotifyFilters、Created イベント定義 |
| FileSystemEventArgs.cs | `src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemEventArgs.cs` | ソース | Created イベント引数 |
