diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 63 |
1 files changed, 35 insertions, 28 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 4c0e44489f21..084756cfdaee 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -323,8 +323,6 @@ static int ip_connect(struct TCP_Server_Info *server); static int generic_ip_connect(struct TCP_Server_Info *server); static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); static void cifs_prune_tlinks(struct work_struct *work); -static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, - const char *devname, bool is_smb3); static char *extract_hostname(const char *unc); /* @@ -530,21 +528,6 @@ cifs_reconnect(struct TCP_Server_Info *server) /* do not want to be sending data on a socket we are freeing */ cifs_dbg(FYI, "%s: tearing down socket\n", __func__); mutex_lock(&server->srv_mutex); - if (server->ssocket) { - cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n", - server->ssocket->state, server->ssocket->flags); - kernel_sock_shutdown(server->ssocket, SHUT_WR); - cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n", - server->ssocket->state, server->ssocket->flags); - sock_release(server->ssocket); - server->ssocket = NULL; - } - server->sequence_number = 0; - server->session_estab = false; - kfree(server->session_key.response); - server->session_key.response = NULL; - server->session_key.len = 0; - server->lstrp = jiffies; /* mark submitted MIDs for retry and issue callback */ INIT_LIST_HEAD(&retry_list); @@ -557,7 +540,6 @@ cifs_reconnect(struct TCP_Server_Info *server) list_move(&mid_entry->qhead, &retry_list); } spin_unlock(&GlobalMid_Lock); - mutex_unlock(&server->srv_mutex); cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__); list_for_each_safe(tmp, tmp2, &retry_list) { @@ -566,6 +548,25 @@ cifs_reconnect(struct TCP_Server_Info *server) mid_entry->callback(mid_entry); } + if (server->ssocket) { + cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n", + server->ssocket->state, server->ssocket->flags); + kernel_sock_shutdown(server->ssocket, SHUT_WR); + cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n", + server->ssocket->state, server->ssocket->flags); + sock_release(server->ssocket); + server->ssocket = NULL; + } else if (cifs_rdma_enabled(server)) + smbd_destroy(server); + server->sequence_number = 0; + server->session_estab = false; + kfree(server->session_key.response); + server->session_key.response = NULL; + server->session_key.len = 0; + server->lstrp = jiffies; + + mutex_unlock(&server->srv_mutex); + do { try_to_freeze(); @@ -931,10 +932,8 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) wake_up_all(&server->request_q); /* give those requests time to exit */ msleep(125); - if (cifs_rdma_enabled(server) && server->smbd_conn) { - smbd_destroy(server->smbd_conn); - server->smbd_conn = NULL; - } + if (cifs_rdma_enabled(server)) + smbd_destroy(server); if (server->ssocket) { sock_release(server->ssocket); server->ssocket = NULL; @@ -2904,8 +2903,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) return NULL; } -static void -cifs_put_smb_ses(struct cifs_ses *ses) +void cifs_put_smb_ses(struct cifs_ses *ses) { unsigned int rc, xid; struct TCP_Server_Info *server = ses->server; @@ -3082,7 +3080,7 @@ cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)), * already got a server reference (server refcount +1). See * cifs_get_tcon() for refcount explanations. */ -static struct cifs_ses * +struct cifs_ses * cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) { int rc = -ENOMEM; @@ -4389,7 +4387,7 @@ static int mount_do_dfs_failover(const char *path, } #endif -static int +int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, const char *devname, bool is_smb3) { @@ -4543,7 +4541,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) struct cifs_tcon *tcon = NULL; struct TCP_Server_Info *server; char *root_path = NULL, *full_path = NULL; - char *old_mountdata; + char *old_mountdata, *origin_mountdata = NULL; int count; rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); @@ -4602,6 +4600,14 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) goto error; } + /* Save DFS root volume information for DFS refresh worker */ + origin_mountdata = kstrndup(cifs_sb->mountdata, + strlen(cifs_sb->mountdata), GFP_KERNEL); + if (!origin_mountdata) { + rc = -ENOMEM; + goto error; + } + if (cifs_sb->mountdata != old_mountdata) { /* If we were redirected, reconnect to new target server */ mount_put_conns(cifs_sb, xid, server, ses, tcon); @@ -4710,7 +4716,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) } spin_unlock(&cifs_tcp_ses_lock); - rc = dfs_cache_add_vol(vol, cifs_sb->origin_fullpath); + rc = dfs_cache_add_vol(origin_mountdata, vol, cifs_sb->origin_fullpath); if (rc) { kfree(cifs_sb->origin_fullpath); goto error; @@ -4728,6 +4734,7 @@ out: error: kfree(full_path); kfree(root_path); + kfree(origin_mountdata); mount_put_conns(cifs_sb, xid, server, ses, tcon); return rc; } |