aboutsummaryrefslogtreecommitdiff
path: root/fs/cifs
diff options
context:
space:
mode:
authorRonnie Sahlberg2023-02-17 13:35:00 +1000
committerGreg Kroah-Hartman2023-03-10 09:34:06 +0100
commitc992b699b9cb9551d2202fff2b932e526b28b714 (patch)
tree19da892be2a5bd56d1c8cc4e21ae79653f2a490f /fs/cifs
parentf1d84943289e9f982077e37d042895f56e18ecc1 (diff)
cifs: Check the lease context if we actually got a lease
commit 66d45ca1350a3bb8d5f4db8879ccad3ed492337a upstream. Some servers may return that we got a lease in rsp->OplockLevel but then in the lease context contradict this and say we got no lease at all. Thus we need to check the context if we have a lease. Additionally, If we do not get a lease we need to make sure we close the handle before we return an error to the caller. Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Cc: stable@vger.kernel.org Reviewed-by: Bharath SM <bharathsm@microsoft.com> Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cached_dir.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/cifs/cached_dir.c b/fs/cifs/cached_dir.c
index b36ae64034a3..d5e5d757fc56 100644
--- a/fs/cifs/cached_dir.c
+++ b/fs/cifs/cached_dir.c
@@ -221,8 +221,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
}
goto oshr_free;
}
-
- atomic_inc(&tcon->num_remote_opens);
+ cfid->is_open = true;
o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
oparms.fid->persistent_fid = o_rsp->PersistentFileId;
@@ -239,7 +238,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
&oparms.fid->epoch,
oparms.fid->lease_key, &oplock,
NULL, NULL);
-
+ if (!(oplock & SMB2_LEASE_READ_CACHING_HE))
+ goto oshr_free;
qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
goto oshr_free;
@@ -262,7 +262,6 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
cfid->dentry = dentry;
cfid->tcon = tcon;
cfid->time = jiffies;
- cfid->is_open = true;
cfid->has_lease = true;
oshr_free:
@@ -282,12 +281,17 @@ oshr_free:
}
spin_unlock(&cfids->cfid_list_lock);
if (rc) {
+ if (cfid->is_open)
+ SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
+ cfid->fid.volatile_fid);
free_cached_dir(cfid);
cfid = NULL;
}
- if (rc == 0)
+ if (rc == 0) {
*ret_cfid = cfid;
+ atomic_inc(&tcon->num_remote_opens);
+ }
return rc;
}