Commit ea1f4502 authored by Jeff Layton's avatar Jeff Layton

cifs: move mid finding into separate routine

Begin breaking up find_cifs_mid into smaller pieces. The parts that
coalesce T2 responses don't really need to be done under the
GlobalMid_lock anyway. Create a new function that just finds the
mid on the list, and then later takes it off the list if the entire
response has been received.
Reviewed-and-Tested-by: default avatarPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
parent 89482a56
...@@ -542,28 +542,59 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type) ...@@ -542,28 +542,59 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
} }
static struct mid_q_entry * static struct mid_q_entry *
find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, find_mid(struct TCP_Server_Info *server, struct smb_hdr *buf)
int *length, bool is_large_buf, bool *is_multi_rsp, char **bigbuf)
{ {
struct mid_q_entry *mid = NULL, *tmp_mid, *ret = NULL; struct mid_q_entry *mid;
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_for_each_entry_safe(mid, tmp_mid, &server->pending_mid_q, qhead) { list_for_each_entry(mid, &server->pending_mid_q, qhead) {
if (mid->mid != buf->Mid || if (mid->mid == buf->Mid &&
mid->midState != MID_REQUEST_SUBMITTED || mid->midState == MID_REQUEST_SUBMITTED &&
mid->command != buf->Command) mid->command == buf->Command) {
continue; spin_unlock(&GlobalMid_Lock);
return mid;
}
}
spin_unlock(&GlobalMid_Lock);
return NULL;
}
static void
dequeue_mid(struct mid_q_entry *mid, int malformed)
{
#ifdef CONFIG_CIFS_STATS2
mid->when_received = jiffies;
#endif
spin_lock(&GlobalMid_Lock);
if (!malformed)
mid->midState = MID_RESPONSE_RECEIVED;
else
mid->midState = MID_RESPONSE_MALFORMED;
list_del_init(&mid->qhead);
spin_unlock(&GlobalMid_Lock);
}
static struct mid_q_entry *
find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
int *malformed, bool is_large_buf, bool *is_multi_rsp,
char **bigbuf)
{
struct mid_q_entry *mid = NULL;
if (*length == 0 && check2ndT2(buf) > 0) { mid = find_mid(server, buf);
if (!mid)
return mid;
if (*malformed == 0 && check2ndT2(buf) > 0) {
/* We have a multipart transact2 resp */ /* We have a multipart transact2 resp */
*is_multi_rsp = true; *is_multi_rsp = true;
if (mid->resp_buf) { if (mid->resp_buf) {
/* merge response - fix up 1st*/ /* merge response - fix up 1st*/
*length = coalesce_t2(buf, mid->resp_buf); *malformed = coalesce_t2(buf, mid->resp_buf);
if (*length > 0) { if (*malformed > 0) {
*length = 0; *malformed = 0;
mid->multiRsp = true; mid->multiRsp = true;
break; return NULL;
} }
/* All parts received or packet is malformed. */ /* All parts received or packet is malformed. */
mid->multiEnd = true; mid->multiEnd = true;
...@@ -578,25 +609,13 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, ...@@ -578,25 +609,13 @@ find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
mid->largeBuf = true; mid->largeBuf = true;
*bigbuf = NULL; *bigbuf = NULL;
} }
break; return mid;
} }
mid->resp_buf = buf; mid->resp_buf = buf;
mid->largeBuf = is_large_buf; mid->largeBuf = is_large_buf;
multi_t2_fnd: multi_t2_fnd:
if (*length == 0) dequeue_mid(mid, *malformed);
mid->midState = MID_RESPONSE_RECEIVED; return mid;
else
mid->midState = MID_RESPONSE_MALFORMED;
#ifdef CONFIG_CIFS_STATS2
mid->when_received = jiffies;
#endif
list_del_init(&mid->qhead);
ret = mid;
break;
}
spin_unlock(&GlobalMid_Lock);
return ret;
} }
static void clean_demultiplex_info(struct TCP_Server_Info *server) static void clean_demultiplex_info(struct TCP_Server_Info *server)
......
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