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>
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index ee5ceae..8f27c8a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -760,6 +760,24 @@
 	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;