aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/smb2transport.c')
-rw-r--r--fs/cifs/smb2transport.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
index 7b351c65ee46..d1181572758b 100644
--- a/fs/cifs/smb2transport.c
+++ b/fs/cifs/smb2transport.c
@@ -576,6 +576,7 @@ smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
576 struct TCP_Server_Info *server) 576 struct TCP_Server_Info *server)
577{ 577{
578 struct mid_q_entry *temp; 578 struct mid_q_entry *temp;
579 unsigned int credits = le16_to_cpu(shdr->CreditCharge);
579 580
580 if (server == NULL) { 581 if (server == NULL) {
581 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n"); 582 cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc\n");
@@ -586,6 +587,7 @@ smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
586 memset(temp, 0, sizeof(struct mid_q_entry)); 587 memset(temp, 0, sizeof(struct mid_q_entry));
587 kref_init(&temp->refcount); 588 kref_init(&temp->refcount);
588 temp->mid = le64_to_cpu(shdr->MessageId); 589 temp->mid = le64_to_cpu(shdr->MessageId);
590 temp->credits = credits > 0 ? credits : 1;
589 temp->pid = current->pid; 591 temp->pid = current->pid;
590 temp->command = shdr->Command; /* Always LE */ 592 temp->command = shdr->Command; /* Always LE */
591 temp->when_alloc = jiffies; 593 temp->when_alloc = jiffies;
@@ -600,6 +602,8 @@ smb2_mid_entry_alloc(const struct smb2_sync_hdr *shdr,
600 602
601 atomic_inc(&midCount); 603 atomic_inc(&midCount);
602 temp->mid_state = MID_REQUEST_ALLOCATED; 604 temp->mid_state = MID_REQUEST_ALLOCATED;
605 trace_smb3_cmd_enter(shdr->TreeId, shdr->SessionId,
606 le16_to_cpu(shdr->Command), temp->mid);
603 return temp; 607 return temp;
604} 608}
605 609
@@ -615,6 +619,10 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
615 return -EAGAIN; 619 return -EAGAIN;
616 } 620 }
617 621
622 if (ses->server->tcpStatus == CifsNeedNegotiate &&
623 shdr->Command != SMB2_NEGOTIATE)
624 return -EAGAIN;
625
618 if (ses->status == CifsNew) { 626 if (ses->status == CifsNew) {
619 if ((shdr->Command != SMB2_SESSION_SETUP) && 627 if ((shdr->Command != SMB2_SESSION_SETUP) &&
620 (shdr->Command != SMB2_NEGOTIATE)) 628 (shdr->Command != SMB2_NEGOTIATE))
@@ -634,6 +642,7 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_sync_hdr *shdr,
634 spin_lock(&GlobalMid_Lock); 642 spin_lock(&GlobalMid_Lock);
635 list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q); 643 list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q);
636 spin_unlock(&GlobalMid_Lock); 644 spin_unlock(&GlobalMid_Lock);
645
637 return 0; 646 return 0;
638} 647}
639 648
@@ -674,13 +683,18 @@ smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
674 smb2_seq_num_into_buf(ses->server, shdr); 683 smb2_seq_num_into_buf(ses->server, shdr);
675 684
676 rc = smb2_get_mid_entry(ses, shdr, &mid); 685 rc = smb2_get_mid_entry(ses, shdr, &mid);
677 if (rc) 686 if (rc) {
687 revert_current_mid_from_hdr(ses->server, shdr);
678 return ERR_PTR(rc); 688 return ERR_PTR(rc);
689 }
690
679 rc = smb2_sign_rqst(rqst, ses->server); 691 rc = smb2_sign_rqst(rqst, ses->server);
680 if (rc) { 692 if (rc) {
693 revert_current_mid_from_hdr(ses->server, shdr);
681 cifs_delete_mid(mid); 694 cifs_delete_mid(mid);
682 return ERR_PTR(rc); 695 return ERR_PTR(rc);
683 } 696 }
697
684 return mid; 698 return mid;
685} 699}
686 700
@@ -692,14 +706,21 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
692 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base; 706 (struct smb2_sync_hdr *)rqst->rq_iov[0].iov_base;
693 struct mid_q_entry *mid; 707 struct mid_q_entry *mid;
694 708
709 if (server->tcpStatus == CifsNeedNegotiate &&
710 shdr->Command != SMB2_NEGOTIATE)
711 return ERR_PTR(-EAGAIN);
712
695 smb2_seq_num_into_buf(server, shdr); 713 smb2_seq_num_into_buf(server, shdr);
696 714
697 mid = smb2_mid_entry_alloc(shdr, server); 715 mid = smb2_mid_entry_alloc(shdr, server);
698 if (mid == NULL) 716 if (mid == NULL) {
717 revert_current_mid_from_hdr(server, shdr);
699 return ERR_PTR(-ENOMEM); 718 return ERR_PTR(-ENOMEM);
719 }
700 720
701 rc = smb2_sign_rqst(rqst, server); 721 rc = smb2_sign_rqst(rqst, server);
702 if (rc) { 722 if (rc) {
723 revert_current_mid_from_hdr(server, shdr);
703 DeleteMidQEntry(mid); 724 DeleteMidQEntry(mid);
704 return ERR_PTR(rc); 725 return ERR_PTR(rc);
705 } 726 }