2.1.5.18 Server Requests an Oplock
The server provides:
Open - The Open on which the oplock is being requested.
Type - The type of oplock being requested. Valid values are as follows:
LEVEL_TWO (Corresponds to SMB2_OPLOCK_LEVEL_II as described in [MS-SMB2] section 2.2.13.)
LEVEL_ONE (Corresponds to SMB2_OPLOCK_LEVEL_EXCLUSIVE as described in [MS-SMB2] section 2.2.13.)
LEVEL_BATCH (Corresponds to SMB2_OPLOCK_LEVEL_BATCH as described in [MS-SMB2] section 2.2.13.)
LEVEL_GRANULAR (Corresponds to SMB2_OPLOCK_LEVEL_LEASE as described in [MS-SMB2] section 2.2.13.) If this oplock type is specified, the server MUST additionally provide the RequestedOplockLevel parameter.
RequestedOplockLevel - A combination of zero or more of the following flags, which are only given for LEVEL_GRANULAR Type Oplocks:
READ_CACHING
HANDLE_CACHING
WRITE_CACHING
Following is a list of legal nonzero combinations of RequestedOplockLevel:
READ_CACHING
READ_CACHING | WRITE_CACHING
READ_CACHING | HANDLE_CACHING
READ_CACHING | WRITE_CACHING | HANDLE_CACHING
Notes for the operation follow:
If the oplock is not granted, the request completes at this point.
If the oplock is granted, the request does not complete until the oplock is broken; the operation waits for this to happen. Processing of an oplock break is described in section 2.1.5.18.3. Whether the oplock is granted or not, the object store MUST return:
Status - An NTSTATUS code indicating the result of the operation.
If the oplock is granted, then when the oplock breaks and the request finally completes, the object store MUST additionally return:
NewOplockLevel: The type of oplock the requested oplock has been broken to. Valid values are as follows:
LEVEL_NONE (that is, no oplock)
LEVEL_TWO
A combination of one or more of the following flags:
READ_CACHING
HANDLE_CACHING
WRITE_CACHING
AcknowledgeRequired: A Boolean value; TRUE if the server MUST acknowledge the oplock break, FALSE if not, as specified in section 2.1.5.18.2.
Pseudocode for the operation is as follows:
If Open.Stream.StreamType is DirectoryStream:
The operation MUST be failed with STATUS_INVALID_PARAMETER under either of the following conditions:
Type is not LEVEL_GRANULAR.
Type is LEVEL_GRANULAR but RequestedOplockLevel is neither READ_CACHING nor (READ_CACHING|HANDLE_CACHING).
If Type is LEVEL_ONE or LEVEL_BATCH:
The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED under either of the following conditions:
Open.File.OpenList contains more than one Open whose Stream is the same as Open.Stream.
Open.Mode contains either FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT.
Request an exclusive oplock according to the algorithm in section 2.1.5.18.1, setting the algorithm's parameters as follows:
Pass in the current Open.
RequestedOplock equal to Type.
The operation MUST at this point return any status code returned by the exclusive oplock request algorithm.
Else If Type is LEVEL_TWO:
The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED under either of the following conditions:
Open.Stream.ByteRangeLockList is not empty and Open.Stream.AllocationSize is greater than any ByteRangeLock.LockOffset in Open.Stream.ByteRangeLockList.<195>
Open.Mode contains either FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT.
Request a shared oplock according to the algorithm in section 2.1.5.18.2, setting the algorithm's parameters as follows:
Pass in the current Open.
RequestedOplock equal to Type.
GrantingInAck equal to FALSE.
The operation MUST at this point return any status code returned by the shared oplock request algorithm.
Else If Type is LEVEL_GRANULAR:
If RequestedOplockLevel is READ_CACHING or (READ_CACHING|HANDLE_CACHING):
The operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED under either of the following conditions:
Open.Stream.ByteRangeLockList is not empty and Open.Stream.AllocationSize is greater than any ByteRangeLock.LockOffset in Open.Stream.ByteRangeLockList.<196>
Open.Mode contains either FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT.
Request a shared oplock according to the algorithm in section 2.1.5.18.2, setting the algorithm's parameters as follows:
Pass in the current Open.
RequestedOplock equal to RequestedOplockLevel.
GrantingInAck equal to FALSE.
The operation MUST at this point return any status code returned by the shared oplock request algorithm.
Else If RequestedOplockLevel is (READ_CACHING|WRITE_CACHING) or (READ_CACHING|WRITE_CACHING|HANDLE_CACHING):
If Open.Mode contains either FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT, the operation MUST be failed with STATUS_OPLOCK_NOT_GRANTED.
Request an exclusive oplock according to the algorithm in section 2.1.5.18.1, setting the algorithm's parameters as follows:
Pass in the current Open.
RequestedOplock equal to RequestedOplockLevel.
The operation MUST at this point return any status code returned by the exclusive oplock request algorithm.
Else if RequestedOplockLevel is 0 (that is, no flags):
The operation MUST return STATUS_SUCCESS at this point.
Else
The operation MUST be failed with STATUS_INVALID_PARAMETER.
EndIf
EndIf