aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsfs.c6
-rw-r--r--fs/cifs/cifsglob.h3
-rw-r--r--fs/cifs/connect.c21
3 files changed, 25 insertions, 5 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index d9f652a522a6..99d777a03dd0 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -77,7 +77,11 @@ unsigned int cifs_max_pending = CIFS_MAX_REQ;
77module_param(cifs_max_pending, int, 0); 77module_param(cifs_max_pending, int, 0);
78MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. " 78MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
79 "Default: 50 Range: 2 to 256"); 79 "Default: 50 Range: 2 to 256");
80 80unsigned short echo_retries = 5;
81module_param(echo_retries, ushort, 0644);
82MODULE_PARM_DESC(echo_retries, "Number of echo attempts before giving up and "
83 "reconnecting server. Default: 5. 0 means "
84 "never reconnect.");
81extern mempool_t *cifs_sm_req_poolp; 85extern mempool_t *cifs_sm_req_poolp;
82extern mempool_t *cifs_req_poolp; 86extern mempool_t *cifs_req_poolp;
83extern mempool_t *cifs_mid_poolp; 87extern mempool_t *cifs_mid_poolp;
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 9c728dd5b146..7040abc638fa 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -804,6 +804,9 @@ GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
804GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */ 804GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */
805GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/ 805GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
806 806
807/* reconnect after this many failed echo attempts */
808GLOBAL_EXTERN unsigned short echo_retries;
809
807void cifs_oplock_break(struct work_struct *work); 810void cifs_oplock_break(struct work_struct *work);
808void cifs_oplock_break_get(struct cifsFileInfo *cfile); 811void cifs_oplock_break_get(struct cifsFileInfo *cfile);
809void cifs_oplock_break_put(struct cifsFileInfo *cfile); 812void cifs_oplock_break_put(struct cifsFileInfo *cfile);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f38ca084c9d2..f5d7b59a3553 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -186,6 +186,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
186 kfree(server->session_key.response); 186 kfree(server->session_key.response);
187 server->session_key.response = NULL; 187 server->session_key.response = NULL;
188 server->session_key.len = 0; 188 server->session_key.len = 0;
189 server->lstrp = jiffies;
189 mutex_unlock(&server->srv_mutex); 190 mutex_unlock(&server->srv_mutex);
190 191
191 /* mark submitted MIDs for retry and issue callback */ 192 /* mark submitted MIDs for retry and issue callback */
@@ -420,7 +421,20 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
420 smb_msg.msg_control = NULL; 421 smb_msg.msg_control = NULL;
421 smb_msg.msg_controllen = 0; 422 smb_msg.msg_controllen = 0;
422 pdu_length = 4; /* enough to get RFC1001 header */ 423 pdu_length = 4; /* enough to get RFC1001 header */
424
423incomplete_rcv: 425incomplete_rcv:
426 if (echo_retries > 0 &&
427 time_after(jiffies, server->lstrp +
428 (echo_retries * SMB_ECHO_INTERVAL))) {
429 cERROR(1, "Server %s has not responded in %d seconds. "
430 "Reconnecting...", server->hostname,
431 (echo_retries * SMB_ECHO_INTERVAL / HZ));
432 cifs_reconnect(server);
433 csocket = server->ssocket;
434 wake_up(&server->response_q);
435 continue;
436 }
437
424 length = 438 length =
425 kernel_recvmsg(csocket, &smb_msg, 439 kernel_recvmsg(csocket, &smb_msg,
426 &iov, 1, pdu_length, 0 /* BB other flags? */); 440 &iov, 1, pdu_length, 0 /* BB other flags? */);
@@ -581,6 +595,8 @@ incomplete_rcv:
581 } 595 }
582 596
583 mid_entry = NULL; 597 mid_entry = NULL;
598 server->lstrp = jiffies;
599
584 spin_lock(&GlobalMid_Lock); 600 spin_lock(&GlobalMid_Lock);
585 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { 601 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
586 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 602 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
@@ -629,10 +645,6 @@ multi_t2_fnd:
629#ifdef CONFIG_CIFS_STATS2 645#ifdef CONFIG_CIFS_STATS2
630 mid_entry->when_received = jiffies; 646 mid_entry->when_received = jiffies;
631#endif 647#endif
632 /* so we do not time out requests to server
633 which is still responding (since server could
634 be busy but not dead) */
635 server->lstrp = jiffies;
636 break; 648 break;
637 } 649 }
638 mid_entry = NULL; 650 mid_entry = NULL;
@@ -1685,6 +1697,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1685 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); 1697 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1686 tcp_ses->session_estab = false; 1698 tcp_ses->session_estab = false;
1687 tcp_ses->sequence_number = 0; 1699 tcp_ses->sequence_number = 0;
1700 tcp_ses->lstrp = jiffies;
1688 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); 1701 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1689 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); 1702 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1690 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); 1703 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);