Oplock 和网络重定向程序

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

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

Oplock 概述

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

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

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

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

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

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

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

Oplock 密钥

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

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

如果满足以下所有条件,则 oplock 中断:

  • 在除授予 oplock 的句柄之外的其他句柄上接收到文件操作。
  • 与 oplock 句柄关联的 oplock 键不同于与操作句柄关联的键。
  • 该操作与当前授予的 oplock 不兼容。

即使同一进程或线程执行不兼容的操作,Op锁也会中断。 例如,当独占 oplock 立即中断时:

  1. 进程打开一个已被授予独占 Oplock 的数据流。
  2. 同一进程使用不同的(或没有)机会锁密钥再次打开同一流。

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

请记住,作锁键存在于句柄上,并在创建句柄时将其“置于”句柄上。 即使没有授予 oplock 密钥,也可以将句柄与 oplock 密钥关联。