struct cifsTconInfo *tcon;
struct mid_q_entry * mid_entry;
- if(server->tcpStatus == CifsExiting)
+ spin_lock(&GlobalMid_Lock);
+ if(server->tcpStatus == CifsExiting) {
+ /* the demux thread will exit normally
+ next time through the loop */
+ spin_unlock(&GlobalMid_Lock);
return rc;
- server->tcpStatus = CifsNeedReconnect;
+ } else
+ server->tcpStatus = CifsNeedReconnect;
+ spin_unlock(&GlobalMid_Lock);
server->maxBuf = 0;
cFYI(1, ("Reconnecting tcp session "));
}
}
read_unlock(&GlobalSMBSeslock);
-
+ /* do not want to be sending data on a socket we are freeing */
+ down(&server->tcpSem);
if(server->ssocket) {
cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
server->ssocket->flags));
}
}
spin_unlock(&GlobalMid_Lock);
-
+ up(&server->tcpSem);
while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
{
schedule_timeout(3 * HZ);
} else {
atomic_inc(&tcpSesReconnectCount);
- server->tcpStatus = CifsGood;
+ spin_lock(&GlobalMid_Lock);
+ if(server->tcpStatus != CifsExiting)
+ server->tcpStatus = CifsGood;
+ spin_unlock(&GlobalMid_Lock);
atomic_set(&server->inFlight,0);
wake_up(&server->response_q);
}
/* some servers kill tcp session rather than returning
smb negprot error in which case reconnecting here is
not going to help - return error to mount */
+ spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
wake_up(&server->response_q);
break;
}
- cFYI(1,("Reconnecting after unexpected rcvmsg error "));
+ cFYI(1,("Reconnecting after unexpected peek error %d",length));
cifs_reconnect(server);
csocket = server->ssocket;
wake_up(&server->response_q);
length = sock_recvmsg(csocket, &smb_msg, 4, 0);
cFYI(0,("Received 4 byte keep alive packet"));
} else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) {
- iov.iov_base = smb_buffer;
+ iov.iov_base = smb_buffer;
iov.iov_len = 4;
length = sock_recvmsg(csocket, &smb_msg, 4, 0);
cFYI(1,("Good RFC 1002 session rsp"));
/* if nack on negprot (rather than
ret of smb negprot error) reconnecting
not going to help, ret error to mount */
+ spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
/* wake up thread doing negprot */
wake_up(&server->response_q);
break;
}
}
}
+ spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
atomic_set(&server->inFlight, 0);
/* Although there should not be any requests blocked on
this queue it can not hurt to be paranoid and try to wake up requests
}
if ((temp_len = strnlen(value, 300)) < 300) {
vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
+ if(vol->UNC == NULL)
+ return 1;
strcpy(vol->UNC,value);
if (strncmp(vol->UNC, "//", 2) == 0) {
vol->UNC[0] = '\\';
}
if ((temp_len = strnlen(devname, 300)) < 300) {
vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
+ if(vol->UNC == NULL)
+ return 1;
strcpy(vol->UNC,devname);
if (strncmp(vol->UNC, "//", 2) == 0) {
vol->UNC[0] = '\\';
} else {
/* BB other socket options to set KEEPALIVE, NODELAY? */
cFYI(1,("ipv6 Socket created"));
- (*csocket)->sk->sk_allocation = GFP_NOFS;
+ (*csocket)->sk->sk_allocation = GFP_NOFS;
}
}
init_waitqueue_head(&srvTcp->response_q);
init_waitqueue_head(&srvTcp->request_q);
INIT_LIST_HEAD(&srvTcp->pending_mid_q);
+ /* at this point we are the only ones with the pointer
+ to the struct since the kernel thread not created yet
+ so no need to spinlock this init of tcpStatus */
srvTcp->tcpStatus = CifsNew;
init_MUTEX(&srvTcp->tcpSem);
kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
/* on error free sesinfo and tcon struct if needed */
if (rc) {
- if(atomic_read(&srvTcp->socketUseCount) == 0)
- srvTcp->tcpStatus = CifsExiting;
- /* If find_unc succeeded then rc == 0 so we can not end */
+ if(atomic_read(&srvTcp->socketUseCount) == 0) {
+ spin_lock(&GlobalMid_Lock);
+ srvTcp->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
+ }
+ /* If find_unc succeeded then rc == 0 so we can not end */
if (tcon) /* up here accidently freeing someone elses tcon struct */
tconInfoFree(tcon);
if (existingCifsSes == 0) {
bcc_ptr +=
pSMBr->resp.SecurityBlobLength;
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
pSMBr->resp.SecurityBlobLength));
}
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
ses->server->secMode |=
SECMODE_SIGN_ENABLED;
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
cFYI(1,
("NTLMSSP response to Authenticate "));
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) {
remaining_words =
(BCC(smb_buffer_response)
/* skip service field (NB: this field is always ASCII) */
bcc_ptr += length + 1;
strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
- if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
length = UniStrnlen((wchar_t *) bcc_ptr, 512);
if (((long) bcc_ptr + (2 * length)) -
(long) pByteArea(smb_buffer_response) <=
char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
int ntlmv2_flag = FALSE;
- /* what if server changes its buffer size after dropping the session? */
+ /* what if server changes its buffer size after dropping the session? */
if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
rc = CIFSSMBNegotiate(xid, pSesInfo);
if(rc == -EAGAIN) /* retry only once on 1st time connection */ {
if(rc == -EAGAIN)
rc = -EHOSTDOWN;
}
- if(rc == 0)
- pSesInfo->server->tcpStatus = CifsGood;
+ if(rc == 0) {
+ spin_lock(&GlobalMid_Lock);
+ if(pSesInfo->server->tcpStatus != CifsExiting)
+ pSesInfo->server->tcpStatus = CifsGood;
+ else
+ rc = -EHOSTDOWN;
+ spin_unlock(&GlobalMid_Lock);
+
+ }
}
if (!rc) {
pSesInfo->capabilities = pSesInfo->server->capabilities;