summaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-19 15:29:31 -0400
committerJeff Layton <jlayton@redhat.com>2011-10-19 15:29:31 -0400
commitc8054ebdb6903208b83aa59c387b16d5129492d5 (patch)
tree14ccf83e7b917303d1724818142e2cd07f13cc2d /fs/cifs
parent2a37ef94bb153fad13cbb091aab679d7c8b9a67f (diff)
downloadlinux-stable-c8054ebdb6903208b83aa59c387b16d5129492d5.tar.gz
linux-stable-c8054ebdb6903208b83aa59c387b16d5129492d5.tar.bz2
linux-stable-c8054ebdb6903208b83aa59c387b16d5129492d5.zip
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: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8918f935bf07..52195bad5e67 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -568,27 +568,21 @@ dequeue_mid(struct mid_q_entry *mid, int malformed)
spin_unlock(&GlobalMid_Lock);
}
-static struct mid_q_entry *
-find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
- int malformed)
+static void
+handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
+ 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) {
mid->multiRsp = true;
if (mid->resp_buf) {
/* merge response - fix up 1st*/
malformed = coalesce_t2(buf, mid->resp_buf);
if (malformed > 0)
- return mid;
+ return;
/* All parts received or packet is malformed. */
mid->multiEnd = true;
- goto multi_t2_fnd;
+ return dequeue_mid(mid, malformed);
}
if (!server->large_buf) {
/*FIXME: switch to already allocated largebuf?*/
@@ -599,7 +593,7 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
mid->largeBuf = true;
server->bigbuf = NULL;
}
- return mid;
+ return;
}
mid->resp_buf = buf;
mid->largeBuf = server->large_buf;
@@ -611,9 +605,7 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
else
server->smallbuf = NULL;
}
-multi_t2_fnd:
dequeue_mid(mid, malformed);
- return mid;
}
static void clean_demultiplex_info(struct TCP_Server_Info *server)
@@ -775,6 +767,8 @@ cifs_demultiplex_thread(void *p)
continue;
server->total_read += length;
+ mid_entry = find_mid(server, smb_buffer);
+
if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
cERROR(1, "SMB response too long (%u bytes)",
pdu_length);
@@ -819,8 +813,8 @@ cifs_demultiplex_thread(void *p)
server->lstrp = jiffies;
- mid_entry = find_cifs_mid(server, smb_buffer, length);
if (mid_entry != NULL) {
+ handle_mid(mid_entry, server, smb_buffer, length);
if (!mid_entry->multiRsp || mid_entry->multiEnd)
mid_entry->callback(mid_entry);
} else if (length != 0) {