Skip to content

Commit

Permalink
fs/cifs: reopen persistent handles on reconnect
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Steve French committed Oct 12, 2016
1 parent 3afca26 commit 52ace1e
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
2 changes: 2 additions & 0 deletions fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
18 changes: 18 additions & 0 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions fs/cifs/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 52ace1e

Please sign in to comment.