Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52ace1ef authored by Steve French's avatar Steve French
Browse files

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: default avatarAurelien Aptel <aaptel@suse.com>
Reviewed-by: default avatarGermano Percossi <germano.percossi@citrix.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 3afca265
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -193,6 +193,8 @@ extern struct smb_vol *cifs_get_volume_info(char *mount_data,
extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *);
extern void cifs_umount(struct cifs_sb_info *);
extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon);
extern void cifs_reopen_persistent_handles(struct cifs_tcon *tcon);

extern bool cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset,
				    __u64 length, __u8 type,
				    struct cifsLockInfo **conf_lock,
+18 −0
Original line number Diff line number Diff line
@@ -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;
+5 −0
Original line number Diff line number Diff line
@@ -250,8 +250,13 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
	}

	cifs_mark_open_files_invalid(tcon);

	rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nls_codepage);
	mutex_unlock(&tcon->ses->session_mutex);

	if (tcon->use_persistent)
		cifs_reopen_persistent_handles(tcon);

	cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
	if (rc)
		goto out;