以下示例显示数据移动和 SMB 消息移动,因为机会锁是制造和损坏的。 请注意,客户端可以缓存文件属性数据和文件数据。
另请注意,这些示例基于客户端应用程序从远程服务器请求机会锁的情况。 这些进程由网络重定向程序和远程服务器自动启动,客户端应用程序或应用程序没有直接参与。 这些示例描述的过程可以通用化为本地客户端应用程序直接从本地文件系统请求机会锁的情况,但例外情况是,不涉及通过网络交换数据。
级别 1 机会锁
下图显示了文件上级别 1 机会锁的网络流量视图。 箭头指示数据移动的方向(如果有)。
事件 | 客户端 X | 服务器 | 客户端 Y |
---|---|---|---|
1 | 打开文件,请求级别 1 锁定 ==> | ||
2 | <== 授予级别 1 机会锁 | ||
3 | 执行读取、写入和其他作 ==> | ||
4 | <== 打开文件的请求 | ||
5 | <== 中断机会锁 | ||
6 | 放弃预读数据 | ||
7 | 写入数据 ==> | ||
8 | 发送“close”或“done”消息 ==> | ||
9 | 正常打开作 ==> | ||
10 | 执行读取、写入和其他作 ==> | <== 执行读取、写入和其他作 |
在事件 1 中,客户端 X 将打开一个文件,作为打开作的一部分,请求对文件进行级别 1 的机会锁。 在事件 2 中,服务器授予级别 1 锁,因为没有其他客户端打开文件。 客户端在事件 3 中以通常的方式访问文件。
在事件 4 中,客户端 Y 尝试打开该文件并请求机会锁。 服务器看到客户端 X 已打开文件。 当客户端 X 刷新任何写入数据并放弃文件的读取缓存时,服务器会忽略 Y 的请求。
服务器通过发送到 XMB 消息来强制 X 清除机会锁(事件 5)。 客户端 X“无提示”放弃任何预读数据;换句话说,此过程不会生成任何网络流量。 在事件 7 中,客户端 X 会将任何缓存的写入数据写入服务器。 客户端 X 将缓存数据写入服务器后,客户端 X 会将“close”或“done”消息发送到服务器,事件 8。
服务器收到通知后,客户端 X 将写入缓存刷新到服务器或关闭文件后,服务器可以在事件 9 中打开客户端 Y 的文件。 由于服务器现在有两个客户端打开同一个文件,因此它向两个客户端授予机会锁。 这两个客户端都继续从文件读取,一个或两个客户端都没有写入文件。
Batch 机会锁
下图显示了批处理机会锁的网络流量视图。 箭头指示数据移动的方向(如果有)。
事件 | 客户端 X | 服务器 | 客户端 Y |
---|---|---|---|
1 | 打开文件,请求批处理锁 ==> | ||
2 | <== 授予批处理机会锁 | ||
3 | 读取文件 ==> | ||
4 | <== 发送数据 | ||
5 | 关闭文件 | ||
6 | 打开文件 | ||
7 | 搜索数据 | ||
8 | 读取数据 ==> | ||
9 | <== 发送数据 | ||
10 | 关闭文件 | ||
11 | <== 打开文件 | ||
12 | <== 中断机会锁 | ||
13 | 关闭文件 ==> | ||
14 | 正常打开作 ==> | ||
15 | <== 执行读取、写入和其他作 |
在批处理机会锁中,客户端 X 打开文件、事件 1,服务器在事件 2 中向客户端 X 授予批处理锁。 客户端 X 尝试读取数据,事件 3,服务器使用数据响应的事件 4。
事件 5 显示工作中的批处理机会锁。 客户端 X 上的应用程序关闭文件。 但是,网络重定向程序会筛选掉关闭作,并且不会传输关闭消息,从而执行“无提示”关闭作。 网络重定向程序可以执行此作,因为客户端 X 拥有文件的唯一所有权。 稍后,在事件 6 中,应用程序将重新打开该文件。 同样,没有数据流过网络。 就服务器而言,此客户端自事件 2 以来已打开文件。
事件 7、8 和 9 显示网络流量的正常过程。 在事件 10 中,发生另一个无提示关闭。
在事件 11 中,客户端 Y 尝试打开该文件。 服务器的文件视图是客户端 X 已打开它,即使客户端 X 上的应用程序已关闭它。 因此,服务器向客户端 X 发送中断机会锁的消息。客户端 X 现在通过网络事件 13 发送关闭消息。 事件 14 后,服务器打开客户端 Y 的文件。客户端 X 上的应用程序已关闭文件,因此不会再向或传出该文件的服务器传输。 客户端 Y 在事件 15 中照常开始数据传输。
在客户端 X 在事件 2 中授予对文件的锁和事件 13 的最后关闭时间之间,客户端缓存的任何文件数据都是有效的,尽管干预应用程序打开和关闭作。 但是,在机会锁断开后,缓存的数据不能被视为有效。
筛选机会锁
下图显示了筛选器机会锁的网络流量视图。 箭头指示数据移动的方向(如果有)。
事件 | 客户端 X | 服务器 | 客户端 Y |
---|---|---|---|
1 | 打开没有访问权限 ==> 的文件 | ||
2 | <== 打开文件 | ||
3 | 请求筛选器 lock==> | ||
4 | <== 授予锁定 | ||
5 | 打开用于读取 ==> 的文件 | ||
6 | <== 重新打开文件 | ||
7 | 使用读取句柄 ==> 读取数据 | ||
8 | <== 发送数据 | ||
9 | <== 发送数据 | ||
10 | <== 发送数据 | ||
11 | <== 打开文件 | ||
12 | 打开文件 ==> | ||
13 | <== 请求筛选器锁 | ||
14 | 拒绝筛选器 lock==> | ||
15 | <== 读取数据 | ||
16 | 发送数据 ==> | ||
17 | 读取(缓存)数据 | ||
18 | 关闭文件 ==> | ||
19 | <== 关闭文件 |
在筛选器机会锁中,客户端 X 打开文件、事件 1,服务器在事件 2 中响应。 然后,客户端在事件 3 中请求筛选器机会锁,然后是服务器在事件 4 中授予机会锁。 然后,客户端 X 再次打开文件,以便在事件 5 中读取,服务器在事件 6 中响应该文件。 然后,客户端会尝试读取服务器使用数据(事件 8)响应的数据。
事件 9 显示工作中的筛选器机会锁。 服务器在客户端之前读取数据,并通过网络发送数据,即使客户端尚未请求它。 客户端缓存数据。 在事件 10 中,服务器还预计将来会请求数据,并发送文件的另一部分供客户端缓存。
在事件 11 和 12 中,另一个客户端 Y 将打开该文件。 客户端 Y 还请求筛选器机会锁。 在事件 14 中,服务器拒绝它。 在事件 15 中,客户端 Y 请求服务器在事件 16 中发送的数据。 这不会影响客户端 X。随时,另一个客户端可以打开此文件进行读取访问。 其他任何客户端都不会影响客户端 X 的筛选器锁。
事件 17 显示客户端 X 读取数据。 但是,由于服务器已发送数据,并且客户端已缓存数据,因此不会有流量穿过网络。
在此示例中,客户端 X 从不尝试读取文件中的所有数据,因此事件 9 和 10 指示的预读被“浪费”;也就是说,从未实际使用过数据。 这是可接受的损失,因为预读加速了应用程序。
在事件 18 中,客户端 X 关闭文件。 客户端的网络重定向程序放弃缓存的数据。 服务器关闭文件。