Oplock 和网络重定向程序

网络重定向程序使用机会锁 (oplock) 来优化文件访问性能,减少客户端-服务器环境中的网络流量。

本文档面向网络重定向程序开发人员,但某些信息也适用于客户端应用程序开发人员。 有关客户端应用程序的更多 oplock 文档,请参阅 Windows SDK 的机会锁文章。

Oplock 概述

oplock(机会锁)是由客户端放置在驻留在服务器上的文件中的锁。 在大多数情况下,客户端会请求一个 oplock,以便在本地缓存数据。 远程服务器客户端的网络重定向程序和本地服务器的客户端应用程序都使用 Oplock。 有关各种当前和旧版 oplock 的描述,请参阅 oplock 类型

Oplock 允许文件服务器客户端(如使用 SMB 和 SMB2 协议的客户端)以一致的方式动态更改给定文件或的缓冲策略。 使用 oplock 可以提高性能,减少网络使用。 为了提高远程文件操作的网络性能,客户端可以在本地缓冲文件数据,从而减少或消除发送和接收网络数据包的需要。 例如:

  • 如果客户端知道没有其他进程在访问远程服务器上的数据,那么客户端可能就不必将信息写入该文件中。
  • 如果客户端知道没有其他进程正在向远程文件写入数据,则可以缓冲来自远程文件的预读数据。

应用程序和驱动程序还可以使用 oplock 来透明地访问文件,而不会影响可能需要使用这些文件的其他应用程序。

NTFS 等文件系统支持每个文件多个数据流。 系统会在流句柄上授予 oplock,这意味着 oplock 是针对特定文件流的打开而授予的,而操作也适用于该文件流。 除了少数例外情况,对一个数据流的操作不会影响另一个数据流上的 oplock。 有关详细信息,请参阅请求和授予 oplock

对于不支持备用数据流的文件系统(如 FAT),当 oplock 讨论提到“流”时,应想到是“文件”。

oplock 包的核心 oplock 功能在内核中实现,主要通过 FsRtlXxx 例程实现,例如 FsRtlInitializeOplock。 文件系统会调用该包,以在其文件系统中实现 oplock 功能。 本部分中的 oplock 文章介绍了 NTFS 文件系统如何与内核 oplock 包互操作。 其他文件系统的功能与此类似,但可能存在细微差别。

Oplock 密钥

流句柄可与 oplock 密钥 关联,这是一个 GUID 值,用于识别属于同一客户端缓存视图的多个句柄。 更准确地说,oplock 密钥与流句柄指向的 FILE_OBJECT 结构相关联。 当句柄被复制时,例如使用 DuplicateHandle 时,这种区别就非常重要。 每个重复句柄都指向相同的基础 FILE_OBJECT 结构。

在创建流句柄时,可以显式提供 oplock 密钥(向 IoCreateFileEx 提供)。 如果在创建句柄时没有显式指定 oplock 密钥,系统就会将句柄视为与之关联的唯一 oplock 密钥。 这个独一无二的密钥不同于任何其他句柄上的密钥。

oplock 在以下情况时会被中断:

  • 在授予 oplock 的句柄以外的句柄上接收到文件操作,以及
  • 与 oplock 句柄相关的 oplock 密钥不同于与操作句柄相关的密钥,以及
  • 该操作与当前授予的 oplock 不兼容。

即使执行不兼容操作的是同一个进程或线程,也会中断 oplock。 例如,在以下情况时,专属 oplock 会立即被中断:

  1. 进程打开一个已被授予独占 Oplock 的数据流。
  2. 然后,同一进程使用不同(或不使用)oplock 密钥再次打开同一数据流。

有关详细信息,请参阅中断 oplock

请记住,oplock 密钥存在于句柄上,在创建句柄时就已“安装”在句柄上。 即使没有授予 oplock 密钥,也可以将句柄与 oplock 密钥关联。