2.1.5.8 Server Requests a Byte-Range Lock

The server provides:

  • Open: An Open of a DataStream.

  • FileOffset: A 64-bit unsigned integer containing the starting offset, in bytes.

  • Length: A 64-bit unsigned integer containing the length, in bytes. This value MAY be zero.

  • ExclusiveLock: A Boolean indicating whether the range is to be locked exclusively (TRUE) or shared (FALSE).

  • FailImmediately: A Boolean indicating whether the lock request is to fail (TRUE) if the range is locked by another open or if it is to wait until the lock can be acquired (FALSE).

  • LockKey: A 32-bit unsigned integer containing an identifier for the lock being obtained by a specific process.

On completion, the object store MUST return:

  • Status: An NTSTATUS code that specifies the result

Pseudocode for the operation is as follows:

  • [Validation]

  • If Open.Stream.StreamType is DirectoryStream, return STATUS_INVALID_PARAMETER, as byte range locks are not permitted on directories.

  • If (((FileOffset + Length - 1) < FileOffset) && Length != 0)

    • This means that the requested range contains one or more bytes with offsets beyond the maximum 64-bit unsigned integer. The operation MUST be failed with STATUS_INVALID_LOCK_RANGE.

  • EndIf

  • [Processing]

  • If (FileOffset < Open.Stream.AllocationSize)<81> and Open.Stream.Oplock is not empty, the object store MUST check for an oplock break according to the algorithm in section 2.1.4.12, with input values as follows:

    • Open equal to this operation's Open

    • Oplock equal to Open.Stream.Oplock

    • Operation equal to "LOCK_CONTROL"

    • OpParams empty

  • The object store MUST check for byte range lock conflicts by using the algorithm described in section 2.1.4.10, with ByteOffset set to FileOffset, Length set to Length, IsExclusive set to ExclusiveLock, LockIntent set to TRUE, and Open set to Open. If a conflict is detected, then:

    • If FailImmediately is TRUE, the operation MUST be failed with STATUS_LOCK_NOT_GRANTED.

    • Else

      • Insert operation into CancelableOperations.CancelableOperationList.

      • Wait until there are no overlapping ByteRangeLocks or until the operation is canceled as specified in section 2.1.5.20. Overlapping ByteRangeLocks can be removed from ByteRangeLockList in different ways:

        • The ByteRangeLock can be explicitly unlocked as described in section 2.1.5.9.

        • The ByteRangeLock.OwnerOpen can be closed as described in section 2.1.5.5.

    • EndIf

  • EndIf

  • Initialize a new ByteRangeLock:

    • ByteRangeLock.LockOffset MUST be initialized to FileOffset.

    • ByteRangeLock.LockLength MUST be initialized to Length.

    • ByteRangeLock.IsExclusive MUST be initialized to ExclusiveLock.

    • ByteRangeLock.OwnerOpen MUST be initialized to Open.

    • ByteRangeLock.LockKey MUST be set to the server provided LockKey, if provided.

  • Insert ByteRangeLock into Open.Stream.ByteRangeLockList.

  • Complete this operation with STATUS_SUCCESS.