aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-19 15:29:05 -0400
committerJeff Layton <jlayton@redhat.com>2011-10-19 15:29:05 -0400
commitea1f4502fc939b64807f9ab0eca259321047fe83 (patch)
treed572678f31748fa8e4012747008cad6e892b3f9f /fs/cifs
parent89482a56a079f01c2f4c709f8e23fbf7eeda1b43 (diff)
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: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/connect.c113
1 files changed, 66 insertions, 47 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5308bc6e1248..0f69b311d3fc 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -542,61 +542,80 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
542} 542}
543 543
544static struct mid_q_entry * 544static struct mid_q_entry *
545find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf, 545find_mid(struct TCP_Server_Info *server, struct smb_hdr *buf)
546 int *length, bool is_large_buf, bool *is_multi_rsp, char **bigbuf)
547{ 546{
548 struct mid_q_entry *mid = NULL, *tmp_mid, *ret = NULL; 547 struct mid_q_entry *mid;
549 548
550 spin_lock(&GlobalMid_Lock); 549 spin_lock(&GlobalMid_Lock);
551 list_for_each_entry_safe(mid, tmp_mid, &server->pending_mid_q, qhead) { 550 list_for_each_entry(mid, &server->pending_mid_q, qhead) {
552 if (mid->mid != buf->Mid || 551 if (mid->mid == buf->Mid &&
553 mid->midState != MID_REQUEST_SUBMITTED || 552 mid->midState == MID_REQUEST_SUBMITTED &&
554 mid->command != buf->Command) 553 mid->command == buf->Command) {
555 continue; 554 spin_unlock(&GlobalMid_Lock);
556 555 return mid;
557 if (*length == 0 && check2ndT2(buf) > 0) {
558 /* We have a multipart transact2 resp */
559 *is_multi_rsp = true;
560 if (mid->resp_buf) {
561 /* merge response - fix up 1st*/
562 *length = coalesce_t2(buf, mid->resp_buf);
563 if (*length > 0) {
564 *length = 0;
565 mid->multiRsp = true;
566 break;
567 }
568 /* All parts received or packet is malformed. */
569 mid->multiEnd = true;
570 goto multi_t2_fnd;
571 }
572 if (!is_large_buf) {
573 /*FIXME: switch to already allocated largebuf?*/
574 cERROR(1, "1st trans2 resp needs bigbuf");
575 } else {
576 /* Have first buffer */
577 mid->resp_buf = buf;
578 mid->largeBuf = true;
579 *bigbuf = NULL;
580 }
581 break;
582 } 556 }
583 mid->resp_buf = buf; 557 }
584 mid->largeBuf = is_large_buf; 558 spin_unlock(&GlobalMid_Lock);
585multi_t2_fnd: 559 return NULL;
586 if (*length == 0) 560}
587 mid->midState = MID_RESPONSE_RECEIVED; 561
588 else 562static void
589 mid->midState = MID_RESPONSE_MALFORMED; 563dequeue_mid(struct mid_q_entry *mid, int malformed)
564{
590#ifdef CONFIG_CIFS_STATS2 565#ifdef CONFIG_CIFS_STATS2
591 mid->when_received = jiffies; 566 mid->when_received = jiffies;
592#endif 567#endif
593 list_del_init(&mid->qhead); 568 spin_lock(&GlobalMid_Lock);
594 ret = mid; 569 if (!malformed)
595 break; 570 mid->midState = MID_RESPONSE_RECEIVED;
596 } 571 else
572 mid->midState = MID_RESPONSE_MALFORMED;
573 list_del_init(&mid->qhead);
597 spin_unlock(&GlobalMid_Lock); 574 spin_unlock(&GlobalMid_Lock);
575}
598 576
599 return ret; 577static struct mid_q_entry *
578find_cifs_mid(struct TCP_Server_Info *server, struct smb_hdr *buf,
579 int *malformed, bool is_large_buf, bool *is_multi_rsp,
580 char **bigbuf)
581{
582 struct mid_q_entry *mid = NULL;
583
584 mid = find_mid(server, buf);
585 if (!mid)
586 return mid;
587
588 if (*malformed == 0 && check2ndT2(buf) > 0) {
589 /* We have a multipart transact2 resp */
590 *is_multi_rsp = true;
591 if (mid->resp_buf) {
592 /* merge response - fix up 1st*/
593 *malformed = coalesce_t2(buf, mid->resp_buf);
594 if (*malformed > 0) {
595 *malformed = 0;
596 mid->multiRsp = true;
597 return NULL;
598 }
599 /* All parts received or packet is malformed. */
600 mid->multiEnd = true;
601 goto multi_t2_fnd;
602 }
603 if (!is_large_buf) {
604 /*FIXME: switch to already allocated largebuf?*/
605 cERROR(1, "1st trans2 resp needs bigbuf");
606 } else {
607 /* Have first buffer */
608 mid->resp_buf = buf;
609 mid->largeBuf = true;
610 *bigbuf = NULL;
611 }
612 return mid;
613 }
614 mid->resp_buf = buf;
615 mid->largeBuf = is_large_buf;
616multi_t2_fnd:
617 dequeue_mid(mid, *malformed);
618 return mid;
600} 619}
601 620
602static void clean_demultiplex_info(struct TCP_Server_Info *server) 621static void clean_demultiplex_info(struct TCP_Server_Info *server)