Commit e70aaeb1 authored by Steve French's avatar Steve French

lock session when reconnecting so we do not oops in retrying sendmsg

Signed-off-by: Steve French (sfrench@us.ibm.com)
parent 6774af67
...@@ -128,7 +128,8 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -128,7 +128,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
} }
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
/* do not want to be sending data on a socket we are freeing */
down(&server->tcpSem);
if(server->ssocket) { if(server->ssocket) {
cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state, cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
server->ssocket->flags)); server->ssocket->flags));
...@@ -154,7 +155,7 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -154,7 +155,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
} }
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
up(&ses->server->tcpSem);
while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood)) while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
{ {
......
...@@ -120,6 +120,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, ...@@ -120,6 +120,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
unsigned int smb_buf_length, struct sockaddr *sin) unsigned int smb_buf_length, struct sockaddr *sin)
{ {
int rc = 0; int rc = 0;
int i = 0;
struct msghdr smb_msg; struct msghdr smb_msg;
struct iovec iov; struct iovec iov;
mm_segment_t temp_fs; mm_segment_t temp_fs;
...@@ -151,6 +152,14 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, ...@@ -151,6 +152,14 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
while(iov.iov_len > 0) { while(iov.iov_len > 0) {
rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4); rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
if ((rc == -ENOSPC) || (rc == -EAGAIN)) { if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
i++;
if(i > 60) {
cERROR(1,
("sends on sock %p stuck for 30 seconds",
ssocket));
rc = -EAGAIN;
break;
}
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/2); schedule_timeout(HZ/2);
continue; continue;
...@@ -259,6 +268,16 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -259,6 +268,16 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
midQ->midState = MID_REQUEST_SUBMITTED; midQ->midState = MID_REQUEST_SUBMITTED;
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
(struct sockaddr *) &(ses->server->addr.sockAddr)); (struct sockaddr *) &(ses->server->addr.sockAddr));
if(rc < 0) {
DeleteMidQEntry(midQ);
up(&ses->server->tcpSem);
/* If not lock req, update # of requests on wire to server */
if(long_op < 3) {
atomic_dec(&ses->server->inFlight);
wake_up(&ses->server->request_q);
}
return rc;
} else
up(&ses->server->tcpSem); up(&ses->server->tcpSem);
if (long_op == -1) if (long_op == -1)
goto cifs_no_response_exit; goto cifs_no_response_exit;
......
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