3.3.4.6 Object Store Indicates an Oplock Break
The underlying object store on the local resource indicates the breaking of an opportunistic lock, specifying the LocalOpen and the new oplock level, a status code of the oplock break, and optionally expects the new oplock level in return. The new oplock level SHOULD<240> be SMB2_OPLOCK_LEVEL_NONE or SMB2_OPLOCK_LEVEL_II or SMB2_OPLOCK_LEVEL_EXCLUSIVE. The conditions under which each oplock level is to be indicated are described in [MS-FSA] section 2.1.5.18.3.
The server MUST locate the open by walking the GlobalOpenTable to find an entry whose Open.LocalOpen matches the one provided in the oplock break. If no entry is found, the break indication MUST be ignored and the server MUST complete the oplock break call with SMB2_OPLOCK_LEVEL_NONE as the new oplock level.
If an entry is found, the server MUST perform the following:
For the specified Open, the server MUST select the connection as specified in section 3.3.4.1.6. If no connection is available, Open.IsResilient is FALSE, Open.IsDurable is FALSE, and Open.IsPersistent is FALSE, the server SHOULD close the Open as specified in section 3.3.4.17.
The server MUST construct an Oplock Break Notification following the syntax specified in section 2.2.23.1 to send back to the client. The server MUST set the Command in the SMB2 header to SMB2 OPLOCK_BREAK, and the MessageId to 0xFFFFFFFFFFFFFFFF. The server SHOULD<241> set the SessionId in the SMB2 header to Open.Session.SessionId. The server MUST set the TreeId in the SMB2 header to zero. The FileId field of the response structure MUST be set to the values from the Open structure, with the volatile part set to Open.FileId and the persistent part set to Open.DurableFileId. The oplock Level of the response MUST be set to the value provided by the object store. The server MUST set Open.OplockState to Breaking and set Open.OplockTimeout to the current time plus an implementation-specific default value in milliseconds.<242> The message SHOULD NOT be signed.
If the server implements the SMB 3.x dialect family, SMB2 Oplock Break Notification MUST be sent to the client using the first available connection in Open.Session.ChannelList where Channel.Connection is not NULL. If the server fails to send the notification to the client, the server MUST retry the send using an alternate connection, if available, in Open.Session.ChannelList.
Otherwise, SMB2 Oplock Break Notification MUST be sent to the client using Open.Connection.
If the notification could not be sent on any connection, the server MUST complete the oplock break from the underlying object store with SMB2_OPLOCK_LEVEL_NONE as the new oplock level and MUST set Open.OplockLevel to SMB2_OPLOCK_LEVEL_NONE and Open.OplockState to None.
If the server succeeds in sending the notification, the server MUST start the oplock break acknowledgment timer as specified in section 3.3.2.1.