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