3.3.5.9.8 Handling the SMB2_CREATE_REQUEST_LEASE Create Context
This section applies only to servers that implement the SMB 2.1 or 3.x dialect family.
If both SMB2_CREATE_DURABLE_HANDLE_RECONNECT and SMB2_CREATE_REQUEST_LEASE create contexts are present in the request, they are processed as specified in section 3.3.5.9.7, and this section does not apply.
If both SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 and SMB2_CREATE_REQUEST_LEASE create contexts are present in the request, they are processed as specified in section 3.3.5.9.12, and this section does not apply.
If the server does not support leasing, the server MUST ignore the SMB2_CREATE_REQUEST_LEASE Create Context request.
If RequestedOplockLevel is not SMB2_OPLOCK_LEVEL_LEASE, the server SHOULD<338> ignore the SMB2_CREATE_REQUEST_LEASE Create Context request.
By specifying a RequestedOplockLevel of SMB2_OPLOCK_LEVEL_LEASE, the client is requesting that a lease be acquired for this open. If the request does not provide an SMB2_CREATE_REQUEST_LEASE Create Context, the lease request MUST be ignored and Open.OplockLevel MUST be set to SMB2_OPLOCK_LEVEL_NONE.
The processing changes involved in acquiring the lease are:
In the "Path Name Validation" phase, the server MUST attempt to locate a Lease Table by performing a lookup in GlobalLeaseTableList using Connection.ClientGuid as the lookup key. If no LeaseTable is found, one MUST be allocated and the following values set:
LeaseTable.ClientGuid is set to Connection.ClientGuid.
LeaseTable.LeaseList is set to an empty list.
If the allocation fails, the create request MUST be failed with STATUS_INSUFFICIENT_RESOURCES.
The server MUST attempt to locate a Lease by performing a lookup in the LeaseTable.LeaseList using the LeaseKey in the SMB2_CREATE_REQUEST_LEASE as the lookup key. If a lease is found, Lease.FileDeleteOnClose is FALSE, and Lease.Filename does not match the file name for the incoming request, the request MUST be failed with STATUS_INVALID_PARAMETER.
If no lease is found, one MUST be allocated with the following values set:
Lease.LeaseKey is set to the LeaseKey in the SMB2_CREATE_REQUEST_LEASE create context.
Lease.ClientLeaseId is set to a value as specified in section 3.3.1.4.
Lease.Filename is set to the file being opened.
Lease.LeaseState is set to NONE.
Lease.BreakToLeaseState is set to NONE.
Lease.LeaseBreakTimeout is set to 0.
Lease.LeaseOpens is set to an empty list.
Lease.Breaking is set to FALSE.
Lease.FileDeleteOnClose is set to FALSE.
If Connection.Dialect belongs to the SMB 3.x dialect family, Lease.Version is set to 1.
If the allocation fails, the create request MUST be failed with STATUS_INSUFFICIENT_RESOURCES. Otherwise, if a LeaseTable was created it MUST be added to the GlobalLeaseTableList, and if a Lease was created it MUST be added to the LeaseTable.LeaseList.
At this point, execution of create continues as described in 3.3.5.9 until the Oplock Acquisition phase.
During "Oplock Acquisition", if the underlying object store does not support leasing, the server SHOULD fall back to requesting a batch oplock instead of a lease and continue processing as described in "Oplock Acquisition". If the underlying object store does support leasing, the following steps are taken:
If TreeConnect.Share.ForceLevel2Oplock is TRUE, and LeaseState includes SMB2_LEASE_WRITE_CACHING, the server MUST clear the bit SMB2_LEASE_WRITE_CACHING in the LeaseState field.
If Connection.Dialect belongs to the SMB 3.x dialect family, TreeConnect.Share.Type is STYPE_CLUSTER_SOFS as specified in [MS-SRVS] section 2.2.2.4, and if LeaseState includes SMB2_LEASE_READ_CACHING, the server MUST set LeaseState to SMB2_LEASE_READ_CACHING, otherwise set LeaseState to SMB2_LEASE_NONE.
If the caching state requested in LeaseState of the SMB2_CREATE_REQUEST_LEASE is not a superset of Lease.LeaseState or if Lease.Breaking is TRUE, the server MUST NOT promote Lease.LeaseState. If the lease state requested is a superset of Lease.LeaseState and Lease.Breaking is FALSE, the server MUST request promotion of the lease state from the underlying object store to the new caching state.<339>
If the object store succeeds this request, Lease.LeaseState MUST be set to the new caching state. If Lease.Breaking is TRUE, the server MUST return the existing Lease.LeaseState to client and set LeaseFlags to be SMB2_LEASE_FLAG_BREAK_IN_PROGRESS. At this point, execution continues as described in section 3.3.5.9 until the "Response Construction" phase.
In the "Response Construction" phase, the server MUST construct an SMB2_CREATE_RESPONSE_LEASE response create context, following the syntax specified in section 2.2.14.2.10, and include it in the buffer described by the response CreateContextsLength and CreateContextsOffset. This structure MUST have the following values set:
LeaseKey MUST be set to Lease.LeaseKey.
LeaseState MUST be set to Lease.LeaseState.
The server MUST set Open.OplockState to Held, set Open.Lease to a reference to Lease, set Open.OplockLevel to SMB2_OPLOCK_LEVEL_LEASE, and add Open to Lease.LeaseOpens. If this Open is the first open in Lease.LeaseOpens, the server MUST set Lease.Held to TRUE. The remainder of open response construction continues as described in "Response Construction".
If Open.Lease is not NULL and CreateOptions field in the CREATE request includes FILE_DELETE_ON_CLOSE, the server MUST set Open.Lease.FileDeleteOnClose to TRUE.