126.96.36.199.11 Handling the SMB2_CREATE_REQUEST_LEASE_V2 Create Context
This section applies only to servers that implement the SMB 3.x dialect family.
If both SMB2_CREATE_DURABLE_HANDLE_RECONNECT and SMB2_CREATE_REQUEST_LEASE_V2 create contexts are present in the request, they are processed as specified in section 188.8.131.52.7, and this section does not apply.
If both SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 and SMB2_CREATE_REQUEST_LEASE_V2 create contexts are present in the request, they are processed as specified in section 184.108.40.206.12, and this section does not apply.
If the server does not support leasing, the server MUST ignore the SMB2_CREATE_REQUEST_LEASE_V2 Create Context request.
If Connection.Dialect does not belong to the SMB 3.x dialect family or if RequestedOplockLevel is not SMB2_OPLOCK_LEVEL_LEASE, the server SHOULD<326> ignore the SMB2_CREATE_REQUEST_LEASE_V2 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_V2 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_V2 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 a lease is found, the server MUST construct an SMB2_CREATE_RESPONSE_LEASE_V2 response create context as specified below.
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_V2 create context.
If the SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET bit is set in the Flags field of the request, Lease.ParentLeaseKey MUST be set to the ParentLeaseKey of the request.
Lease.ClientLeaseId is set to a value as specified in section 220.127.116.11
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.Epoch is set to 0.
Lease.FileDeleteOnClose is set to FALSE.
Lease.Version is set to 2.
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 18.104.22.168 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 the FileAttributes field in the request includes FILE_ATTRIBUTE_DIRECTORY and LeaseState includes SMB2_LEASE_WRITE_CACHING, the server MUST clear the bit SMB2_LEASE_WRITE_CACHING in the LeaseState field.
If TreeConnect.Share.Type is STYPE_CLUSTER_SOFS as specified in [MS-SRVS] section 22.214.171.124, 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_V2 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.<327>
If the object store succeeds this request, Lease.LeaseState MUST be set to the new caching state. The server MUST increment Lease.Epoch by 1. If Lease.Breaking is TRUE, the server MUST return the existing Lease.LeaseState to client and set Flags to be SMB2_LEASE_FLAG_BREAK_IN_PROGRESS. At this point, execution continues as described in section 126.96.36.199 until the "Response Construction" phase.
In the "Response Construction" phase, the server MUST construct an SMB2_CREATE_RESPONSE_LEASE_V2 response create context, following the syntax specified in section 188.8.131.52.11, 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.
If Lease.ParentLeaseKey is not empty, ParentLeaseKey MUST be set to Lease.ParentLeaseKey, and the SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET bit MUST be set in the Flags field of the response.
Epoch MUST be set to Lease.Epoch.
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 the "Response Construction" phase.
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.