diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/connect.c | 44 |
1 files changed, 15 insertions, 29 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 17ca8ce81bb7..1126f7ab4606 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -125,7 +125,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
125 | struct mid_q_entry *mid_entry; | 125 | struct mid_q_entry *mid_entry; |
126 | 126 | ||
127 | spin_lock(&GlobalMid_Lock); | 127 | spin_lock(&GlobalMid_Lock); |
128 | if (kthread_should_stop()) { | 128 | if (server->tcpStatus == CifsExiting) { |
129 | /* the demux thread will exit normally | 129 | /* the demux thread will exit normally |
130 | next time through the loop */ | 130 | next time through the loop */ |
131 | spin_unlock(&GlobalMid_Lock); | 131 | spin_unlock(&GlobalMid_Lock); |
@@ -185,7 +185,8 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
185 | spin_unlock(&GlobalMid_Lock); | 185 | spin_unlock(&GlobalMid_Lock); |
186 | up(&server->tcpSem); | 186 | up(&server->tcpSem); |
187 | 187 | ||
188 | while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) { | 188 | while ((server->tcpStatus != CifsExiting) && |
189 | (server->tcpStatus != CifsGood)) { | ||
189 | try_to_freeze(); | 190 | try_to_freeze(); |
190 | if (server->protocolType == IPV6) { | 191 | if (server->protocolType == IPV6) { |
191 | rc = ipv6_connect(&server->addr.sockAddr6, | 192 | rc = ipv6_connect(&server->addr.sockAddr6, |
@@ -202,7 +203,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
202 | } else { | 203 | } else { |
203 | atomic_inc(&tcpSesReconnectCount); | 204 | atomic_inc(&tcpSesReconnectCount); |
204 | spin_lock(&GlobalMid_Lock); | 205 | spin_lock(&GlobalMid_Lock); |
205 | if (!kthread_should_stop()) | 206 | if (server->tcpStatus != CifsExiting) |
206 | server->tcpStatus = CifsGood; | 207 | server->tcpStatus = CifsGood; |
207 | server->sequence_number = 0; | 208 | server->sequence_number = 0; |
208 | spin_unlock(&GlobalMid_Lock); | 209 | spin_unlock(&GlobalMid_Lock); |
@@ -357,7 +358,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
357 | GFP_KERNEL); | 358 | GFP_KERNEL); |
358 | 359 | ||
359 | set_freezable(); | 360 | set_freezable(); |
360 | while (!kthread_should_stop()) { | 361 | while (server->tcpStatus != CifsExiting) { |
361 | if (try_to_freeze()) | 362 | if (try_to_freeze()) |
362 | continue; | 363 | continue; |
363 | if (bigbuf == NULL) { | 364 | if (bigbuf == NULL) { |
@@ -398,7 +399,7 @@ incomplete_rcv: | |||
398 | kernel_recvmsg(csocket, &smb_msg, | 399 | kernel_recvmsg(csocket, &smb_msg, |
399 | &iov, 1, pdu_length, 0 /* BB other flags? */); | 400 | &iov, 1, pdu_length, 0 /* BB other flags? */); |
400 | 401 | ||
401 | if (kthread_should_stop()) { | 402 | if (server->tcpStatus == CifsExiting) { |
402 | break; | 403 | break; |
403 | } else if (server->tcpStatus == CifsNeedReconnect) { | 404 | } else if (server->tcpStatus == CifsNeedReconnect) { |
404 | cFYI(1, ("Reconnect after server stopped responding")); | 405 | cFYI(1, ("Reconnect after server stopped responding")); |
@@ -523,7 +524,7 @@ incomplete_rcv: | |||
523 | total_read += length) { | 524 | total_read += length) { |
524 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, | 525 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, |
525 | pdu_length - total_read, 0); | 526 | pdu_length - total_read, 0); |
526 | if (kthread_should_stop() || | 527 | if ((server->tcpStatus == CifsExiting) || |
527 | (length == -EINTR)) { | 528 | (length == -EINTR)) { |
528 | /* then will exit */ | 529 | /* then will exit */ |
529 | reconnect = 2; | 530 | reconnect = 2; |
@@ -652,14 +653,6 @@ multi_t2_fnd: | |||
652 | spin_unlock(&GlobalMid_Lock); | 653 | spin_unlock(&GlobalMid_Lock); |
653 | wake_up_all(&server->response_q); | 654 | wake_up_all(&server->response_q); |
654 | 655 | ||
655 | /* don't exit until kthread_stop is called */ | ||
656 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
657 | while (!kthread_should_stop()) { | ||
658 | schedule(); | ||
659 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
660 | } | ||
661 | set_current_state(TASK_RUNNING); | ||
662 | |||
663 | /* check if we have blocked requests that need to free */ | 656 | /* check if we have blocked requests that need to free */ |
664 | /* Note that cifs_max_pending is normally 50, but | 657 | /* Note that cifs_max_pending is normally 50, but |
665 | can be set at module install time to as little as two */ | 658 | can be set at module install time to as little as two */ |
@@ -2234,14 +2227,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2234 | spin_lock(&GlobalMid_Lock); | 2227 | spin_lock(&GlobalMid_Lock); |
2235 | srvTcp->tcpStatus = CifsExiting; | 2228 | srvTcp->tcpStatus = CifsExiting; |
2236 | spin_unlock(&GlobalMid_Lock); | 2229 | spin_unlock(&GlobalMid_Lock); |
2237 | if (srvTcp->tsk) { | 2230 | force_sig(SIGKILL, srvTcp->tsk); |
2238 | /* If we could verify that kthread_stop would | ||
2239 | always wake up processes blocked in | ||
2240 | tcp in recv_mesg then we could remove the | ||
2241 | send_sig call */ | ||
2242 | force_sig(SIGKILL, srvTcp->tsk); | ||
2243 | kthread_stop(srvTcp->tsk); | ||
2244 | } | ||
2245 | } | 2231 | } |
2246 | /* If find_unc succeeded then rc == 0 so we can not end */ | 2232 | /* If find_unc succeeded then rc == 0 so we can not end */ |
2247 | if (tcon) /* up accidently freeing someone elses tcon struct */ | 2233 | if (tcon) /* up accidently freeing someone elses tcon struct */ |
@@ -2255,18 +2241,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2255 | /* if the socketUseCount is now zero */ | 2241 | /* if the socketUseCount is now zero */ |
2256 | if ((temp_rc == -ESHUTDOWN) && | 2242 | if ((temp_rc == -ESHUTDOWN) && |
2257 | (pSesInfo->server) && | 2243 | (pSesInfo->server) && |
2258 | (pSesInfo->server->tsk)) { | 2244 | (pSesInfo->server->tsk)) |
2259 | force_sig(SIGKILL, | 2245 | force_sig(SIGKILL, |
2260 | pSesInfo->server->tsk); | 2246 | pSesInfo->server->tsk); |
2261 | kthread_stop(pSesInfo->server->tsk); | ||
2262 | } | ||
2263 | } else { | 2247 | } else { |
2264 | cFYI(1, ("No session or bad tcon")); | 2248 | cFYI(1, ("No session or bad tcon")); |
2265 | if ((pSesInfo->server) && | 2249 | if ((pSesInfo->server) && |
2266 | (pSesInfo->server->tsk)) { | 2250 | (pSesInfo->server->tsk)) { |
2251 | spin_lock(&GlobalMid_Lock); | ||
2252 | srvTcp->tcpStatus = CifsExiting; | ||
2253 | spin_unlock(&GlobalMid_Lock); | ||
2267 | force_sig(SIGKILL, | 2254 | force_sig(SIGKILL, |
2268 | pSesInfo->server->tsk); | 2255 | pSesInfo->server->tsk); |
2269 | kthread_stop(pSesInfo->server->tsk); | ||
2270 | } | 2256 | } |
2271 | } | 2257 | } |
2272 | sesInfoFree(pSesInfo); | 2258 | sesInfoFree(pSesInfo); |
@@ -3577,10 +3563,8 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | |||
3577 | return 0; | 3563 | return 0; |
3578 | } else if (rc == -ESHUTDOWN) { | 3564 | } else if (rc == -ESHUTDOWN) { |
3579 | cFYI(1, ("Waking up socket by sending signal")); | 3565 | cFYI(1, ("Waking up socket by sending signal")); |
3580 | if (cifsd_task) { | 3566 | if (cifsd_task) |
3581 | force_sig(SIGKILL, cifsd_task); | 3567 | force_sig(SIGKILL, cifsd_task); |
3582 | kthread_stop(cifsd_task); | ||
3583 | } | ||
3584 | rc = 0; | 3568 | rc = 0; |
3585 | } /* else - we have an smb session | 3569 | } /* else - we have an smb session |
3586 | left on this socket do not kill cifsd */ | 3570 | left on this socket do not kill cifsd */ |
@@ -3710,7 +3694,9 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
3710 | cERROR(1, ("Send error in SessSetup = %d", rc)); | 3694 | cERROR(1, ("Send error in SessSetup = %d", rc)); |
3711 | } else { | 3695 | } else { |
3712 | cFYI(1, ("CIFS Session Established successfully")); | 3696 | cFYI(1, ("CIFS Session Established successfully")); |
3697 | spin_lock(&GlobalMid_Lock); | ||
3713 | pSesInfo->status = CifsGood; | 3698 | pSesInfo->status = CifsGood; |
3699 | spin_unlock(&GlobalMid_Lock); | ||
3714 | } | 3700 | } |
3715 | 3701 | ||
3716 | ss_err_exit: | 3702 | ss_err_exit: |