Commit c8054ebd authored by Jeff Layton's avatar Jeff Layton

cifs: find mid earlier in receive codepath

In order to receive directly into a preallocated buffer, we need to ID
the mid earlier, before the bulk of the response is read. Call the mid
finding routine as soon as we're able to read the mid.
Reviewed-and-Tested-by: default avatarPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
parent 2a37ef94
...@@ -568,27 +568,21 @@ dequeue_mid(struct mid_q_entry *mid, int malformed) ...@@ -568,27 +568,21 @@ dequeue_mid(struct mid_q_entry *mid, int malformed)
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} }
static struct mid_q_entry * static void
find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
int malformed) struct smb_hdr *buf, int malformed)
{ {
struct mid_q_entry *mid = NULL;
mid = find_mid(server, buf);
if (!mid)
return mid;
if (malformed == 0 && check2ndT2(buf) > 0) { if (malformed == 0 && check2ndT2(buf) > 0) {
mid->multiRsp = true; mid->multiRsp = true;
if (mid->resp_buf) { if (mid->resp_buf) {
/* merge response - fix up 1st*/ /* merge response - fix up 1st*/
malformed = coalesce_t2(buf, mid->resp_buf); malformed = coalesce_t2(buf, mid->resp_buf);
if (malformed > 0) if (malformed > 0)
return mid; return;
/* All parts received or packet is malformed. */ /* All parts received or packet is malformed. */
mid->multiEnd = true; mid->multiEnd = true;
goto multi_t2_fnd; return dequeue_mid(mid, malformed);
} }
if (!server->large_buf) { if (!server->large_buf) {
/*FIXME: switch to already allocated largebuf?*/ /*FIXME: switch to already allocated largebuf?*/
...@@ -599,7 +593,7 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, ...@@ -599,7 +593,7 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
mid->largeBuf = true; mid->largeBuf = true;
server->bigbuf = NULL; server->bigbuf = NULL;
} }
return mid; return;
} }
mid->resp_buf = buf; mid->resp_buf = buf;
mid->largeBuf = server->large_buf; mid->largeBuf = server->large_buf;
...@@ -611,9 +605,7 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, ...@@ -611,9 +605,7 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
else else
server->smallbuf = NULL; server->smallbuf = NULL;
} }
multi_t2_fnd:
dequeue_mid(mid, malformed); dequeue_mid(mid, malformed);
return mid;
} }
static void clean_demultiplex_info(struct TCP_Server_Info *server) static void clean_demultiplex_info(struct TCP_Server_Info *server)
...@@ -775,6 +767,8 @@ cifs_demultiplex_thread(void *p) ...@@ -775,6 +767,8 @@ cifs_demultiplex_thread(void *p)
continue; continue;
server->total_read += length; server->total_read += length;
mid_entry = find_mid(server, smb_buffer);
if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
cERROR(1, "SMB response too long (%u bytes)", cERROR(1, "SMB response too long (%u bytes)",
pdu_length); pdu_length);
...@@ -819,8 +813,8 @@ cifs_demultiplex_thread(void *p) ...@@ -819,8 +813,8 @@ cifs_demultiplex_thread(void *p)
server->lstrp = jiffies; server->lstrp = jiffies;
mid_entry = find_cifs_mid(server, smb_buffer, length);
if (mid_entry != NULL) { if (mid_entry != NULL) {
handle_mid(mid_entry, server, smb_buffer, length);
if (!mid_entry->multiRsp || mid_entry->multiEnd) if (!mid_entry->multiRsp || mid_entry->multiEnd)
mid_entry->callback(mid_entry); mid_entry->callback(mid_entry);
} else if (length != 0) { } else if (length != 0) {
......
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