フィルター ドライバーの BypassIO
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 と呼ばれます。
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 関数
さらに、次の DDI が BypassIO をサポートするように変更されました。
- 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 圧縮を有効にできません。
NTFS 暗号化は、BypassIO がアクティブなファイルで有効にできます。 BypassIO は一時停止されます。
BypassIO はオフロードの読み取り/書き込み操作には影響しません。