diff options
Diffstat (limited to 'fs/cifs/smb2transport.c')
| -rw-r--r-- | fs/cifs/smb2transport.c | 25 |
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 | } |
