SMB2 CHANGE_NOTIFY 能否用于保存远程目录列表的准确快照?
Can SMB2 CHANGE_NOTIFY be used to keep an accurate snapshot of a remote directory listing?
SMB2 CHANGE_NOTIFY 看起来很有前途,好像它可以从服务器提供有关子目录或子树更新的足够信息,因此我们可以通过处理响应使我们的远程目录列表保持最新。
但是,它不是对事件流的订阅,只是接收一个响应的一次性命令,所以我怀疑它只能用作使我们的缓存无效并重新读取目录的提示。当我们收到回复时,在我们发送另一个 CHANGE_NOTIFY 请求之前可能会有任何其他更改,我们将错过这些更改的详细信息。
有什么办法可以解决这个问题吗?还是重新阅读目录以了解它已更新是必要的步骤?
我想了解协议级别的可能解决方案(你可以想象我正在使用一个自定义的客户端,我可以做我想做的事,使用一些常见的服务器,如 Windows 或 smbd3)。
严格来说,即使重新阅读目录列表也无济于事,因为目录可能会在重新阅读列表和提交另一个 CHANGE_NOTIFY 请求之间发生变化。竞争条件只是移动到不同的位置。
除非没有竞争条件。
这需要一点挖掘,但规范中都有。在MS-SMB2 v20200826 §3.3.5.19 ‘Receiving an SMB2 CHANGE_NOTIFY Request’中表示:
The server MUST process a change notification request in the object store as specified by the algorithm in section 3.3.1.3.
在 §3.3.1.3 ‘Algorithm for Change Notifications in an Object Store’中,我们有:
The server MUST implement an algorithm that monitors for changes on an object store. The effect of this algorithm MUST be identical to that used to offer the behavior specified in [MS-CIFS] sections 3.2.4.39 and 3.3.5.59.4.
而在 MS-CIFS v20201001 §3.3.5.59.4 ‘Receiving an NT_TRANSACT_NOTIFY_CHANGE Request' 中是这样的:
If the client has not issued any NT_TRANSACT_NOTIFY_CHANGE Requests on this FID previously, the server SHOULD allocate an empty change notification buffer and associate it with the open directory. The size of the buffer SHOULD be at least equal to the MaxParameterCount field in the SMB_COM_NT_TRANSACT Request (section 2.2.4.62.1) used to transport the NT_TRANSACT_NOTIFY_CHANGE Request. If the client previously issued an NT_TRANSACT_NOTIFY_CHANGE Request on this FID, the server SHOULD already have a change notification buffer associated with the FID. The change notification buffer is used to collect directory change information in between NT_TRANSACT_NOTIFY_CHANGE (section 2.2.7.4) calls that reference the same FID.
强调我的。这与 how Samba implements it 一致(fsp
结构在各个请求之间持续存在)。我不认为微软会因为不遵守他们在自己的规范中做出的承诺而做得更糟。
SMB2 CHANGE_NOTIFY 看起来很有前途,好像它可以从服务器提供有关子目录或子树更新的足够信息,因此我们可以通过处理响应使我们的远程目录列表保持最新。
但是,它不是对事件流的订阅,只是接收一个响应的一次性命令,所以我怀疑它只能用作使我们的缓存无效并重新读取目录的提示。当我们收到回复时,在我们发送另一个 CHANGE_NOTIFY 请求之前可能会有任何其他更改,我们将错过这些更改的详细信息。
有什么办法可以解决这个问题吗?还是重新阅读目录以了解它已更新是必要的步骤?
我想了解协议级别的可能解决方案(你可以想象我正在使用一个自定义的客户端,我可以做我想做的事,使用一些常见的服务器,如 Windows 或 smbd3)。
严格来说,即使重新阅读目录列表也无济于事,因为目录可能会在重新阅读列表和提交另一个 CHANGE_NOTIFY 请求之间发生变化。竞争条件只是移动到不同的位置。
除非没有竞争条件。
这需要一点挖掘,但规范中都有。在MS-SMB2 v20200826 §3.3.5.19 ‘Receiving an SMB2 CHANGE_NOTIFY Request’中表示:
The server MUST process a change notification request in the object store as specified by the algorithm in section 3.3.1.3.
在 §3.3.1.3 ‘Algorithm for Change Notifications in an Object Store’中,我们有:
The server MUST implement an algorithm that monitors for changes on an object store. The effect of this algorithm MUST be identical to that used to offer the behavior specified in [MS-CIFS] sections 3.2.4.39 and 3.3.5.59.4.
而在 MS-CIFS v20201001 §3.3.5.59.4 ‘Receiving an NT_TRANSACT_NOTIFY_CHANGE Request' 中是这样的:
If the client has not issued any NT_TRANSACT_NOTIFY_CHANGE Requests on this FID previously, the server SHOULD allocate an empty change notification buffer and associate it with the open directory. The size of the buffer SHOULD be at least equal to the MaxParameterCount field in the SMB_COM_NT_TRANSACT Request (section 2.2.4.62.1) used to transport the NT_TRANSACT_NOTIFY_CHANGE Request. If the client previously issued an NT_TRANSACT_NOTIFY_CHANGE Request on this FID, the server SHOULD already have a change notification buffer associated with the FID. The change notification buffer is used to collect directory change information in between NT_TRANSACT_NOTIFY_CHANGE (section 2.2.7.4) calls that reference the same FID.
强调我的。这与 how Samba implements it 一致(fsp
结构在各个请求之间持续存在)。我不认为微软会因为不遵守他们在自己的规范中做出的承诺而做得更糟。