diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 273cf42b2915..6070ba69647b 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -137,6 +137,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
137 | struct cifsSesInfo *ses; | 137 | struct cifsSesInfo *ses; |
138 | struct cifsTconInfo *tcon; | 138 | struct cifsTconInfo *tcon; |
139 | struct mid_q_entry *mid_entry; | 139 | struct mid_q_entry *mid_entry; |
140 | struct list_head retry_list; | ||
140 | 141 | ||
141 | spin_lock(&GlobalMid_Lock); | 142 | spin_lock(&GlobalMid_Lock); |
142 | if (server->tcpStatus == CifsExiting) { | 143 | if (server->tcpStatus == CifsExiting) { |
@@ -188,16 +189,23 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
188 | mutex_unlock(&server->srv_mutex); | 189 | mutex_unlock(&server->srv_mutex); |
189 | 190 | ||
190 | /* mark submitted MIDs for retry and issue callback */ | 191 | /* mark submitted MIDs for retry and issue callback */ |
191 | cFYI(1, "%s: issuing mid callbacks", __func__); | 192 | INIT_LIST_HEAD(&retry_list); |
193 | cFYI(1, "%s: moving mids to private list", __func__); | ||
192 | spin_lock(&GlobalMid_Lock); | 194 | spin_lock(&GlobalMid_Lock); |
193 | list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { | 195 | list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { |
194 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | 196 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
195 | if (mid_entry->midState == MID_REQUEST_SUBMITTED) | 197 | if (mid_entry->midState == MID_REQUEST_SUBMITTED) |
196 | mid_entry->midState = MID_RETRY_NEEDED; | 198 | mid_entry->midState = MID_RETRY_NEEDED; |
199 | list_move(&mid_entry->qhead, &retry_list); | ||
200 | } | ||
201 | spin_unlock(&GlobalMid_Lock); | ||
202 | |||
203 | cFYI(1, "%s: issuing mid callbacks", __func__); | ||
204 | list_for_each_safe(tmp, tmp2, &retry_list) { | ||
205 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | ||
197 | list_del_init(&mid_entry->qhead); | 206 | list_del_init(&mid_entry->qhead); |
198 | mid_entry->callback(mid_entry); | 207 | mid_entry->callback(mid_entry); |
199 | } | 208 | } |
200 | spin_unlock(&GlobalMid_Lock); | ||
201 | 209 | ||
202 | while (server->tcpStatus == CifsNeedReconnect) { | 210 | while (server->tcpStatus == CifsNeedReconnect) { |
203 | try_to_freeze(); | 211 | try_to_freeze(); |
@@ -671,12 +679,12 @@ multi_t2_fnd: | |||
671 | mid_entry->when_received = jiffies; | 679 | mid_entry->when_received = jiffies; |
672 | #endif | 680 | #endif |
673 | list_del_init(&mid_entry->qhead); | 681 | list_del_init(&mid_entry->qhead); |
674 | mid_entry->callback(mid_entry); | ||
675 | break; | 682 | break; |
676 | } | 683 | } |
677 | spin_unlock(&GlobalMid_Lock); | 684 | spin_unlock(&GlobalMid_Lock); |
678 | 685 | ||
679 | if (mid_entry != NULL) { | 686 | if (mid_entry != NULL) { |
687 | mid_entry->callback(mid_entry); | ||
680 | /* Was previous buf put in mpx struct for multi-rsp? */ | 688 | /* Was previous buf put in mpx struct for multi-rsp? */ |
681 | if (!isMultiRsp) { | 689 | if (!isMultiRsp) { |
682 | /* smb buffer will be freed by user thread */ | 690 | /* smb buffer will be freed by user thread */ |
@@ -740,15 +748,25 @@ multi_t2_fnd: | |||
740 | cifs_small_buf_release(smallbuf); | 748 | cifs_small_buf_release(smallbuf); |
741 | 749 | ||
742 | if (!list_empty(&server->pending_mid_q)) { | 750 | if (!list_empty(&server->pending_mid_q)) { |
751 | struct list_head dispose_list; | ||
752 | |||
753 | INIT_LIST_HEAD(&dispose_list); | ||
743 | spin_lock(&GlobalMid_Lock); | 754 | spin_lock(&GlobalMid_Lock); |
744 | list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { | 755 | list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { |
745 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | 756 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
746 | cFYI(1, "Clearing Mid 0x%x - issuing callback", | 757 | cFYI(1, "Clearing mid 0x%x", mid_entry->mid); |
747 | mid_entry->mid); | 758 | mid_entry->midState = MID_SHUTDOWN; |
759 | list_move(&mid_entry->qhead, &dispose_list); | ||
760 | } | ||
761 | spin_unlock(&GlobalMid_Lock); | ||
762 | |||
763 | /* now walk dispose list and issue callbacks */ | ||
764 | list_for_each_safe(tmp, tmp2, &dispose_list) { | ||
765 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | ||
766 | cFYI(1, "Callback mid 0x%x", mid_entry->mid); | ||
748 | list_del_init(&mid_entry->qhead); | 767 | list_del_init(&mid_entry->qhead); |
749 | mid_entry->callback(mid_entry); | 768 | mid_entry->callback(mid_entry); |
750 | } | 769 | } |
751 | spin_unlock(&GlobalMid_Lock); | ||
752 | /* 1/8th of sec is more than enough time for them to exit */ | 770 | /* 1/8th of sec is more than enough time for them to exit */ |
753 | msleep(125); | 771 | msleep(125); |
754 | } | 772 | } |