BypassIO について
BypassIO 機能は、ファイルからの読み取りに最適化された入出力パスを提供します。 このパスにより、読み取りの CPU オーバーヘッドが削減され、Windows での次世代ゲームの読み込みと実行に関する I/O の要求を満たすのに役立ちます。 BypassIO は、Windows 上の DirectStorage をサポートするインフラストラクチャの一部です。 Windows 11 以降で利用可能です。
ミニフィルターは BypassIO のサポートを実装し、可能な限り BypassIO を有効にしておくことが重要です。 フィルターをサポートしないと、ゲームのパフォーマンスが低下し、エンド ユーザーのゲーム エクスペリエンスが低下します。
今後の Windows リリースには、ゲーム以外の広範なアプリケーションの使用が含まれます。
BypassIO はハンドルごとの概念です。 BypassIO を要求するときは、明示的なファイル ハンドルを要求します。 BypassIO は、そのファイルの他のハンドルには影響しません。
FSCTL_MANAGE_BYPASS_IO と同等の IOCTL_STORAGE_MANAGE_BYPASS_IO がこのインフラストラクチャの一部として追加されました。 ミニフィルターは FSCTL_MANAGE_BYPASS_IO処理しますが、ファイル システムはボリュームとストレージ スタックに IOCTL_STORAGE_MANAGE_BYPASS_IO を送信します。 これらの制御コードは、診断可能に設計されています。これらはどちらも、BypassIO 要求に失敗したドライバーの ID と拒否の理由を返します。
この記事では、ファイル システム フィルターとストレージ スタック全体のアーキテクチャの詳細と、ミニフィルター ドライバーで BypassIO を実装する方法について説明します。 ストレージ ドライバーに固有の BypassIO 情報については、ストレージ ドライバーの BypassIO を参照してください。
BypassIO サポートの範囲
Windows 11 以降、BypassIO のサポートには次の機能が含まれています。
Windows クライアント システムでのサポートのみ。 サーバー システムのサポートは、今後のリリースで提供される予定です。
NVMe ストレージ デバイスでのサポートのみ。 他のストレージ テクノロジのサポートは、今後のリリースで提供される予定です。
NTFS ファイル システムでのみサポートされます。 他のファイル システムのサポートは、今後のリリースで提供される予定です。
キャッシュされていない読み取り専用のサポート。 キャッシュされていない書き込みのサポートは、今後のリリースで提供される予定です。
ファイルのみのサポート (ディレクトリまたはボリューム ハンドルではサポートされていません)。
BypassIO のしくみ
BypassIO 対応 FileHandle で NtReadFile を呼び出すと、通常、この操作は従来の I/O スタックを通過せず、ファイル システム スタック、ボリューム スタック、ストレージ スタック全体を走査します。 そうではなく、操作は I/O マネージャーから (NTFS) ファイル システム、次にディスク (classpnp) ドライバー、それから StorNVMe ドライバーへと直接フローします。 完全に BypassIO が有効な FileHandle では、次のようになります。
- この操作では、すべてのファイル システム フィルターがスキップされます。
- この操作では、すべてのボリューム スタック フィルターがスキップされます。
- この操作では、ディスク ドライバーの上、およびディスクドライバーと StorNVMe ドライバーの間にあるすべての記憶域スタック フィルターとドライバーがスキップされます。
ファイル システム フィルター スタックが BypassIO をサポートしているが、ボリュームとストレージ スタックではサポートされないシナリオでは、次の操作が行われます。
- 読み取り IO はフィルター スタックをバイパスします。
- IO の読み取りは引き続きボリュームとストレージ スタックを通過します。
このレベルのサポートは、部分 BypassIO と呼ばれます。
読み取り要求の従来の I O パスを示す画像。
読み取り要求のバイパス I O パスを示す画像。
BypassIO の DDI の変更と追加
BypassIO のサポートを提供するため、フィルター ドライバーに関連する次の DDI が追加されました。
- FltVetoBypassIo 関数
- FS_BPIO_INFLAGS 列挙子
- FS_BPIO_INFO 構造体
- FS_BPIO_INPUT 構造体
- FS_BPIO_OPERATIONS 列挙子
- FS_BPIO_OUTFLAGS 列挙子
- FS_BPIO_OUTPUT 構造体
- FS_BPIO_RESULTS 構造体
- FSCTL_MANAGE_BYPASS_IO 制御コード
- FsRtlGetBypassIoOpenCount 関数
さらに、BypassIO をサポートするように次の DDI が変更されました。
- BypassIoOpenCount フィールドが FSRTL_ADVANCED_FCB_HEADER 構造体に追加されました。 ファイル システムは、このフィールドを使って、現在 BypassIO が有効になっているストリーム上の一意の FileObject の数を保持します。 このフィールドの追加により、構造体のサイズが大きくなります。 Windows 11 以降で使用する構造体のバージョンは FSRTL_FCB_HEADER_V4 です。
BypassIO が有効なハンドルに対する他の操作の影響
ハンドルで BypassIO を有効にしても、他のハンドルには影響しません。 ただし、次のシナリオのような、BypassIO が有効なハンドルに対する他の操作は、BypassIO の使用に影響します。
BypassIO が有効で機能しているファイルに対してハンドル A を開いている場合に、他のユーザー (別のスレッドやプロセスなど) がハンドル B を開いてキャッシュ IO やメモリ マップ IO を実行すると、ハンドル B が閉じられるまで、ハンドル A での BypassIO は一時的に中断されます。 代わりに、システムは従来の I/O パスを使って、古いデータが発生しないことを保証します。 すべてのデータ セクションとキャッシュ マップが破棄されるまで、システムはそのハンドル上の従来の入出力パスを引き続き使用します。 その結果、BypassIO を再開する前に、フィルターでハンドルのファイルを閉じる必要があります。
BypassIO が有効なファイルがスパースとしてマークされている場合、すべての BypassIO 操作は従来の I/O パスを使って開始します。
BypassIO が有効なファイルを最適化している間は、すべての BypassIO 操作で従来の I/O パスが使われます。 最適化が完了すると、システムはそのハンドルの BypassIO パスに戻ります。
ミニフィルターでの BypassIO のサポートの実装
INF または MANIFEST ファイルを更新する
Windows 11 以降では、フィルター開発者はドライバーの INF または MANIFEST ファイルの SupportedFeatures に SUPPORTED_FS_FEATURES_BYPASS_IO を追加する必要があります。 (管理者特権でのコマンド プロンプトで「fltmc instances」と入力して、すべてのアクティブなフィルターの "SprtFtrs" 値を確認できます)。
Note
BypassIO をサポートしないフィルターでは、引き続き SupportedFeatures 状態にSUPPORTED_FS_FEATURES_BYPASS_IOを追加し、その理由を指定してフィルター内で適切に拒否する必要があります。
ミニフィルターでは、可能な限り BypassIO の拒否を最小限にすることをお勧めします。
BypassIO が有効にされているボリュームにアタッチされたミニフィルターで、SUPPORTED_FS_FEATURES_BYPASS_IO を含むように SupportedFeatures の設定を更新していない場合、そのボリュームでのすべての BypassIO 操作はすぐにブロックされ、従来の I/O パスにフォールバックするので、ゲームのパフォーマンスが低下します。
IRP_MJ_READまたはIRP_MJ_WRITEフィルターを適用しないミニフィルターは、SupportedFeatures にSUPPORTED_FS_FEATURES_BYPASS_IOを追加したかのように、BypassIO サポートに自動的にオプトインします。
オプトインしていないミニフィルターがアタッチされている場合、スタックでのFS_BPIO_OP_ENABLE 操作と FS_BPIO_OP_QUERY 操作は失敗します。
BypassIO 要求のサポートを実装する
ミニフィルターでは、FSCTL_MANAGE_BYPASS_IO 制御コードを通して送信される BypassIO 要求のサポートを追加する必要があります。 詳しくは、「BypassIO 操作のサポート」をご覧ください。
BypassIO が機能しているかどうかの判断
追加された fsutil コマンドは、FS_BPIO_OP_QUERY 操作を指定する FSCTL_MANAGE_BYPASS_IO を発行します。 表示された結果は、BypassIO を妨げる最初のドライバーとその理由を識別します。
> fsutil bypassIo state /v <path>
<path> にはボリューム、ディレクトリ、または特定のファイル名を指定でき、/v はオプションの詳細フラグです。
この最初の例では、WOF ミニフィルターは BypassIO をオプトインしません。 fsutil bypassIo state c:\ コマンドを実行すると、次の出力が得られます。
BypassIo on "c:\" is not currently supported.
Status: 506 (At least one minifilter does not support bypass IO)
Driver: wof.sys
Reason: The specified minifilter does not support bypass IO.
この 2 番目の例では、BitLocker が有効になっているシステムで fsutil bypassIO state /v c:\ を実行すると、次の出力が得られます。
BypassIo on "c:\" is partially supported
Volume stack bypass is disabled (fvevol.sys)
Status: 495 (The specified operation is not supported while encryption is enabled on the target object)
Reason: BitLocker Drive Encryption is enabled.
Storage Type: NVMe
Storage Driver: BypassIo compatible
Driver Name: stornvme.sys
NTFS 固有の動作
NTFS 常駐ファイルで BypassIO を有効にすることができます。ただし、ファイルは常駐している限り、従来の I/O パスを受け取ります。 ファイルへの書き込みによってファイルが常駐ではなくなると、システムは BypassIO パスを使うように切り替えます。
BypassIO アクティブ ファイルで NTFS 圧縮を有効にすることはできません。
BypassIO アクティブ ファイルで NTFS 暗号化を有効にすることができます。 BypassIO は一時停止されます。
BypassIO はオフロードの読み取り/書き込み操作には影響しません。