aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f51b79a67e1..71b7661e226 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -750,6 +750,7 @@ multi_t2_fnd:
750 write_unlock(&GlobalSMBSeslock); 750 write_unlock(&GlobalSMBSeslock);
751 751
752 kfree(server->hostname); 752 kfree(server->hostname);
753 task_to_wake = xchg(&server->tsk, NULL);
753 kfree(server); 754 kfree(server);
754 755
755 length = atomic_dec_return(&tcpSesAllocCount); 756 length = atomic_dec_return(&tcpSesAllocCount);
@@ -757,6 +758,16 @@ multi_t2_fnd:
757 mempool_resize(cifs_req_poolp, length + cifs_min_rcv, 758 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
758 GFP_KERNEL); 759 GFP_KERNEL);
759 760
761 /* if server->tsk was NULL then wait for a signal before exiting */
762 if (!task_to_wake) {
763 set_current_state(TASK_INTERRUPTIBLE);
764 while (!signal_pending(current)) {
765 schedule();
766 set_current_state(TASK_INTERRUPTIBLE);
767 }
768 set_current_state(TASK_RUNNING);
769 }
770
760 return 0; 771 return 0;
761} 772}
762 773
@@ -1846,6 +1857,16 @@ convert_delimiter(char *path, char delim)
1846 } 1857 }
1847} 1858}
1848 1859
1860static void
1861kill_cifsd(struct TCP_Server_Info *server)
1862{
1863 struct task_struct *task;
1864
1865 task = xchg(&server->tsk, NULL);
1866 if (task)
1867 force_sig(SIGKILL, task);
1868}
1869
1849int 1870int
1850cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 1871cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1851 char *mount_data, const char *devname) 1872 char *mount_data, const char *devname)
@@ -2233,7 +2254,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2233 spin_lock(&GlobalMid_Lock); 2254 spin_lock(&GlobalMid_Lock);
2234 srvTcp->tcpStatus = CifsExiting; 2255 srvTcp->tcpStatus = CifsExiting;
2235 spin_unlock(&GlobalMid_Lock); 2256 spin_unlock(&GlobalMid_Lock);
2236 force_sig(SIGKILL, srvTcp->tsk); 2257 kill_cifsd(srvTcp);
2237 } 2258 }
2238 /* If find_unc succeeded then rc == 0 so we can not end */ 2259 /* If find_unc succeeded then rc == 0 so we can not end */
2239 if (tcon) /* up accidently freeing someone elses tcon struct */ 2260 if (tcon) /* up accidently freeing someone elses tcon struct */
@@ -2246,19 +2267,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2246 temp_rc = CIFSSMBLogoff(xid, pSesInfo); 2267 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2247 /* if the socketUseCount is now zero */ 2268 /* if the socketUseCount is now zero */
2248 if ((temp_rc == -ESHUTDOWN) && 2269 if ((temp_rc == -ESHUTDOWN) &&
2249 (pSesInfo->server) && 2270 (pSesInfo->server))
2250 (pSesInfo->server->tsk)) 2271 kill_cifsd(pSesInfo->server);
2251 force_sig(SIGKILL,
2252 pSesInfo->server->tsk);
2253 } else { 2272 } else {
2254 cFYI(1, ("No session or bad tcon")); 2273 cFYI(1, ("No session or bad tcon"));
2255 if ((pSesInfo->server) && 2274 if (pSesInfo->server) {
2256 (pSesInfo->server->tsk)) {
2257 spin_lock(&GlobalMid_Lock); 2275 spin_lock(&GlobalMid_Lock);
2258 srvTcp->tcpStatus = CifsExiting; 2276 srvTcp->tcpStatus = CifsExiting;
2259 spin_unlock(&GlobalMid_Lock); 2277 spin_unlock(&GlobalMid_Lock);
2260 force_sig(SIGKILL, 2278 kill_cifsd(pSesInfo->server);
2261 pSesInfo->server->tsk);
2262 } 2279 }
2263 } 2280 }
2264 sesInfoFree(pSesInfo); 2281 sesInfoFree(pSesInfo);
@@ -3545,7 +3562,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3545 int rc = 0; 3562 int rc = 0;
3546 int xid; 3563 int xid;
3547 struct cifsSesInfo *ses = NULL; 3564 struct cifsSesInfo *ses = NULL;
3548 struct task_struct *cifsd_task;
3549 char *tmp; 3565 char *tmp;
3550 3566
3551 xid = GetXid(); 3567 xid = GetXid();
@@ -3561,7 +3577,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3561 tconInfoFree(cifs_sb->tcon); 3577 tconInfoFree(cifs_sb->tcon);
3562 if ((ses) && (ses->server)) { 3578 if ((ses) && (ses->server)) {
3563 /* save off task so we do not refer to ses later */ 3579 /* save off task so we do not refer to ses later */
3564 cifsd_task = ses->server->tsk;
3565 cFYI(1, ("About to do SMBLogoff ")); 3580 cFYI(1, ("About to do SMBLogoff "));
3566 rc = CIFSSMBLogoff(xid, ses); 3581 rc = CIFSSMBLogoff(xid, ses);
3567 if (rc == -EBUSY) { 3582 if (rc == -EBUSY) {
@@ -3569,8 +3584,8 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3569 return 0; 3584 return 0;
3570 } else if (rc == -ESHUTDOWN) { 3585 } else if (rc == -ESHUTDOWN) {
3571 cFYI(1, ("Waking up socket by sending signal")); 3586 cFYI(1, ("Waking up socket by sending signal"));
3572 if (cifsd_task) 3587 if (ses->server)
3573 force_sig(SIGKILL, cifsd_task); 3588 kill_cifsd(ses->server);
3574 rc = 0; 3589 rc = 0;
3575 } /* else - we have an smb session 3590 } /* else - we have an smb session
3576 left on this socket do not kill cifsd */ 3591 left on this socket do not kill cifsd */