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@xxxxxxxxxx> --- fs/cifs/cached_dir.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cached_dir.c b/fs/cifs/cached_dir.c index 60399081046a..6672f1a0acd7 100644 --- a/fs/cifs/cached_dir.c +++ b/fs/cifs/cached_dir.c @@ -220,8 +220,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; @@ -238,7 +237,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; @@ -261,7 +261,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: @@ -281,12 +280,17 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, } 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; } -- 2.35.3