| From f801568332321e2b1e7a8bd26c3e4913a312a2ec Mon Sep 17 00:00:00 2001 |
| From: Steve French <stfrench@microsoft.com> |
| Date: Fri, 31 Aug 2018 15:12:10 -0500 |
| Subject: smb3: check for and properly advertise directory lease support |
| |
| From: Steve French <stfrench@microsoft.com> |
| |
| commit f801568332321e2b1e7a8bd26c3e4913a312a2ec upstream. |
| |
| Although servers will typically ignore unsupported features, |
| we should advertise the support for directory leases (as |
| Windows e.g. does) in the negotiate protocol capabilities we |
| pass to the server, and should check for the server capability |
| (CAP_DIRECTORY_LEASING) before sending a lease request for an |
| open of a directory. This will prevent us from accidentally |
| sending directory leases to SMB2.1 or SMB2 server for example. |
| |
| Signed-off-by: Steve French <stfrench@microsoft.com> |
| CC: Stable <stable@vger.kernel.org> |
| Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/cifs/smb2ops.c | 10 +++++----- |
| fs/cifs/smb2pdu.c | 3 +++ |
| 2 files changed, 8 insertions(+), 5 deletions(-) |
| |
| --- a/fs/cifs/smb2ops.c |
| +++ b/fs/cifs/smb2ops.c |
| @@ -3215,7 +3215,7 @@ struct smb_version_values smb21_values = |
| struct smb_version_values smb3any_values = { |
| .version_string = SMB3ANY_VERSION_STRING, |
| .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */ |
| - .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, |
| + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, |
| .large_lock_type = 0, |
| .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, |
| .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
| @@ -3235,7 +3235,7 @@ struct smb_version_values smb3any_values |
| struct smb_version_values smbdefault_values = { |
| .version_string = SMBDEFAULT_VERSION_STRING, |
| .protocol_id = SMB302_PROT_ID, /* doesn't matter, send protocol array */ |
| - .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, |
| + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, |
| .large_lock_type = 0, |
| .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, |
| .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
| @@ -3255,7 +3255,7 @@ struct smb_version_values smbdefault_val |
| struct smb_version_values smb30_values = { |
| .version_string = SMB30_VERSION_STRING, |
| .protocol_id = SMB30_PROT_ID, |
| - .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, |
| + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, |
| .large_lock_type = 0, |
| .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, |
| .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
| @@ -3275,7 +3275,7 @@ struct smb_version_values smb30_values = |
| struct smb_version_values smb302_values = { |
| .version_string = SMB302_VERSION_STRING, |
| .protocol_id = SMB302_PROT_ID, |
| - .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, |
| + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, |
| .large_lock_type = 0, |
| .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, |
| .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
| @@ -3296,7 +3296,7 @@ struct smb_version_values smb302_values |
| struct smb_version_values smb311_values = { |
| .version_string = SMB311_VERSION_STRING, |
| .protocol_id = SMB311_PROT_ID, |
| - .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION, |
| + .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES | SMB2_GLOBAL_CAP_ENCRYPTION | SMB2_GLOBAL_CAP_DIRECTORY_LEASING, |
| .large_lock_type = 0, |
| .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK, |
| .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK, |
| --- a/fs/cifs/smb2pdu.c |
| +++ b/fs/cifs/smb2pdu.c |
| @@ -1816,6 +1816,9 @@ SMB2_open(const unsigned int xid, struct |
| if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) || |
| *oplock == SMB2_OPLOCK_LEVEL_NONE) |
| req->RequestedOplockLevel = *oplock; |
| + else if (!(server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) && |
| + (oparms->create_options & CREATE_NOT_FILE)) |
| + req->RequestedOplockLevel = *oplock; /* no srv lease support */ |
| else { |
| rc = add_lease_context(server, iov, &n_iov, oplock); |
| if (rc) { |