summaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2016-09-22 19:23:56 -0500
committerSteve French <smfrench@gmail.com>2016-10-12 12:08:33 -0500
commit52ace1ef1259e119a24a34b45cb800c4e7529090 (patch)
tree41f8d27ff08c4086025c5894f2cdcd8ee5f205e6 /fs/cifs/file.c
parent3afca265b5f53a0b15b79531c13858049505582d (diff)
downloadlinux-52ace1ef1259e119a24a34b45cb800c4e7529090.tar.bz2
fs/cifs: reopen persistent handles on reconnect
Continuous Availability features like persistent handles require that clients reconnect their open files, not just the sessions, soon after the network connection comes back up, otherwise the server will throw away the state (byte range locks, leases, deny modes) on those handles after a timeout. Add code to reconnect handles when use_persistent set (e.g. Continuous Availability shares) after tree reconnect. Signed-off-by: Aurelien Aptel <aaptel@suse.com> Reviewed-by: Germano Percossi <germano.percossi@citrix.com> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index ee5ceae22411..8f27c8a74384 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -760,6 +760,24 @@ int cifs_close(struct inode *inode, struct file *file)
return 0;
}
+void
+cifs_reopen_persistent_handles(struct cifs_tcon *tcon)
+{
+ struct cifsFileInfo *open_file = NULL;
+ struct list_head *tmp;
+ struct list_head *tmp1;
+
+ /* list all files open on tree connection, reopen resilient handles */
+ spin_lock(&tcon->open_file_lock);
+ list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
+ open_file = list_entry(tmp, struct cifsFileInfo, tlist);
+ spin_unlock(&tcon->open_file_lock);
+ cifs_reopen_file(open_file, false /* do not flush */);
+ spin_lock(&tcon->open_file_lock);
+ }
+ spin_unlock(&tcon->open_file_lock);
+}
+
int cifs_closedir(struct inode *inode, struct file *file)
{
int rc = 0;