diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 79 |
1 files changed, 40 insertions, 39 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 791ca5c1a116..f428bf3bf1a9 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -348,7 +348,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
348 | int reconnect; | 348 | int reconnect; |
349 | 349 | ||
350 | current->flags |= PF_MEMALLOC; | 350 | current->flags |= PF_MEMALLOC; |
351 | server->tsk = current; /* save process info to wake at shutdown */ | ||
352 | cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); | 351 | cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); |
353 | write_lock(&GlobalSMBSeslock); | 352 | write_lock(&GlobalSMBSeslock); |
354 | atomic_inc(&tcpSesAllocCount); | 353 | atomic_inc(&tcpSesAllocCount); |
@@ -651,10 +650,20 @@ multi_t2_fnd: | |||
651 | 650 | ||
652 | spin_lock(&GlobalMid_Lock); | 651 | spin_lock(&GlobalMid_Lock); |
653 | server->tcpStatus = CifsExiting; | 652 | server->tcpStatus = CifsExiting; |
654 | server->tsk = NULL; | 653 | spin_unlock(&GlobalMid_Lock); |
654 | |||
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 | |||
655 | /* check if we have blocked requests that need to free */ | 663 | /* check if we have blocked requests that need to free */ |
656 | /* Note that cifs_max_pending is normally 50, but | 664 | /* Note that cifs_max_pending is normally 50, but |
657 | can be set at module install time to as little as two */ | 665 | can be set at module install time to as little as two */ |
666 | spin_lock(&GlobalMid_Lock); | ||
658 | if (atomic_read(&server->inFlight) >= cifs_max_pending) | 667 | if (atomic_read(&server->inFlight) >= cifs_max_pending) |
659 | atomic_set(&server->inFlight, cifs_max_pending - 1); | 668 | atomic_set(&server->inFlight, cifs_max_pending - 1); |
660 | /* We do not want to set the max_pending too low or we | 669 | /* We do not want to set the max_pending too low or we |
@@ -1318,42 +1327,43 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1318 | 1327 | ||
1319 | static struct cifsSesInfo * | 1328 | static struct cifsSesInfo * |
1320 | cifs_find_tcp_session(struct in_addr *target_ip_addr, | 1329 | cifs_find_tcp_session(struct in_addr *target_ip_addr, |
1321 | struct in6_addr *target_ip6_addr, | 1330 | struct in6_addr *target_ip6_addr, |
1322 | char *userName, struct TCP_Server_Info **psrvTcp) | 1331 | char *userName, struct TCP_Server_Info **psrvTcp) |
1323 | { | 1332 | { |
1324 | struct list_head *tmp; | 1333 | struct list_head *tmp; |
1325 | struct cifsSesInfo *ses; | 1334 | struct cifsSesInfo *ses; |
1335 | |||
1326 | *psrvTcp = NULL; | 1336 | *psrvTcp = NULL; |
1327 | read_lock(&GlobalSMBSeslock); | ||
1328 | 1337 | ||
1338 | read_lock(&GlobalSMBSeslock); | ||
1329 | list_for_each(tmp, &GlobalSMBSessionList) { | 1339 | list_for_each(tmp, &GlobalSMBSessionList) { |
1330 | ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); | 1340 | ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); |
1331 | if (ses->server) { | 1341 | if (!ses->server) |
1332 | if ((target_ip_addr && | 1342 | continue; |
1333 | (ses->server->addr.sockAddr.sin_addr.s_addr | 1343 | |
1334 | == target_ip_addr->s_addr)) || (target_ip6_addr | 1344 | if (target_ip_addr && |
1335 | && memcmp(&ses->server->addr.sockAddr6.sin6_addr, | 1345 | ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr) |
1336 | target_ip6_addr, sizeof(*target_ip6_addr)))) { | 1346 | continue; |
1337 | /* BB lock server and tcp session and increment | 1347 | else if (target_ip6_addr && |
1338 | use count here?? */ | 1348 | memcmp(&ses->server->addr.sockAddr6.sin6_addr, |
1339 | 1349 | target_ip6_addr, sizeof(*target_ip6_addr))) | |
1340 | /* found a match on the TCP session */ | 1350 | continue; |
1341 | *psrvTcp = ses->server; | 1351 | /* BB lock server and tcp session; increment use count here?? */ |
1342 | 1352 | ||
1343 | /* BB check if reconnection needed */ | 1353 | /* found a match on the TCP session */ |
1344 | if (strncmp | 1354 | *psrvTcp = ses->server; |
1345 | (ses->userName, userName, | 1355 | |
1346 | MAX_USERNAME_SIZE) == 0){ | 1356 | /* BB check if reconnection needed */ |
1347 | read_unlock(&GlobalSMBSeslock); | 1357 | if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) { |
1348 | /* Found exact match on both TCP and | 1358 | read_unlock(&GlobalSMBSeslock); |
1349 | SMB sessions */ | 1359 | /* Found exact match on both TCP and |
1350 | return ses; | 1360 | SMB sessions */ |
1351 | } | 1361 | return ses; |
1352 | } | ||
1353 | } | 1362 | } |
1354 | /* else tcp and smb sessions need reconnection */ | 1363 | /* else tcp and smb sessions need reconnection */ |
1355 | } | 1364 | } |
1356 | read_unlock(&GlobalSMBSeslock); | 1365 | read_unlock(&GlobalSMBSeslock); |
1366 | |||
1357 | return NULL; | 1367 | return NULL; |
1358 | } | 1368 | } |
1359 | 1369 | ||
@@ -2186,15 +2196,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2186 | srvTcp->tcpStatus = CifsExiting; | 2196 | srvTcp->tcpStatus = CifsExiting; |
2187 | spin_unlock(&GlobalMid_Lock); | 2197 | spin_unlock(&GlobalMid_Lock); |
2188 | if (srvTcp->tsk) { | 2198 | if (srvTcp->tsk) { |
2189 | struct task_struct *tsk; | ||
2190 | /* If we could verify that kthread_stop would | 2199 | /* If we could verify that kthread_stop would |
2191 | always wake up processes blocked in | 2200 | always wake up processes blocked in |
2192 | tcp in recv_mesg then we could remove the | 2201 | tcp in recv_mesg then we could remove the |
2193 | send_sig call */ | 2202 | send_sig call */ |
2194 | force_sig(SIGKILL, srvTcp->tsk); | 2203 | force_sig(SIGKILL, srvTcp->tsk); |
2195 | tsk = srvTcp->tsk; | 2204 | kthread_stop(srvTcp->tsk); |
2196 | if (tsk) | ||
2197 | kthread_stop(tsk); | ||
2198 | } | 2205 | } |
2199 | } | 2206 | } |
2200 | /* If find_unc succeeded then rc == 0 so we can not end */ | 2207 | /* If find_unc succeeded then rc == 0 so we can not end */ |
@@ -2210,23 +2217,17 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2210 | if ((temp_rc == -ESHUTDOWN) && | 2217 | if ((temp_rc == -ESHUTDOWN) && |
2211 | (pSesInfo->server) && | 2218 | (pSesInfo->server) && |
2212 | (pSesInfo->server->tsk)) { | 2219 | (pSesInfo->server->tsk)) { |
2213 | struct task_struct *tsk; | ||
2214 | force_sig(SIGKILL, | 2220 | force_sig(SIGKILL, |
2215 | pSesInfo->server->tsk); | 2221 | pSesInfo->server->tsk); |
2216 | tsk = pSesInfo->server->tsk; | 2222 | kthread_stop(pSesInfo->server->tsk); |
2217 | if (tsk) | ||
2218 | kthread_stop(tsk); | ||
2219 | } | 2223 | } |
2220 | } else { | 2224 | } else { |
2221 | cFYI(1, ("No session or bad tcon")); | 2225 | cFYI(1, ("No session or bad tcon")); |
2222 | if ((pSesInfo->server) && | 2226 | if ((pSesInfo->server) && |
2223 | (pSesInfo->server->tsk)) { | 2227 | (pSesInfo->server->tsk)) { |
2224 | struct task_struct *tsk; | ||
2225 | force_sig(SIGKILL, | 2228 | force_sig(SIGKILL, |
2226 | pSesInfo->server->tsk); | 2229 | pSesInfo->server->tsk); |
2227 | tsk = pSesInfo->server->tsk; | 2230 | kthread_stop(pSesInfo->server->tsk); |
2228 | if (tsk) | ||
2229 | kthread_stop(tsk); | ||
2230 | } | 2231 | } |
2231 | } | 2232 | } |
2232 | sesInfoFree(pSesInfo); | 2233 | sesInfoFree(pSesInfo); |