summaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2misc.c
diff options
context:
space:
mode:
authorRonnie Sahlberg2018-06-13 22:48:35 +0200
committerSteve French2018-06-15 09:38:07 +0200
commita93864d93977b99bda6c348a09b90a3d7ef8db3a (patch)
tree30d488812c67cb68adce979d2b642756e9281a37 /fs/cifs/smb2misc.c
parentsmb3: note that smb3.11 posix extensions mount option is experimental (diff)
downloadkernel-qcow2-linux-a93864d93977b99bda6c348a09b90a3d7ef8db3a.tar.gz
kernel-qcow2-linux-a93864d93977b99bda6c348a09b90a3d7ef8db3a.tar.xz
kernel-qcow2-linux-a93864d93977b99bda6c348a09b90a3d7ef8db3a.zip
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;
+ }
}
}
}