Commit bb550c6e authored by Steve French's avatar Steve French Committed by Steve French

fixes for socket retry and error handling of misc. error paths

parent 38aad1bc
Version 1.12
------------
Fixes for large file copy, signal handling, socket retry, buffer
allocation and low memory situations.
Version 1.11
------------
Better port 139 support to Windows servers (RFC1001/RFC1002 Session_Initialize) also
now allowing support for specifying client netbiosname. NT4 support added.
Better port 139 support to Windows servers (RFC1001/RFC1002 Session_Initialize)
also now allowing support for specifying client netbiosname. NT4 support added.
Version 1.10
------------
......
......@@ -1509,7 +1509,7 @@ CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
TRANSACTION2_QPI_REQ *pSMB = NULL;
TRANSACTION2_QPI_RSP *pSMBr = NULL;
int rc = 0;
int bytes_returned;
int bytes_returned = 0;
int name_len;
cFYI(1, ("In QPathInfo (Unix) the path %s", searchName));
......@@ -1565,9 +1565,13 @@ CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
} else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
/* BB also check if enough total bytes returned */
if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512))
if ((pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO) + sizeof(FILE_UNIX_BASIC_INFO)) ||
(pSMBr->DataOffset > 512) ||
(pSMBr->DataOffset < sizeof(struct smb_hdr))) {
cFYI(1,("UnixQPathinfo invalid data offset %d bytes returned %d",
(int)pSMBr->DataOffset,bytes_returned));
rc = -EIO; /* bad smb */
else {
} else {
memcpy((char *) pFindData,
(char *) &pSMBr->hdr.Protocol +
pSMBr->DataOffset,
......
......@@ -201,9 +201,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
memset(smb_buffer, 0, sizeof (struct smb_hdr));
if (smb_buffer == NULL) {
cERROR(1,
("Can not get mem for SMB response buffer "));
return -ENOMEM;
cERROR(1,("Can not get memory for SMB response"));
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ * 3); /* give system time to free memory */
continue;
}
iov.iov_base = smb_buffer;
iov.iov_len = sizeof (struct smb_hdr) - 1;
......
......@@ -1362,6 +1362,11 @@ static void reset_resume_key(struct file * dir_file,
cifsFile->search_resume_name =
kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
if(cifsFile->search_resume_name == NULL) {
cERROR(1,("failed new resume key allocate, length %d",
cifsFile->resume_name_length));
return;
}
if(Unicode)
cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name,
filename, len, nls_tab);
......
......@@ -149,19 +149,25 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
temp_fs = get_fs(); /* we must turn off socket api parm checking */
set_fs(get_ds());
while(iov.iov_len > 0) {
rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
while((rc == -ENOSPC) || (rc == -EAGAIN)) {
if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/2);
rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
continue;
}
if (rc < 0)
break;
iov.iov_base += rc;
iov.iov_len -= rc;
}
set_fs(temp_fs);
if (rc < 0) {
cERROR(1,
("Error %d sending data on socket to server.", rc));
} else
cERROR(1,("Error %d sending data on socket to server.", rc));
} else {
rc = 0;
}
return rc;
}
......@@ -239,7 +245,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
but we still give response a change to complete */
if(midQ->midState & MID_REQUEST_SUBMITTED) {
set_current_state(TASK_UNINTERRUPTIBLE);
timeout = schedule_timeout(2 * HZ);
timeout = sleep_on_timeout(&ses->server->response_q,2 * HZ);
}
} else { /* using normal timeout */
/* timeout = wait_event_interruptible_timeout(ses->server->response_q,
......@@ -250,22 +256,16 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
/* Can not allow user interrupts- wreaks havoc with performance */
if(midQ->midState & MID_REQUEST_SUBMITTED) {
set_current_state(TASK_UNINTERRUPTIBLE);
timeout = schedule_timeout(timeout);
timeout = sleep_on_timeout(&ses->server->response_q,timeout);
}
}
if (signal_pending(current)) {
if (midQ->resp_buf == NULL)
rc = -EINTR; /* BB are we supposed to return -ERESTARTSYS ? */
DeleteMidQEntry(midQ);
return rc; /* why bother returning an error if it succeeded */
} else { /* BB spinlock protect this against races with demux thread */
spin_lock(&GlobalMid_Lock);
if (midQ->resp_buf) {
spin_unlock(&GlobalMid_Lock);
receive_len =
be32_to_cpu(midQ->resp_buf->smb_buf_length);
receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length);
} else {
cFYI(1,("No response buffer"));
cERROR(1,("No response buffer"));
if(midQ->midState == MID_REQUEST_SUBMITTED) {
if(ses->server->tcpStatus == CifsExiting)
rc = -EHOSTDOWN;
......@@ -287,7 +287,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
DeleteMidQEntry(midQ);
return rc;
}
}
if (receive_len > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
cERROR(1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment