筛选器驱动程序的 BypassIO

关于 BypassIO

BypassIO 功能为读取文件提供了优化的 I/O 路径。 该路径的目标是减少执行读取的 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 请求失败的驱动程序的标识,以及否决它的原因。

本页提供文件系统筛选器和存储堆栈的体系结构详细信息,以及如何在微型筛选器驱动程序中实现 BypassIO 的信息。 有关存储驱动程序专用的 BypassIO 信息,请参阅存储驱动程序的 BypassIO

BypassIO 支持的范围

从 Windows 11 开始,支持 BypassIO,如下所示:

  • 仅在 Windows 客户端系统上。 将在未来版本中将添加服务器系统支持。

  • 仅在 NVMe 存储设备上。 将来的版本中将添加对其他存储技术的支持。

  • 仅在 NTFS 文件系统上。 将来的版本中将添加对其他文件系统的支持。

  • 仅支持非缓存读取。 将在未来版本中添加对非缓存写入的支持。

  • 仅在文件上受支持(目录或卷句柄不支持)。

BypassIO 的工作原理

当在启用 BypassIO 的 FileHandle 上调用 NtReadFile 时,该操作通常不会流经传统的 I/O 堆栈,因为传统的 I/O 堆栈会遍历整个文件系统堆栈、卷堆栈和存储堆栈。 相反,操作直接从 I/O 管理器流向 (NTFS) 文件系统,然后流向磁盘 (classpnp) 驱动程序,最后流向 StorNVMe 驱动程序。 使用完全启用 BypassIO 的 FileHandle

  • 所有文件系统筛选器都会被跳过。
  • 所有卷堆栈筛选器都会被跳过。
  • 跳过磁盘驱动程序之上以及磁盘和 StorNVMe 驱动程序之间的所有存储堆栈筛选器和驱动程序。

在文件系统筛选器堆栈支持 BypassIO,但卷和/或存储堆栈不支持 BypassIO 的情况下:

  • 读取 IO 可绕过筛选器堆栈。
  • 读取 IO 仍通过卷和/或存储堆栈来发送。

此支持级别被称为部分 BypassIO。

显示了读取请求的传统 I O 路径的示意图。

显示了读取请求的旁路 I O 路径的示意图。

BypassIO 的 DDI 更改和新增内容

添加了以下与筛选器驱动程序相关的 DDI,以提供 BypassIO 支持:

此外,还更改了以下 DDI 以支持 BypassIO:

  • FSRTL_ADVANCED_FCB_HEADER 结构中添加了 BypassIoOpenCount 字段。 文件系统使用此字段来维护当前已启用 BypassIO 的流上唯一 FileObject 的计数。 增加这个字段会增大结构大小。 从 Windows 11 开始使用的结构版本是 FSRTL_FCB_HEADER_V4

其他操作对启用 BypassIO 的句柄的影响

在句柄上启用 BypassIO 不会对其他句柄造成影响。 但是,对启用 BypassIO 的句柄进行的其他操作确实会影响 BypassIO 的使用,例如以下情况:

  • 如果句柄 A 开启了 BypassIO 并在其上运行的文件,而某人(例如另一个线程或进程)打开了句柄 B 以执行缓存或内存映射 IO,那么句柄 A 上的 BypassIO 将被暂时中止,直到句柄 B 关闭为止。 系统会改为使用传统的 I/O 路径,以确保不会出现过时的数据。 系统将继续在该句柄上使用传统的 I/O 路径,直到所有数据段和缓存映射均被删除。 因此,筛选器必须在 BypassIO 恢复之前关闭句柄文件。

  • 如果启用 BypassIO 的文件被标记为稀疏,所有 BypassIO 操作都将使用传统 I/O 路径启动。

  • 删除启用 BypassIO 的文件会导致所有 BypassIO 操作都使用传统 I/O 路径。 一旦完成解码,系统就会切换回该句柄上的 BypassIO 路径。

在微型筛选器中实现 BypassIO 支持

更新 INF 或 MANIFEST 文件

从 Windows 11 开始,筛选器开发人员应在驱动程序的 INF 或 MANIFEST 文件中将 SUPPORTED_FS_FEATURES_BYPASS_IO 添加到 SupportedFeatures 中。 (可以在提升命令提示符下键入 fltmc instances,以便查看所有活动筛选器的“SprtFtrs”值。)

注意

永远无法支持 BypassIO 的筛选器仍应在其 SupportedFeatures 状态中添加 SUPPORTED_FS_FEATURES_BYPASS_IO,然后在筛选器内部进行适当的否决并说明原因。

鼓励微型筛选器尽可能减少对 BypassIO 的否决。

如果微型筛选器连接到已启用 BypassIO 的卷,但该微型筛选器尚未更新其 SupportedFeatures 设置以包括 SUPPORTED_FS_FEATURES_BYPASS_IO,则该卷上的所有 BypassIO 操作将立即被阻止,退回到传统 I/O 路径,从而导致游戏性能下降。

不筛选 IRP_MJ_READ 或 IRP_MJ_WRITE 的微型筛选器将自动选择加入 BypassIO 支持,就像它们在 SupportedFeatures 中添加了 SUPPORTED_FS_FEATURES_BYPASS_IO 一样。

如果堆栈中附加的微型筛选器没有选择加入,则 FS_BPIO_OP_ENABLEFS_BPIO_OP_QUERY 操作将失败。

实现对 BypassIO 请求的支持

微型筛选器应添加对 BypassIO 请求的支持,这些请求通过 FSCTL_MANAGE_BYPASS_IO 控制代码来发送。 有关详细信息,请参阅支持 BypassIO 操作

确定 BypassIO 是否正常工作

新增的 fsutil 命令会发出 FSCTL_MANAGE_BYPASS_IO,从而指定 FS_BPIO_OP_QUERY 操作。 显示的结果可确定阻止 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.

在第二个示例中,在启用了 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 不影响卸载读/写操作。