Commit a52c1eb7 authored by Jeff Layton's avatar Jeff Layton Committed by Steve French

cifs: simplify read_from_socket

Move the iovec handling entirely into read_from_socket. That simplifies
the code and gets rid of the special handling for header reads. With
this we can also get rid of the "goto incomplete_rcv" label in the main
demultiplex thread function since we can now treat header and non-header
receives the same way.

Also, make it return an int (since we'll never receive enough to worry
about the sign bit anyway), and simply make it return the amount of bytes
read or a negative error code.
Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent 21fed0d5
...@@ -376,35 +376,33 @@ server_unresponsive(struct TCP_Server_Info *server) ...@@ -376,35 +376,33 @@ server_unresponsive(struct TCP_Server_Info *server)
} }
static int static int
read_from_socket(struct TCP_Server_Info *server, read_from_socket(struct TCP_Server_Info *server, char *buf,
struct kvec *iov, unsigned int to_read, unsigned int to_read)
unsigned int *ptotal_read, bool is_header_read)
{ {
int length, rc = 0; int length = 0;
unsigned int total_read; int total_read;
struct msghdr smb_msg; struct msghdr smb_msg;
char *buf = iov->iov_base; struct kvec iov;
smb_msg.msg_control = NULL; smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0; smb_msg.msg_controllen = 0;
for (total_read = 0; total_read < to_read; total_read += length) { for (total_read = 0; to_read; total_read += length, to_read -= length) {
if (server_unresponsive(server)) { if (server_unresponsive(server)) {
rc = 1; total_read = -EAGAIN;
break; break;
} }
length = kernel_recvmsg(server->ssocket, &smb_msg, iov, 1, iov.iov_base = buf + total_read;
to_read - total_read, 0); iov.iov_len = to_read;
length = kernel_recvmsg(server->ssocket, &smb_msg, &iov, 1,
to_read, 0);
if (server->tcpStatus == CifsExiting) { if (server->tcpStatus == CifsExiting) {
/* then will exit */ total_read = -ESHUTDOWN;
rc = 2;
break; break;
} else if (server->tcpStatus == CifsNeedReconnect) { } else if (server->tcpStatus == CifsNeedReconnect) {
cifs_reconnect(server); cifs_reconnect(server);
/* Reconnect wakes up rspns q */ total_read = -EAGAIN;
/* Now we will reread sock */
rc = 1;
break; break;
} else if (length == -ERESTARTSYS || } else if (length == -ERESTARTSYS ||
length == -EAGAIN || length == -EAGAIN ||
...@@ -416,28 +414,16 @@ read_from_socket(struct TCP_Server_Info *server, ...@@ -416,28 +414,16 @@ read_from_socket(struct TCP_Server_Info *server,
*/ */
usleep_range(1000, 2000); usleep_range(1000, 2000);
length = 0; length = 0;
if (!is_header_read)
continue; continue;
/* Special handling for header read */
if (total_read) {
iov->iov_base = (to_read - total_read) +
buf;
iov->iov_len = to_read - total_read;
rc = 3;
} else
rc = 1;
break;
} else if (length <= 0) { } else if (length <= 0) {
cERROR(1, "Received no data, expecting %d", cFYI(1, "Received no data or error: expecting %d "
to_read - total_read); "got %d", to_read, length);
cifs_reconnect(server); cifs_reconnect(server);
rc = 1; total_read = -EAGAIN;
break; break;
} }
} }
return total_read;
*ptotal_read = total_read;
return rc;
} }
static bool static bool
...@@ -658,12 +644,10 @@ cifs_demultiplex_thread(void *p) ...@@ -658,12 +644,10 @@ cifs_demultiplex_thread(void *p)
unsigned int pdu_length, total_read; unsigned int pdu_length, total_read;
char *buf = NULL, *bigbuf = NULL, *smallbuf = NULL; char *buf = NULL, *bigbuf = NULL, *smallbuf = NULL;
struct smb_hdr *smb_buffer = NULL; struct smb_hdr *smb_buffer = NULL;
struct kvec iov;
struct task_struct *task_to_wake = NULL; struct task_struct *task_to_wake = NULL;
struct mid_q_entry *mid_entry; struct mid_q_entry *mid_entry;
bool isLargeBuf = false; bool isLargeBuf = false;
bool isMultiRsp = false; bool isMultiRsp = false;
int rc;
current->flags |= PF_MEMALLOC; current->flags |= PF_MEMALLOC;
cFYI(1, "Demultiplex PID: %d", task_pid_nr(current)); cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
...@@ -686,19 +670,12 @@ cifs_demultiplex_thread(void *p) ...@@ -686,19 +670,12 @@ cifs_demultiplex_thread(void *p)
isMultiRsp = false; isMultiRsp = false;
smb_buffer = (struct smb_hdr *)smallbuf; smb_buffer = (struct smb_hdr *)smallbuf;
buf = smallbuf; buf = smallbuf;
iov.iov_base = buf;
iov.iov_len = 4;
pdu_length = 4; /* enough to get RFC1001 header */ pdu_length = 4; /* enough to get RFC1001 header */
incomplete_rcv: length = read_from_socket(server, buf, pdu_length);
rc = read_from_socket(server, &iov, pdu_length, if (length < 0)
&total_read, true /* header read */);
if (rc == 3)
goto incomplete_rcv;
else if (rc == 2)
break;
else if (rc == 1)
continue; continue;
total_read = length;
/* /*
* The right amount was read from socket - 4 bytes, * The right amount was read from socket - 4 bytes,
...@@ -718,16 +695,10 @@ cifs_demultiplex_thread(void *p) ...@@ -718,16 +695,10 @@ cifs_demultiplex_thread(void *p)
buf = bigbuf; buf = bigbuf;
} }
iov.iov_base = 4 + buf; length = read_from_socket(server, buf + 4, pdu_length);
iov.iov_len = pdu_length; if (length < 0)
rc = read_from_socket(server, &iov, pdu_length,
&total_read, false);
if (rc == 2)
break;
else if (rc == 1)
continue; continue;
total_read += length;
total_read += 4; /* account for rfc1002 hdr */
dump_smb(smb_buffer, total_read); dump_smb(smb_buffer, total_read);
......
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