@@ -714,6 +714,78 @@ cifs_echo_request(struct work_struct *work)
queue_delayed_work(cifsiod_wq, &server->echo, server->echo_interval);
}
+static void cifs_reconnect_tcons(struct work_struct *work)
+{
+ struct TCP_Server_Info *server = container_of(work,
+ struct TCP_Server_Info, reconnect.work);
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon, *tcon2;
+ struct list_head tmp_list;
+ int tcon_exist = false;
+ int rc;
+ int resched = false;
+
+
+ /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */
+ mutex_lock(&server->reconnect_mutex);
+
+ INIT_LIST_HEAD(&tmp_list);
+ cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
+
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+ if (tcon->need_reconnect || tcon->need_reopen_files) {
+ tcon->tc_count++;
+ list_add_tail(&tcon->rlist, &tmp_list);
+ tcon_exist = true;
+ }
+ }
+ /*
+ * IPC has the same lifetime as its session and uses its
+ * refcount.
+ */
+ if (ses->tcon_ipc && ses->tcon_ipc->need_reconnect) {
+ list_add_tail(&ses->tcon_ipc->rlist, &tmp_list);
+ tcon_exist = true;
+ ses->ses_count++;
+ }
+ }
+ /*
+ * Get the reference to server struct to be sure that the last call of
+ * cifs_put_tcon() in the loop below won't release the server pointer.
+ */
+ if (tcon_exist)
+ server->srv_count++;
+
+ spin_unlock(&cifs_tcp_ses_lock);
+
+ list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
+ struct cifs_tcon_reconnect_params params = {
+ .start_timer = false,
+ };
+ rc = cifs_tcon_reconnect(tcon, ¶ms);
+ if (!rc)
+ cifs_reopen_persistent_handles(tcon);
+ else
+ resched = true;
+ list_del_init(&tcon->rlist);
+ if (tcon->ipc)
+ cifs_put_smb_ses(tcon->ses);
+ else
+ cifs_put_tcon(tcon);
+ }
+
+ cifs_dbg(FYI, "Reconnecting tcons finished\n");
+ if (resched)
+ queue_delayed_work(cifsiod_wq, &server->reconnect, 2 * HZ);
+ mutex_unlock(&server->reconnect_mutex);
+
+ /* now we can safely release srv struct */
+ if (tcon_exist)
+ cifs_put_tcp_session(server, 1);
+}
+
static bool
allocate_buffers(struct TCP_Server_Info *server)
{
@@ -3290,78 +3290,6 @@ smb2_echo_callback(struct mid_q_entry *mid)
add_credits(server, &credits, CIFS_ECHO_OP);
}
-void cifs_reconnect_tcons(struct work_struct *work)
-{
- struct TCP_Server_Info *server = container_of(work,
- struct TCP_Server_Info, reconnect.work);
- struct cifs_ses *ses;
- struct cifs_tcon *tcon, *tcon2;
- struct list_head tmp_list;
- int tcon_exist = false;
- int rc;
- int resched = false;
-
-
- /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */
- mutex_lock(&server->reconnect_mutex);
-
- INIT_LIST_HEAD(&tmp_list);
- cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
-
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
- list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
- if (tcon->need_reconnect || tcon->need_reopen_files) {
- tcon->tc_count++;
- list_add_tail(&tcon->rlist, &tmp_list);
- tcon_exist = true;
- }
- }
- /*
- * IPC has the same lifetime as its session and uses its
- * refcount.
- */
- if (ses->tcon_ipc && ses->tcon_ipc->need_reconnect) {
- list_add_tail(&ses->tcon_ipc->rlist, &tmp_list);
- tcon_exist = true;
- ses->ses_count++;
- }
- }
- /*
- * Get the reference to server struct to be sure that the last call of
- * cifs_put_tcon() in the loop below won't release the server pointer.
- */
- if (tcon_exist)
- server->srv_count++;
-
- spin_unlock(&cifs_tcp_ses_lock);
-
- list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
- struct cifs_tcon_reconnect_params params = {
- .start_timer = false,
- };
- rc = cifs_tcon_reconnect(tcon, ¶ms);
- if (!rc)
- cifs_reopen_persistent_handles(tcon);
- else
- resched = true;
- list_del_init(&tcon->rlist);
- if (tcon->ipc)
- cifs_put_smb_ses(tcon->ses);
- else
- cifs_put_tcon(tcon);
- }
-
- cifs_dbg(FYI, "Reconnecting tcons finished\n");
- if (resched)
- queue_delayed_work(cifsiod_wq, &server->reconnect, 2 * HZ);
- mutex_unlock(&server->reconnect_mutex);
-
- /* now we can safely release srv struct */
- if (tcon_exist)
- cifs_put_tcp_session(server, 1);
-}
-
int
SMB2_echo(struct TCP_Server_Info *server)
{
@@ -116,7 +116,6 @@ extern int smb2_open_file(const unsigned int xid,
extern int smb2_unlock_range(struct cifsFileInfo *cfile,
struct file_lock *flock, const unsigned int xid);
extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
-extern void cifs_reconnect_tcons(struct work_struct *work);
extern int smb3_crypto_aead_allocate(struct TCP_Server_Info *server);
extern unsigned long smb_rqst_len(struct TCP_Server_Info *server,
struct smb_rqst *rqst);
Signed-off-by: Stefan Metzmacher <metze@samba.org> --- fs/cifs/connect.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/smb2pdu.c | 72 --------------------------------------------- fs/cifs/smb2proto.h | 1 - 3 files changed, 72 insertions(+), 73 deletions(-)