Skip to content

Commit e0bba0b

Browse files
Ronnie SahlbergSteve French
authored andcommitted
cifs: add compound_send_recv()
Signed-off-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Steve French <[email protected]> Reviewed-by: Pavel Shilovsky <[email protected]>
1 parent 1f3a8f5 commit e0bba0b

File tree

2 files changed

+94
-66
lines changed

2 files changed

+94
-66
lines changed

fs/cifs/cifsproto.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ extern int cifs_call_async(struct TCP_Server_Info *server,
9494
extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
9595
struct smb_rqst *rqst, int *resp_buf_type,
9696
const int flags, struct kvec *resp_iov);
97+
extern int compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
98+
const int flags, const int num_rqst,
99+
struct smb_rqst *rqst, int *resp_buf_type,
100+
struct kvec *resp_iov);
97101
extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
98102
struct smb_hdr * /* input */ ,
99103
struct smb_hdr * /* out */ ,

fs/cifs/transport.c

Lines changed: 90 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -766,20 +766,21 @@ cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
766766
}
767767

768768
int
769-
cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
770-
struct smb_rqst *rqst, int *resp_buf_type, const int flags,
771-
struct kvec *resp_iov)
769+
compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
770+
const int flags, const int num_rqst, struct smb_rqst *rqst,
771+
int *resp_buf_type, struct kvec *resp_iov)
772772
{
773-
int rc = 0;
773+
int i, j, rc = 0;
774774
int timeout, optype;
775-
struct mid_q_entry *midQ;
775+
struct mid_q_entry *midQ[MAX_COMPOUND];
776776
unsigned int credits = 1;
777777
char *buf;
778778

779779
timeout = flags & CIFS_TIMEOUT_MASK;
780780
optype = flags & CIFS_OP_MASK;
781781

782-
*resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */
782+
for (i = 0; i < num_rqst; i++)
783+
resp_buf_type[i] = CIFS_NO_BUFFER; /* no response buf yet */
783784

784785
if ((ses == NULL) || (ses->server == NULL)) {
785786
cifs_dbg(VFS, "Null session\n");
@@ -806,93 +807,116 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
806807

807808
mutex_lock(&ses->server->srv_mutex);
808809

809-
midQ = ses->server->ops->setup_request(ses, rqst);
810-
if (IS_ERR(midQ)) {
811-
mutex_unlock(&ses->server->srv_mutex);
812-
/* Update # of requests on wire to server */
813-
add_credits(ses->server, 1, optype);
814-
return PTR_ERR(midQ);
810+
for (i = 0; i < num_rqst; i++) {
811+
midQ[i] = ses->server->ops->setup_request(ses, &rqst[i]);
812+
if (IS_ERR(midQ[i])) {
813+
for (j = 0; j < i; j++)
814+
cifs_delete_mid(midQ[j]);
815+
mutex_unlock(&ses->server->srv_mutex);
816+
/* Update # of requests on wire to server */
817+
add_credits(ses->server, 1, optype);
818+
return PTR_ERR(midQ[i]);
819+
}
820+
821+
midQ[i]->mid_state = MID_REQUEST_SUBMITTED;
815822
}
816823

817-
midQ->mid_state = MID_REQUEST_SUBMITTED;
818824
cifs_in_send_inc(ses->server);
819-
rc = smb_send_rqst(ses->server, 1, rqst, flags);
825+
rc = smb_send_rqst(ses->server, num_rqst, rqst, flags);
820826
cifs_in_send_dec(ses->server);
821-
cifs_save_when_sent(midQ);
827+
828+
for (i = 0; i < num_rqst; i++)
829+
cifs_save_when_sent(midQ[i]);
822830

823831
if (rc < 0)
824832
ses->server->sequence_number -= 2;
833+
825834
mutex_unlock(&ses->server->srv_mutex);
826835

827-
if (rc < 0)
828-
goto out;
836+
for (i = 0; i < num_rqst; i++) {
837+
if (rc < 0)
838+
goto out;
829839

830-
if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
831-
smb311_update_preauth_hash(ses, rqst->rq_iov,
832-
rqst->rq_nvec);
840+
if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
841+
smb311_update_preauth_hash(ses, rqst[i].rq_iov,
842+
rqst[i].rq_nvec);
833843

834-
if (timeout == CIFS_ASYNC_OP)
835-
goto out;
844+
if (timeout == CIFS_ASYNC_OP)
845+
goto out;
836846

837-
rc = wait_for_response(ses->server, midQ);
838-
if (rc != 0) {
839-
cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid);
840-
send_cancel(ses->server, rqst, midQ);
841-
spin_lock(&GlobalMid_Lock);
842-
if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
843-
midQ->mid_flags |= MID_WAIT_CANCELLED;
844-
midQ->callback = DeleteMidQEntry;
847+
rc = wait_for_response(ses->server, midQ[i]);
848+
if (rc != 0) {
849+
cifs_dbg(FYI, "Cancelling wait for mid %llu\n",
850+
midQ[i]->mid);
851+
send_cancel(ses->server, &rqst[i], midQ[i]);
852+
spin_lock(&GlobalMid_Lock);
853+
if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) {
854+
midQ[i]->mid_flags |= MID_WAIT_CANCELLED;
855+
midQ[i]->callback = DeleteMidQEntry;
856+
spin_unlock(&GlobalMid_Lock);
857+
add_credits(ses->server, 1, optype);
858+
return rc;
859+
}
845860
spin_unlock(&GlobalMid_Lock);
861+
}
862+
863+
rc = cifs_sync_mid_result(midQ[i], ses->server);
864+
if (rc != 0) {
846865
add_credits(ses->server, 1, optype);
847866
return rc;
848867
}
849-
spin_unlock(&GlobalMid_Lock);
850-
}
851-
852-
rc = cifs_sync_mid_result(midQ, ses->server);
853-
if (rc != 0) {
854-
add_credits(ses->server, 1, optype);
855-
return rc;
856-
}
857868

858-
if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
859-
rc = -EIO;
860-
cifs_dbg(FYI, "Bad MID state?\n");
861-
goto out;
862-
}
863-
864-
buf = (char *)midQ->resp_buf;
865-
resp_iov->iov_base = buf;
866-
resp_iov->iov_len = midQ->resp_buf_size +
867-
ses->server->vals->header_preamble_size;
868-
if (midQ->large_buf)
869-
*resp_buf_type = CIFS_LARGE_BUFFER;
870-
else
871-
*resp_buf_type = CIFS_SMALL_BUFFER;
869+
if (!midQ[i]->resp_buf ||
870+
midQ[i]->mid_state != MID_RESPONSE_RECEIVED) {
871+
rc = -EIO;
872+
cifs_dbg(FYI, "Bad MID state?\n");
873+
goto out;
874+
}
872875

873-
if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
874-
struct kvec iov = {
875-
.iov_base = resp_iov->iov_base,
876-
.iov_len = resp_iov->iov_len
877-
};
878-
smb311_update_preauth_hash(ses, &iov, 1);
879-
}
876+
buf = (char *)midQ[i]->resp_buf;
877+
resp_iov[i].iov_base = buf;
878+
resp_iov[i].iov_len = midQ[i]->resp_buf_size +
879+
ses->server->vals->header_preamble_size;
880+
881+
if (midQ[i]->large_buf)
882+
resp_buf_type[i] = CIFS_LARGE_BUFFER;
883+
else
884+
resp_buf_type[i] = CIFS_SMALL_BUFFER;
885+
886+
if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
887+
struct kvec iov = {
888+
.iov_base = resp_iov[i].iov_base,
889+
.iov_len = resp_iov[i].iov_len
890+
};
891+
smb311_update_preauth_hash(ses, &iov, 1);
892+
}
880893

881-
credits = ses->server->ops->get_credits(midQ);
894+
credits = ses->server->ops->get_credits(midQ[i]);
882895

883-
rc = ses->server->ops->check_receive(midQ, ses->server,
884-
flags & CIFS_LOG_ERROR);
896+
rc = ses->server->ops->check_receive(midQ[i], ses->server,
897+
flags & CIFS_LOG_ERROR);
885898

886-
/* mark it so buf will not be freed by cifs_delete_mid */
887-
if ((flags & CIFS_NO_RESP) == 0)
888-
midQ->resp_buf = NULL;
899+
/* mark it so buf will not be freed by cifs_delete_mid */
900+
if ((flags & CIFS_NO_RESP) == 0)
901+
midQ[i]->resp_buf = NULL;
902+
}
889903
out:
890-
cifs_delete_mid(midQ);
904+
for (i = 0; i < num_rqst; i++)
905+
cifs_delete_mid(midQ[i]);
891906
add_credits(ses->server, credits, optype);
892907

893908
return rc;
894909
}
895910

911+
int
912+
cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
913+
struct smb_rqst *rqst, int *resp_buf_type, const int flags,
914+
struct kvec *resp_iov)
915+
{
916+
return compound_send_recv(xid, ses, flags, 1, rqst, resp_buf_type,
917+
resp_iov);
918+
}
919+
896920
int
897921
SendReceive2(const unsigned int xid, struct cifs_ses *ses,
898922
struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,

0 commit comments

Comments
 (0)