diff options
| -rw-r--r-- | fs/cifs/cifsfs.c | 6 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 3 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 21 |
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; | |||
| 77 | module_param(cifs_max_pending, int, 0); | 77 | module_param(cifs_max_pending, int, 0); |
| 78 | MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. " | 78 | MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. " |
| 79 | "Default: 50 Range: 2 to 256"); | 79 | "Default: 50 Range: 2 to 256"); |
| 80 | 80 | unsigned short echo_retries = 5; | |
| 81 | module_param(echo_retries, ushort, 0644); | ||
| 82 | MODULE_PARM_DESC(echo_retries, "Number of echo attempts before giving up and " | ||
| 83 | "reconnecting server. Default: 5. 0 means " | ||
| 84 | "never reconnect."); | ||
| 81 | extern mempool_t *cifs_sm_req_poolp; | 85 | extern mempool_t *cifs_sm_req_poolp; |
| 82 | extern mempool_t *cifs_req_poolp; | 86 | extern mempool_t *cifs_req_poolp; |
| 83 | extern mempool_t *cifs_mid_poolp; | 87 | extern 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 */ | |||
| 804 | GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */ | 804 | GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */ |
| 805 | GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/ | 805 | GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/ |
| 806 | 806 | ||
| 807 | /* reconnect after this many failed echo attempts */ | ||
| 808 | GLOBAL_EXTERN unsigned short echo_retries; | ||
| 809 | |||
| 807 | void cifs_oplock_break(struct work_struct *work); | 810 | void cifs_oplock_break(struct work_struct *work); |
| 808 | void cifs_oplock_break_get(struct cifsFileInfo *cfile); | 811 | void cifs_oplock_break_get(struct cifsFileInfo *cfile); |
| 809 | void cifs_oplock_break_put(struct cifsFileInfo *cfile); | 812 | void 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 | |||
| 423 | incomplete_rcv: | 425 | incomplete_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); |
