summary refs log tree commit diff
path: root/fs/cifs/smb2misc.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <lsahlber@redhat.com>2018-06-14 06:48:35 +1000
committerSteve French <stfrench@microsoft.com>2018-06-15 02:38:07 -0500
commita93864d93977b99bda6c348a09b90a3d7ef8db3a (patch)
tree30d488812c67cb68adce979d2b642756e9281a37 /fs/cifs/smb2misc.c
parent2fbb56446fde14a80790de9b182ae6f7c36a039a (diff)
downloadlinux-a93864d93977b99bda6c348a09b90a3d7ef8db3a.tar.gz
cifs: add lease tracking to the cached root fid
Use a read lease for the cached root fid so that we can detect
when the content of the directory changes (via a break) at which time
we close the handle. On next access to the root the handle will be reopened
and cached again.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/smb2misc.c')
-rw-r--r--fs/cifs/smb2misc.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index e2bec47c6845..0de87ca33e2e 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -492,10 +492,11 @@ cifs_ses_oplock_break(struct work_struct *work)
 {
 	struct smb2_lease_break_work *lw = container_of(work,
 				struct smb2_lease_break_work, lease_break);
-	int rc;
+	int rc = 0;
 
 	rc = SMB2_lease_break(0, tlink_tcon(lw->tlink), lw->lease_key,
 			      lw->lease_state);
+
 	cifs_dbg(FYI, "Lease release rc %d\n", rc);
 	cifs_put_tlink(lw->tlink);
 	kfree(lw);
@@ -561,6 +562,7 @@ smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
 
 		open->oplock = lease_state;
 	}
+
 	return found;
 }
 
@@ -603,6 +605,18 @@ smb2_is_valid_lease_break(char *buffer)
 					return true;
 				}
 				spin_unlock(&tcon->open_file_lock);
+
+				if (tcon->crfid.is_valid &&
+				    !memcmp(rsp->LeaseKey,
+					    tcon->crfid.fid->lease_key,
+					    SMB2_LEASE_KEY_SIZE)) {
+					INIT_WORK(&tcon->crfid.lease_break,
+						  smb2_cached_lease_break);
+					queue_work(cifsiod_wq,
+						   &tcon->crfid.lease_break);
+					spin_unlock(&cifs_tcp_ses_lock);
+					return true;
+				}
 			}
 		}
 	}