summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRohith Surabattula <rohiths@microsoft.com>2021-05-17 11:28:34 +0000
committerSteve French <stfrench@microsoft.com>2021-05-19 21:11:28 -0500
commit0ab95c2510b641fb860a773b3d242ef9768a8f66 (patch)
treeb55de54e7a8ecfc56f8e01bc4e922b38d427c5ea
parent860b69a9d77160d21ca00357fd6c5217f9d41fb1 (diff)
downloadlinux-0ab95c2510b641fb860a773b3d242ef9768a8f66.tar.bz2
Defer close only when lease is enabled.
When smb2 lease parameter is disabled on server. Server grants batch oplock instead of RHW lease by default on open, inode page cache needs to be zapped immediatley upon close as cache is not valid. Signed-off-by: Rohith Surabattula <rohiths@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r--fs/cifs/cifsglob.h1
-rw-r--r--fs/cifs/file.c1
-rw-r--r--fs/cifs/smb2ops.c2
3 files changed, 4 insertions, 0 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index ea90c53386b8..8488d7024462 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1417,6 +1417,7 @@ struct cifsInodeInfo {
struct inode vfs_inode;
struct list_head deferred_closes; /* list of deferred closes */
spinlock_t deferred_lock; /* protection on deferred list */
+ bool lease_granted; /* Flag to indicate whether lease or oplock is granted. */
};
static inline struct cifsInodeInfo *
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 304d9d3783c6..a1abd3da1d44 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -896,6 +896,7 @@ int cifs_close(struct inode *inode, struct file *file)
file->private_data = NULL;
dclose = kmalloc(sizeof(struct cifs_deferred_close), GFP_KERNEL);
if ((cinode->oplock == CIFS_CACHE_RHW_FLG) &&
+ cinode->lease_granted &&
dclose) {
if (test_bit(CIFS_INO_MODIFIED_ATTR, &cinode->flags))
inode->i_ctime = inode->i_mtime = current_time(inode);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index c693624a7267..21ef51d338e0 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -3983,6 +3983,7 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
{
oplock &= 0xFF;
+ cinode->lease_granted = false;
if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
return;
if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
@@ -4009,6 +4010,7 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int new_oplock = 0;
oplock &= 0xFF;
+ cinode->lease_granted = true;
if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
return;