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.c79
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
1319static struct cifsSesInfo * 1328static struct cifsSesInfo *
1320cifs_find_tcp_session(struct in_addr *target_ip_addr, 1329cifs_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);