aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPavel Shilovsky <piastry@etersoft.ru>2012-03-23 14:28:02 -0400
committerJeff Layton <jlayton@redhat.com>2012-03-23 14:28:02 -0400
commit792af7b05b8a78def080ec757a4d4420b9fd0cc2 (patch)
tree6f6d556f155194295375f3d4ad6cbfabbd7aeeeb /fs
parent934e18b5cb4531cc6e81865bf54115cfd21d1ac6 (diff)
CIFS: Separate protocol-specific code from transport routines
that lets us use this functions for SMB2. Signed-off-by: Pavel Shilovsky <piastry@etersoft.ru>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifs_debug.h2
-rw-r--r--fs/cifs/cifsglob.h6
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c21
-rw-r--r--fs/cifs/misc.c5
-rw-r--r--fs/cifs/transport.c171
6 files changed, 119 insertions, 88 deletions
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index 8942b28cf807..0a234c1db947 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -32,7 +32,7 @@ void cifs_dump_mids(struct TCP_Server_Info *);
32#define DBG2 0 32#define DBG2 0
33#endif 33#endif
34extern int traceSMB; /* flag which enables the function below */ 34extern int traceSMB; /* flag which enables the function below */
35void dump_smb(struct smb_hdr *, int); 35void dump_smb(void *, int);
36#define CIFS_INFO 0x01 36#define CIFS_INFO 0x01
37#define CIFS_RC 0x02 37#define CIFS_RC 0x02
38#define CIFS_TIMER 0x04 38#define CIFS_TIMER 0x04
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 339ebe3ebc0d..c3c7d7c46220 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -230,6 +230,12 @@ struct cifs_mnt_data {
230 int flags; 230 int flags;
231}; 231};
232 232
233static inline unsigned int
234get_rfc1002_length(void *buf)
235{
236 return be32_to_cpu(*((__be32 *)buf));
237}
238
233struct TCP_Server_Info { 239struct TCP_Server_Info {
234 struct list_head tcp_ses_list; 240 struct list_head tcp_ses_list;
235 struct list_head smb_ses_list; 241 struct list_head smb_ses_list;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 503e73d8bdb7..5f2f266c42a4 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -77,7 +77,7 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
77 struct smb_hdr * /* out */ , 77 struct smb_hdr * /* out */ ,
78 int * /* bytes returned */ , const int long_op); 78 int * /* bytes returned */ , const int long_op);
79extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, 79extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
80 struct smb_hdr *in_buf, int flags); 80 char *in_buf, int flags);
81extern int cifs_check_receive(struct mid_q_entry *mid, 81extern int cifs_check_receive(struct mid_q_entry *mid,
82 struct TCP_Server_Info *server, bool log_error); 82 struct TCP_Server_Info *server, bool log_error);
83extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *, 83extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 70aac35c398f..a7ed01cd0242 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -696,7 +696,7 @@ CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
696 if (rc) 696 if (rc)
697 return rc; 697 return rc;
698 698
699 rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0); 699 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
700 if (rc) 700 if (rc)
701 cFYI(1, "Tree disconnect failed %d", rc); 701 cFYI(1, "Tree disconnect failed %d", rc);
702 702
@@ -792,7 +792,7 @@ CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
792 pSMB->hdr.Uid = ses->Suid; 792 pSMB->hdr.Uid = ses->Suid;
793 793
794 pSMB->AndXCommand = 0xFF; 794 pSMB->AndXCommand = 0xFF;
795 rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0); 795 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
796session_already_dead: 796session_already_dead:
797 mutex_unlock(&ses->session_mutex); 797 mutex_unlock(&ses->session_mutex);
798 798
@@ -2420,8 +2420,7 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
2420 (struct smb_hdr *) pSMB, &bytes_returned); 2420 (struct smb_hdr *) pSMB, &bytes_returned);
2421 cifs_small_buf_release(pSMB); 2421 cifs_small_buf_release(pSMB);
2422 } else { 2422 } else {
2423 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB, 2423 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, timeout);
2424 timeout);
2425 /* SMB buffer freed by function above */ 2424 /* SMB buffer freed by function above */
2426 } 2425 }
2427 cifs_stats_inc(&tcon->num_locks); 2426 cifs_stats_inc(&tcon->num_locks);
@@ -2588,7 +2587,7 @@ CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2588 pSMB->FileID = (__u16) smb_file_id; 2587 pSMB->FileID = (__u16) smb_file_id;
2589 pSMB->LastWriteTime = 0xFFFFFFFF; 2588 pSMB->LastWriteTime = 0xFFFFFFFF;
2590 pSMB->ByteCount = 0; 2589 pSMB->ByteCount = 0;
2591 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 2590 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2592 cifs_stats_inc(&tcon->num_closes); 2591 cifs_stats_inc(&tcon->num_closes);
2593 if (rc) { 2592 if (rc) {
2594 if (rc != -EINTR) { 2593 if (rc != -EINTR) {
@@ -2617,7 +2616,7 @@ CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
2617 2616
2618 pSMB->FileID = (__u16) smb_file_id; 2617 pSMB->FileID = (__u16) smb_file_id;
2619 pSMB->ByteCount = 0; 2618 pSMB->ByteCount = 0;
2620 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 2619 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
2621 cifs_stats_inc(&tcon->num_flushes); 2620 cifs_stats_inc(&tcon->num_flushes);
2622 if (rc) 2621 if (rc)
2623 cERROR(1, "Send error in Flush = %d", rc); 2622 cERROR(1, "Send error in Flush = %d", rc);
@@ -4625,7 +4624,7 @@ CIFSFindClose(const int xid, struct cifs_tcon *tcon,
4625 4624
4626 pSMB->FileID = searchHandle; 4625 pSMB->FileID = searchHandle;
4627 pSMB->ByteCount = 0; 4626 pSMB->ByteCount = 0;
4628 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 4627 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
4629 if (rc) 4628 if (rc)
4630 cERROR(1, "Send error in FindClose = %d", rc); 4629 cERROR(1, "Send error in FindClose = %d", rc);
4631 4630
@@ -5646,7 +5645,7 @@ CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
5646 pSMB->Reserved4 = 0; 5645 pSMB->Reserved4 = 0;
5647 inc_rfc1001_len(pSMB, byte_count); 5646 inc_rfc1001_len(pSMB, byte_count);
5648 pSMB->ByteCount = cpu_to_le16(byte_count); 5647 pSMB->ByteCount = cpu_to_le16(byte_count);
5649 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5648 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5650 if (rc) { 5649 if (rc) {
5651 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc); 5650 cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
5652 } 5651 }
@@ -5715,7 +5714,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5715 inc_rfc1001_len(pSMB, byte_count); 5714 inc_rfc1001_len(pSMB, byte_count);
5716 pSMB->ByteCount = cpu_to_le16(byte_count); 5715 pSMB->ByteCount = cpu_to_le16(byte_count);
5717 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5716 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
5718 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5717 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5719 if (rc) 5718 if (rc)
5720 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc); 5719 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
5721 5720
@@ -5774,7 +5773,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5774 inc_rfc1001_len(pSMB, byte_count); 5773 inc_rfc1001_len(pSMB, byte_count);
5775 pSMB->ByteCount = cpu_to_le16(byte_count); 5774 pSMB->ByteCount = cpu_to_le16(byte_count);
5776 *data_offset = delete_file ? 1 : 0; 5775 *data_offset = delete_file ? 1 : 0;
5777 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5776 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
5778 if (rc) 5777 if (rc)
5779 cFYI(1, "Send error in SetFileDisposition = %d", rc); 5778 cFYI(1, "Send error in SetFileDisposition = %d", rc);
5780 5779
@@ -6006,7 +6005,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
6006 6005
6007 cifs_fill_unix_set_info(data_offset, args); 6006 cifs_fill_unix_set_info(data_offset, args);
6008 6007
6009 rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 6008 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
6010 if (rc) 6009 if (rc)
6011 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc); 6010 cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
6012 6011
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index c273c12de98e..e88601fc6f22 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -604,16 +604,15 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
604} 604}
605 605
606void 606void
607dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) 607dump_smb(void *buf, int smb_buf_length)
608{ 608{
609 int i, j; 609 int i, j;
610 char debug_line[17]; 610 char debug_line[17];
611 unsigned char *buffer; 611 unsigned char *buffer = buf;
612 612
613 if (traceSMB == 0) 613 if (traceSMB == 0)
614 return; 614 return;
615 615
616 buffer = (unsigned char *) smb_buf;
617 for (i = 0, j = 0; i < smb_buf_length; i++, j++) { 616 for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
618 if (i % 8 == 0) { 617 if (i % 8 == 0) {
619 /* have reached the beginning of line */ 618 /* have reached the beginning of line */
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 310918b6fcb4..3bb447d07a1d 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -126,11 +126,11 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
126 int rc = 0; 126 int rc = 0;
127 int i = 0; 127 int i = 0;
128 struct msghdr smb_msg; 128 struct msghdr smb_msg;
129 struct smb_hdr *smb_buffer = iov[0].iov_base; 129 __be32 *buf_len = (__be32 *)(iov[0].iov_base);
130 unsigned int len = iov[0].iov_len; 130 unsigned int len = iov[0].iov_len;
131 unsigned int total_len; 131 unsigned int total_len;
132 int first_vec = 0; 132 int first_vec = 0;
133 unsigned int smb_buf_length = be32_to_cpu(smb_buffer->smb_buf_length); 133 unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
134 struct socket *ssocket = server->ssocket; 134 struct socket *ssocket = server->ssocket;
135 135
136 if (ssocket == NULL) 136 if (ssocket == NULL)
@@ -150,7 +150,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
150 total_len += iov[i].iov_len; 150 total_len += iov[i].iov_len;
151 151
152 cFYI(1, "Sending smb: total_len %d", total_len); 152 cFYI(1, "Sending smb: total_len %d", total_len);
153 dump_smb(smb_buffer, len); 153 dump_smb(iov[0].iov_base, len);
154 154
155 i = 0; 155 i = 0;
156 while (total_len) { 156 while (total_len) {
@@ -158,24 +158,24 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
158 n_vec - first_vec, total_len); 158 n_vec - first_vec, total_len);
159 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 159 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
160 i++; 160 i++;
161 /* if blocking send we try 3 times, since each can block 161 /*
162 for 5 seconds. For nonblocking we have to try more 162 * If blocking send we try 3 times, since each can block
163 but wait increasing amounts of time allowing time for 163 * for 5 seconds. For nonblocking we have to try more
164 socket to clear. The overall time we wait in either 164 * but wait increasing amounts of time allowing time for
165 case to send on the socket is about 15 seconds. 165 * socket to clear. The overall time we wait in either
166 Similarly we wait for 15 seconds for 166 * case to send on the socket is about 15 seconds.
167 a response from the server in SendReceive[2] 167 * Similarly we wait for 15 seconds for a response from
168 for the server to send a response back for 168 * the server in SendReceive[2] for the server to send
169 most types of requests (except SMB Write 169 * a response back for most types of requests (except
170 past end of file which can be slow, and 170 * SMB Write past end of file which can be slow, and
171 blocking lock operations). NFS waits slightly longer 171 * blocking lock operations). NFS waits slightly longer
172 than CIFS, but this can make it take longer for 172 * than CIFS, but this can make it take longer for
173 nonresponsive servers to be detected and 15 seconds 173 * nonresponsive servers to be detected and 15 seconds
174 is more than enough time for modern networks to 174 * is more than enough time for modern networks to
175 send a packet. In most cases if we fail to send 175 * send a packet. In most cases if we fail to send
176 after the retries we will kill the socket and 176 * after the retries we will kill the socket and
177 reconnect which may clear the network problem. 177 * reconnect which may clear the network problem.
178 */ 178 */
179 if ((i >= 14) || (!server->noblocksnd && (i > 2))) { 179 if ((i >= 14) || (!server->noblocksnd && (i > 2))) {
180 cERROR(1, "sends on sock %p stuck for 15 seconds", 180 cERROR(1, "sends on sock %p stuck for 15 seconds",
181 ssocket); 181 ssocket);
@@ -235,9 +235,8 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
235 else 235 else
236 rc = 0; 236 rc = 0;
237 237
238 /* Don't want to modify the buffer as a 238 /* Don't want to modify the buffer as a side effect of this call. */
239 side effect of this call. */ 239 *buf_len = cpu_to_be32(smb_buf_length);
240 smb_buffer->smb_buf_length = cpu_to_be32(smb_buf_length);
241 240
242 return rc; 241 return rc;
243} 242}
@@ -349,6 +348,33 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
349 return 0; 348 return 0;
350} 349}
351 350
351static int
352cifs_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov,
353 unsigned int nvec, struct mid_q_entry **ret_mid)
354{
355 int rc;
356 struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
357 struct mid_q_entry *mid;
358
359 /* enable signing if server requires it */
360 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
361 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
362
363 mid = AllocMidQEntry(hdr, server);
364 if (mid == NULL)
365 return -ENOMEM;
366
367 /* put it on the pending_mid_q */
368 spin_lock(&GlobalMid_Lock);
369 list_add_tail(&mid->qhead, &server->pending_mid_q);
370 spin_unlock(&GlobalMid_Lock);
371
372 rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
373 if (rc)
374 delete_mid(mid);
375 *ret_mid = mid;
376 return rc;
377}
352 378
353/* 379/*
354 * Send a SMB request and set the callback function in the mid to handle 380 * Send a SMB request and set the callback function in the mid to handle
@@ -361,34 +387,18 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
361{ 387{
362 int rc; 388 int rc;
363 struct mid_q_entry *mid; 389 struct mid_q_entry *mid;
364 struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
365 390
366 rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0); 391 rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0);
367 if (rc) 392 if (rc)
368 return rc; 393 return rc;
369 394
370 /* enable signing if server requires it */
371 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
372 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
373
374 mutex_lock(&server->srv_mutex); 395 mutex_lock(&server->srv_mutex);
375 mid = AllocMidQEntry(hdr, server); 396 rc = cifs_setup_async_request(server, iov, nvec, &mid);
376 if (mid == NULL) { 397 if (rc) {
377 mutex_unlock(&server->srv_mutex); 398 mutex_unlock(&server->srv_mutex);
378 cifs_add_credits(server, 1); 399 cifs_add_credits(server, 1);
379 wake_up(&server->request_q); 400 wake_up(&server->request_q);
380 return -ENOMEM; 401 return rc;
381 }
382
383 /* put it on the pending_mid_q */
384 spin_lock(&GlobalMid_Lock);
385 list_add_tail(&mid->qhead, &server->pending_mid_q);
386 spin_unlock(&GlobalMid_Lock);
387
388 rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
389 if (rc) {
390 mutex_unlock(&server->srv_mutex);
391 goto out_err;
392 } 402 }
393 403
394 mid->receive = receive; 404 mid->receive = receive;
@@ -424,14 +434,14 @@ out_err:
424 */ 434 */
425int 435int
426SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, 436SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
427 struct smb_hdr *in_buf, int flags) 437 char *in_buf, int flags)
428{ 438{
429 int rc; 439 int rc;
430 struct kvec iov[1]; 440 struct kvec iov[1];
431 int resp_buf_type; 441 int resp_buf_type;
432 442
433 iov[0].iov_base = (char *)in_buf; 443 iov[0].iov_base = in_buf;
434 iov[0].iov_len = be32_to_cpu(in_buf->smb_buf_length) + 4; 444 iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
435 flags |= CIFS_NO_RESP; 445 flags |= CIFS_NO_RESP;
436 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags); 446 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
437 cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc); 447 cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
@@ -514,7 +524,7 @@ int
514cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, 524cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
515 bool log_error) 525 bool log_error)
516{ 526{
517 unsigned int len = be32_to_cpu(mid->resp_buf->smb_buf_length) + 4; 527 unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
518 528
519 dump_smb(mid->resp_buf, min_t(u32, 92, len)); 529 dump_smb(mid->resp_buf, min_t(u32, 92, len));
520 530
@@ -534,6 +544,24 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
534 return map_smb_to_linux_error(mid->resp_buf, log_error); 544 return map_smb_to_linux_error(mid->resp_buf, log_error);
535} 545}
536 546
547static int
548cifs_setup_request(struct cifs_ses *ses, struct kvec *iov,
549 unsigned int nvec, struct mid_q_entry **ret_mid)
550{
551 int rc;
552 struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
553 struct mid_q_entry *mid;
554
555 rc = allocate_mid(ses, hdr, &mid);
556 if (rc)
557 return rc;
558 rc = cifs_sign_smb2(iov, nvec, ses->server, &mid->sequence_number);
559 if (rc)
560 delete_mid(mid);
561 *ret_mid = mid;
562 return rc;
563}
564
537int 565int
538SendReceive2(const unsigned int xid, struct cifs_ses *ses, 566SendReceive2(const unsigned int xid, struct cifs_ses *ses,
539 struct kvec *iov, int n_vec, int *pRespBufType /* ret */, 567 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
@@ -542,53 +570,51 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
542 int rc = 0; 570 int rc = 0;
543 int long_op; 571 int long_op;
544 struct mid_q_entry *midQ; 572 struct mid_q_entry *midQ;
545 struct smb_hdr *in_buf = iov[0].iov_base; 573 char *buf = iov[0].iov_base;
546 574
547 long_op = flags & CIFS_TIMEOUT_MASK; 575 long_op = flags & CIFS_TIMEOUT_MASK;
548 576
549 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 577 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
550 578
551 if ((ses == NULL) || (ses->server == NULL)) { 579 if ((ses == NULL) || (ses->server == NULL)) {
552 cifs_small_buf_release(in_buf); 580 cifs_small_buf_release(buf);
553 cERROR(1, "Null session"); 581 cERROR(1, "Null session");
554 return -EIO; 582 return -EIO;
555 } 583 }
556 584
557 if (ses->server->tcpStatus == CifsExiting) { 585 if (ses->server->tcpStatus == CifsExiting) {
558 cifs_small_buf_release(in_buf); 586 cifs_small_buf_release(buf);
559 return -ENOENT; 587 return -ENOENT;
560 } 588 }
561 589
562 /* Ensure that we do not send more than 50 overlapping requests 590 /*
563 to the same server. We may make this configurable later or 591 * Ensure that we do not send more than 50 overlapping requests
564 use ses->maxReq */ 592 * to the same server. We may make this configurable later or
593 * use ses->maxReq.
594 */
565 595
566 rc = wait_for_free_request(ses->server, long_op); 596 rc = wait_for_free_request(ses->server, long_op);
567 if (rc) { 597 if (rc) {
568 cifs_small_buf_release(in_buf); 598 cifs_small_buf_release(buf);
569 return rc; 599 return rc;
570 } 600 }
571 601
572 /* make sure that we sign in the same order that we send on this socket 602 /*
573 and avoid races inside tcp sendmsg code that could cause corruption 603 * Make sure that we sign in the same order that we send on this socket
574 of smb data */ 604 * and avoid races inside tcp sendmsg code that could cause corruption
605 * of smb data.
606 */
575 607
576 mutex_lock(&ses->server->srv_mutex); 608 mutex_lock(&ses->server->srv_mutex);
577 609
578 rc = allocate_mid(ses, in_buf, &midQ); 610 rc = cifs_setup_request(ses, iov, n_vec, &midQ);
579 if (rc) { 611 if (rc) {
580 mutex_unlock(&ses->server->srv_mutex); 612 mutex_unlock(&ses->server->srv_mutex);
581 cifs_small_buf_release(in_buf); 613 cifs_small_buf_release(buf);
582 /* Update # of requests on wire to server */ 614 /* Update # of requests on wire to server */
583 cifs_add_credits(ses->server, 1); 615 cifs_add_credits(ses->server, 1);
584 return rc; 616 return rc;
585 } 617 }
586 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
587 if (rc) {
588 mutex_unlock(&ses->server->srv_mutex);
589 cifs_small_buf_release(in_buf);
590 goto out;
591 }
592 618
593 midQ->midState = MID_REQUEST_SUBMITTED; 619 midQ->midState = MID_REQUEST_SUBMITTED;
594 cifs_in_send_inc(ses->server); 620 cifs_in_send_inc(ses->server);
@@ -599,30 +625,30 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
599 mutex_unlock(&ses->server->srv_mutex); 625 mutex_unlock(&ses->server->srv_mutex);
600 626
601 if (rc < 0) { 627 if (rc < 0) {
602 cifs_small_buf_release(in_buf); 628 cifs_small_buf_release(buf);
603 goto out; 629 goto out;
604 } 630 }
605 631
606 if (long_op == CIFS_ASYNC_OP) { 632 if (long_op == CIFS_ASYNC_OP) {
607 cifs_small_buf_release(in_buf); 633 cifs_small_buf_release(buf);
608 goto out; 634 goto out;
609 } 635 }
610 636
611 rc = wait_for_response(ses->server, midQ); 637 rc = wait_for_response(ses->server, midQ);
612 if (rc != 0) { 638 if (rc != 0) {
613 send_nt_cancel(ses->server, in_buf, midQ); 639 send_nt_cancel(ses->server, (struct smb_hdr *)buf, midQ);
614 spin_lock(&GlobalMid_Lock); 640 spin_lock(&GlobalMid_Lock);
615 if (midQ->midState == MID_REQUEST_SUBMITTED) { 641 if (midQ->midState == MID_REQUEST_SUBMITTED) {
616 midQ->callback = DeleteMidQEntry; 642 midQ->callback = DeleteMidQEntry;
617 spin_unlock(&GlobalMid_Lock); 643 spin_unlock(&GlobalMid_Lock);
618 cifs_small_buf_release(in_buf); 644 cifs_small_buf_release(buf);
619 cifs_add_credits(ses->server, 1); 645 cifs_add_credits(ses->server, 1);
620 return rc; 646 return rc;
621 } 647 }
622 spin_unlock(&GlobalMid_Lock); 648 spin_unlock(&GlobalMid_Lock);
623 } 649 }
624 650
625 cifs_small_buf_release(in_buf); 651 cifs_small_buf_release(buf);
626 652
627 rc = cifs_sync_mid_result(midQ, ses->server); 653 rc = cifs_sync_mid_result(midQ, ses->server);
628 if (rc != 0) { 654 if (rc != 0) {
@@ -636,8 +662,9 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
636 goto out; 662 goto out;
637 } 663 }
638 664
639 iov[0].iov_base = (char *)midQ->resp_buf; 665 buf = (char *)midQ->resp_buf;
640 iov[0].iov_len = be32_to_cpu(midQ->resp_buf->smb_buf_length) + 4; 666 iov[0].iov_base = buf;
667 iov[0].iov_len = get_rfc1002_length(buf) + 4;
641 if (midQ->largeBuf) 668 if (midQ->largeBuf)
642 *pRespBufType = CIFS_LARGE_BUFFER; 669 *pRespBufType = CIFS_LARGE_BUFFER;
643 else 670 else