4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * Jeremy Allison (jra@samba.org) 2006.
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <linux/list.h>
25 #include <linux/gfp.h>
26 #include <linux/wait.h>
27 #include <linux/net.h>
28 #include <linux/delay.h>
29 #include <asm/uaccess.h>
30 #include <asm/processor.h>
31 #include <linux/mempool.h>
34 #include "cifsproto.h"
35 #include "cifs_debug.h"
37 extern mempool_t *cifs_mid_poolp;
39 static struct mid_q_entry *
40 AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
42 struct mid_q_entry *temp;
45 cERROR(1, "Null TCP session in AllocMidQEntry");
49 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
53 memset(temp, 0, sizeof(struct mid_q_entry));
54 temp->mid = smb_buffer->Mid; /* always LE */
55 temp->pid = current->pid;
56 temp->command = smb_buffer->Command;
57 cFYI(1, "For smb_command %d", temp->command);
58 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
59 /* when mid allocated can be before when sent */
60 temp->when_alloc = jiffies;
64 atomic_inc(&midCount);
65 temp->midState = MID_REQUEST_ALLOCATED;
70 DeleteMidQEntry(struct mid_q_entry *midEntry)
72 #ifdef CONFIG_CIFS_STATS2
75 midEntry->midState = MID_FREE;
76 atomic_dec(&midCount);
77 if (midEntry->largeBuf)
78 cifs_buf_release(midEntry->resp_buf);
80 cifs_small_buf_release(midEntry->resp_buf);
81 #ifdef CONFIG_CIFS_STATS2
83 /* commands taking longer than one second are indications that
84 something is wrong, unless it is quite a slow link or server */
85 if ((now - midEntry->when_alloc) > HZ) {
86 if ((cifsFYI & CIFS_TIMER) &&
87 (midEntry->command != SMB_COM_LOCKING_ANDX)) {
88 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
89 midEntry->command, midEntry->mid);
90 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
91 now - midEntry->when_alloc,
92 now - midEntry->when_sent,
93 now - midEntry->when_received);
97 mempool_free(midEntry, cifs_mid_poolp);
101 delete_mid(struct mid_q_entry *mid)
103 spin_lock(&GlobalMid_Lock);
104 list_del(&mid->qhead);
105 spin_unlock(&GlobalMid_Lock);
107 DeleteMidQEntry(mid);
111 smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
115 struct msghdr smb_msg;
116 struct smb_hdr *smb_buffer = iov[0].iov_base;
117 unsigned int len = iov[0].iov_len;
118 unsigned int total_len;
120 unsigned int smb_buf_length = smb_buffer->smb_buf_length;
121 struct socket *ssocket = server->ssocket;
124 return -ENOTSOCK; /* BB eventually add reconnect code here */
126 smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
127 smb_msg.msg_namelen = sizeof(struct sockaddr);
128 smb_msg.msg_control = NULL;
129 smb_msg.msg_controllen = 0;
130 if (server->noblocksnd)
131 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
133 smb_msg.msg_flags = MSG_NOSIGNAL;
135 /* smb header is converted in header_assemble. bcc and rest of SMB word
136 area, and byte area if necessary, is converted to littleendian in
137 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
138 Flags2 is converted in SendReceive */
142 for (i = 0; i < n_vec; i++)
143 total_len += iov[i].iov_len;
145 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
146 cFYI(1, "Sending smb: total_len %d", total_len);
147 dump_smb(smb_buffer, len);
151 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
152 n_vec - first_vec, total_len);
153 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
155 /* if blocking send we try 3 times, since each can block
156 for 5 seconds. For nonblocking we have to try more
157 but wait increasing amounts of time allowing time for
158 socket to clear. The overall time we wait in either
159 case to send on the socket is about 15 seconds.
160 Similarly we wait for 15 seconds for
161 a response from the server in SendReceive[2]
162 for the server to send a response back for
163 most types of requests (except SMB Write
164 past end of file which can be slow, and
165 blocking lock operations). NFS waits slightly longer
166 than CIFS, but this can make it take longer for
167 nonresponsive servers to be detected and 15 seconds
168 is more than enough time for modern networks to
169 send a packet. In most cases if we fail to send
170 after the retries we will kill the socket and
171 reconnect which may clear the network problem.
173 if ((i >= 14) || (!server->noblocksnd && (i > 2))) {
174 cERROR(1, "sends on sock %p stuck for 15 seconds",
185 if (rc == total_len) {
188 } else if (rc > total_len) {
189 cERROR(1, "sent %d requested %d", rc, total_len);
193 /* should never happen, letting socket clear before
194 retrying is our only obvious option here */
195 cERROR(1, "tcp sent no data");
200 /* the line below resets i */
201 for (i = first_vec; i < n_vec; i++) {
202 if (iov[i].iov_len) {
203 if (rc > iov[i].iov_len) {
204 rc -= iov[i].iov_len;
207 iov[i].iov_base += rc;
208 iov[i].iov_len -= rc;
214 i = 0; /* in case we get ENOSPC on the next send */
217 if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
218 cFYI(1, "partial send (%d remaining), terminating session",
220 /* If we have only sent part of an SMB then the next SMB
221 could be taken as the remainder of this one. We need
222 to kill the socket so the server throws away the partial
224 server->tcpStatus = CifsNeedReconnect;
228 cERROR(1, "Error %d sending data on socket to server", rc);
232 /* Don't want to modify the buffer as a
233 side effect of this call. */
234 smb_buffer->smb_buf_length = smb_buf_length;
240 smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
241 unsigned int smb_buf_length)
245 iov.iov_base = smb_buffer;
246 iov.iov_len = smb_buf_length + 4;
248 return smb_sendv(server, &iov, 1);
251 static int wait_for_free_request(struct TCP_Server_Info *server,
254 if (long_op == CIFS_ASYNC_OP) {
255 /* oplock breaks must not be held up */
256 atomic_inc(&server->inFlight);
260 spin_lock(&GlobalMid_Lock);
262 if (atomic_read(&server->inFlight) >= cifs_max_pending) {
263 spin_unlock(&GlobalMid_Lock);
264 #ifdef CONFIG_CIFS_STATS2
265 atomic_inc(&server->num_waiters);
267 wait_event(server->request_q,
268 atomic_read(&server->inFlight)
270 #ifdef CONFIG_CIFS_STATS2
271 atomic_dec(&server->num_waiters);
273 spin_lock(&GlobalMid_Lock);
275 if (server->tcpStatus == CifsExiting) {
276 spin_unlock(&GlobalMid_Lock);
280 /* can not count locking commands against total
281 as they are allowed to block on server */
283 /* update # of requests on the wire to server */
284 if (long_op != CIFS_BLOCKING_OP)
285 atomic_inc(&server->inFlight);
286 spin_unlock(&GlobalMid_Lock);
293 static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
294 struct mid_q_entry **ppmidQ)
296 if (ses->server->tcpStatus == CifsExiting) {
300 if (ses->server->tcpStatus == CifsNeedReconnect) {
301 cFYI(1, "tcp session dead - return to caller to retry");
305 if (ses->status != CifsGood) {
306 /* check if SMB session is bad because we are setting it up */
307 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
308 (in_buf->Command != SMB_COM_NEGOTIATE))
310 /* else ok - we are setting up session */
312 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
315 spin_lock(&GlobalMid_Lock);
316 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
317 spin_unlock(&GlobalMid_Lock);
321 static int wait_for_response(struct cifsSesInfo *ses,
322 struct mid_q_entry *midQ,
323 unsigned long timeout,
324 unsigned long time_to_wait)
326 unsigned long curr_timeout;
329 curr_timeout = timeout + jiffies;
330 wait_event_timeout(ses->server->response_q,
331 midQ->midState != MID_REQUEST_SUBMITTED, timeout);
333 if (time_after(jiffies, curr_timeout) &&
334 (midQ->midState == MID_REQUEST_SUBMITTED) &&
335 ((ses->server->tcpStatus == CifsGood) ||
336 (ses->server->tcpStatus == CifsNew))) {
340 /* We timed out. Is the server still
342 spin_lock(&GlobalMid_Lock);
343 lrt = ses->server->lstrp;
344 spin_unlock(&GlobalMid_Lock);
346 /* Calculate time_to_wait past last receive time.
347 Although we prefer not to time out if the
348 server is still responding - we will time
349 out if the server takes more than 15 (or 45
350 or 180) seconds to respond to this request
351 and has not responded to any request from
352 other threads on the client within 10 seconds */
354 if (time_after(jiffies, lrt)) {
355 /* No replies for time_to_wait. */
356 cERROR(1, "server not responding");
368 * Send an SMB Request. No response info (other than return code)
369 * needs to be parsed.
371 * flags indicate the type of request buffer and how long to wait
372 * and whether to log NT STATUS code (error) before mapping it to POSIX error
376 SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
377 struct smb_hdr *in_buf, int flags)
383 iov[0].iov_base = (char *)in_buf;
384 iov[0].iov_len = in_buf->smb_buf_length + 4;
385 flags |= CIFS_NO_RESP;
386 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
387 cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
393 sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
397 spin_lock(&GlobalMid_Lock);
400 spin_unlock(&GlobalMid_Lock);
404 cERROR(1, "No response to cmd %d mid %d", mid->command, mid->mid);
405 if (mid->midState == MID_REQUEST_SUBMITTED) {
406 if (server->tcpStatus == CifsExiting)
409 server->tcpStatus = CifsNeedReconnect;
410 mid->midState = MID_RETRY_NEEDED;
414 if (rc != -EHOSTDOWN) {
415 if (mid->midState == MID_RETRY_NEEDED) {
417 cFYI(1, "marking request for retry");
422 spin_unlock(&GlobalMid_Lock);
429 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
430 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
435 unsigned int receive_len;
436 unsigned long timeout;
437 struct mid_q_entry *midQ;
438 struct smb_hdr *in_buf = iov[0].iov_base;
440 long_op = flags & CIFS_TIMEOUT_MASK;
442 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
444 if ((ses == NULL) || (ses->server == NULL)) {
445 cifs_small_buf_release(in_buf);
446 cERROR(1, "Null session");
450 if (ses->server->tcpStatus == CifsExiting) {
451 cifs_small_buf_release(in_buf);
455 /* Ensure that we do not send more than 50 overlapping requests
456 to the same server. We may make this configurable later or
459 rc = wait_for_free_request(ses->server, long_op);
461 cifs_small_buf_release(in_buf);
465 /* make sure that we sign in the same order that we send on this socket
466 and avoid races inside tcp sendmsg code that could cause corruption
469 mutex_lock(&ses->server->srv_mutex);
471 rc = allocate_mid(ses, in_buf, &midQ);
473 mutex_unlock(&ses->server->srv_mutex);
474 cifs_small_buf_release(in_buf);
475 /* Update # of requests on wire to server */
476 atomic_dec(&ses->server->inFlight);
477 wake_up(&ses->server->request_q);
480 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
482 mutex_unlock(&ses->server->srv_mutex);
483 cifs_small_buf_release(in_buf);
487 midQ->midState = MID_REQUEST_SUBMITTED;
488 #ifdef CONFIG_CIFS_STATS2
489 atomic_inc(&ses->server->inSend);
491 rc = smb_sendv(ses->server, iov, n_vec);
492 #ifdef CONFIG_CIFS_STATS2
493 atomic_dec(&ses->server->inSend);
494 midQ->when_sent = jiffies;
497 mutex_unlock(&ses->server->srv_mutex);
498 cifs_small_buf_release(in_buf);
503 if (long_op == CIFS_STD_OP)
505 else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
507 else if (long_op == CIFS_LONG_OP)
508 timeout = 45 * HZ; /* should be greater than
509 servers oplock break timeout (about 43 seconds) */
510 else if (long_op == CIFS_ASYNC_OP)
512 else if (long_op == CIFS_BLOCKING_OP)
513 timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */
515 cERROR(1, "unknown timeout flag %d", long_op);
520 /* wait for 15 seconds or until woken up due to response arriving or
521 due to last connection to this server being unmounted */
522 if (signal_pending(current)) {
523 /* if signal pending do not hold up user for full smb timeout
524 but we still give response a chance to complete */
528 /* No user interrupts in wait - wreaks havoc with performance */
529 wait_for_response(ses, midQ, timeout, 10 * HZ);
531 rc = sync_mid_result(midQ, ses->server);
533 atomic_dec(&ses->server->inFlight);
534 wake_up(&ses->server->request_q);
538 receive_len = midQ->resp_buf->smb_buf_length;
540 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
541 cERROR(1, "Frame too large received. Length: %d Xid: %d",
547 /* rcvd frame is ok */
549 if (midQ->resp_buf &&
550 (midQ->midState == MID_RESPONSE_RECEIVED)) {
552 iov[0].iov_base = (char *)midQ->resp_buf;
554 *pRespBufType = CIFS_LARGE_BUFFER;
556 *pRespBufType = CIFS_SMALL_BUFFER;
557 iov[0].iov_len = receive_len + 4;
559 dump_smb(midQ->resp_buf, 80);
560 /* convert the length into a more usable form */
561 if ((receive_len > 24) &&
562 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
563 SECMODE_SIGN_ENABLED))) {
564 rc = cifs_verify_signature(midQ->resp_buf,
566 midQ->sequence_number+1);
568 cERROR(1, "Unexpected SMB signature");
569 /* BB FIXME add code to kill session */
573 /* BB special case reconnect tid and uid here? */
574 rc = map_smb_to_linux_error(midQ->resp_buf,
575 flags & CIFS_LOG_ERROR);
577 /* convert ByteCount if necessary */
578 if (receive_len >= sizeof(struct smb_hdr) - 4
579 /* do not count RFC1001 header */ +
580 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
581 BCC(midQ->resp_buf) =
582 le16_to_cpu(BCC_LE(midQ->resp_buf));
583 if ((flags & CIFS_NO_RESP) == 0)
584 midQ->resp_buf = NULL; /* mark it so buf will
589 cFYI(1, "Bad MID state?");
594 atomic_dec(&ses->server->inFlight);
595 wake_up(&ses->server->request_q);
601 SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
602 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
603 int *pbytes_returned, const int long_op)
606 unsigned int receive_len;
607 unsigned long timeout;
608 struct mid_q_entry *midQ;
611 cERROR(1, "Null smb session");
614 if (ses->server == NULL) {
615 cERROR(1, "Null tcp session");
619 if (ses->server->tcpStatus == CifsExiting)
622 /* Ensure that we do not send more than 50 overlapping requests
623 to the same server. We may make this configurable later or
626 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
627 cERROR(1, "Illegal length, greater than maximum frame, %d",
628 in_buf->smb_buf_length);
632 rc = wait_for_free_request(ses->server, long_op);
636 /* make sure that we sign in the same order that we send on this socket
637 and avoid races inside tcp sendmsg code that could cause corruption
640 mutex_lock(&ses->server->srv_mutex);
642 rc = allocate_mid(ses, in_buf, &midQ);
644 mutex_unlock(&ses->server->srv_mutex);
645 /* Update # of requests on wire to server */
646 atomic_dec(&ses->server->inFlight);
647 wake_up(&ses->server->request_q);
651 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
653 mutex_unlock(&ses->server->srv_mutex);
657 midQ->midState = MID_REQUEST_SUBMITTED;
658 #ifdef CONFIG_CIFS_STATS2
659 atomic_inc(&ses->server->inSend);
661 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
662 #ifdef CONFIG_CIFS_STATS2
663 atomic_dec(&ses->server->inSend);
664 midQ->when_sent = jiffies;
666 mutex_unlock(&ses->server->srv_mutex);
671 if (long_op == CIFS_STD_OP)
673 /* wait for 15 seconds or until woken up due to response arriving or
674 due to last connection to this server being unmounted */
675 else if (long_op == CIFS_ASYNC_OP)
677 else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
679 else if (long_op == CIFS_LONG_OP)
680 timeout = 45 * HZ; /* should be greater than
681 servers oplock break timeout (about 43 seconds) */
682 else if (long_op == CIFS_BLOCKING_OP)
683 timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
685 cERROR(1, "unknown timeout flag %d", long_op);
690 if (signal_pending(current)) {
691 /* if signal pending do not hold up user for full smb timeout
692 but we still give response a chance to complete */
696 /* No user interrupts in wait - wreaks havoc with performance */
697 wait_for_response(ses, midQ, timeout, 10 * HZ);
699 rc = sync_mid_result(midQ, ses->server);
701 atomic_dec(&ses->server->inFlight);
702 wake_up(&ses->server->request_q);
706 receive_len = midQ->resp_buf->smb_buf_length;
708 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
709 cERROR(1, "Frame too large received. Length: %d Xid: %d",
715 /* rcvd frame is ok */
717 if (midQ->resp_buf && out_buf
718 && (midQ->midState == MID_RESPONSE_RECEIVED)) {
719 out_buf->smb_buf_length = receive_len;
720 memcpy((char *)out_buf + 4,
721 (char *)midQ->resp_buf + 4,
724 dump_smb(out_buf, 92);
725 /* convert the length into a more usable form */
726 if ((receive_len > 24) &&
727 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
728 SECMODE_SIGN_ENABLED))) {
729 rc = cifs_verify_signature(out_buf,
731 midQ->sequence_number+1);
733 cERROR(1, "Unexpected SMB signature");
734 /* BB FIXME add code to kill session */
738 *pbytes_returned = out_buf->smb_buf_length;
740 /* BB special case reconnect tid and uid here? */
741 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
743 /* convert ByteCount if necessary */
744 if (receive_len >= sizeof(struct smb_hdr) - 4
745 /* do not count RFC1001 header */ +
746 (2 * out_buf->WordCount) + 2 /* bcc */ )
747 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
750 cERROR(1, "Bad MID state?");
755 atomic_dec(&ses->server->inFlight);
756 wake_up(&ses->server->request_q);
761 /* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
764 send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
765 struct mid_q_entry *midQ)
768 struct cifsSesInfo *ses = tcon->ses;
769 __u16 mid = in_buf->Mid;
771 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
773 mutex_lock(&ses->server->srv_mutex);
774 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
776 mutex_unlock(&ses->server->srv_mutex);
779 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
780 mutex_unlock(&ses->server->srv_mutex);
784 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
785 blocking lock to return. */
788 send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
789 struct smb_hdr *in_buf,
790 struct smb_hdr *out_buf)
793 struct cifsSesInfo *ses = tcon->ses;
794 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
796 /* We just modify the current in_buf to change
797 the type of lock from LOCKING_ANDX_SHARED_LOCK
798 or LOCKING_ANDX_EXCLUSIVE_LOCK to
799 LOCKING_ANDX_CANCEL_LOCK. */
801 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
803 pSMB->hdr.Mid = GetNextMid(ses->server);
805 return SendReceive(xid, ses, in_buf, out_buf,
806 &bytes_returned, CIFS_STD_OP);
810 SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
811 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
812 int *pbytes_returned)
816 unsigned int receive_len;
817 struct mid_q_entry *midQ;
818 struct cifsSesInfo *ses;
820 if (tcon == NULL || tcon->ses == NULL) {
821 cERROR(1, "Null smb session");
826 if (ses->server == NULL) {
827 cERROR(1, "Null tcp session");
831 if (ses->server->tcpStatus == CifsExiting)
834 /* Ensure that we do not send more than 50 overlapping requests
835 to the same server. We may make this configurable later or
838 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
839 cERROR(1, "Illegal length, greater than maximum frame, %d",
840 in_buf->smb_buf_length);
844 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP);
848 /* make sure that we sign in the same order that we send on this socket
849 and avoid races inside tcp sendmsg code that could cause corruption
852 mutex_lock(&ses->server->srv_mutex);
854 rc = allocate_mid(ses, in_buf, &midQ);
856 mutex_unlock(&ses->server->srv_mutex);
860 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
863 mutex_unlock(&ses->server->srv_mutex);
867 midQ->midState = MID_REQUEST_SUBMITTED;
868 #ifdef CONFIG_CIFS_STATS2
869 atomic_inc(&ses->server->inSend);
871 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
872 #ifdef CONFIG_CIFS_STATS2
873 atomic_dec(&ses->server->inSend);
874 midQ->when_sent = jiffies;
876 mutex_unlock(&ses->server->srv_mutex);
883 /* Wait for a reply - allow signals to interrupt. */
884 rc = wait_event_interruptible(ses->server->response_q,
885 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
886 ((ses->server->tcpStatus != CifsGood) &&
887 (ses->server->tcpStatus != CifsNew)));
889 /* Were we interrupted by a signal ? */
890 if ((rc == -ERESTARTSYS) &&
891 (midQ->midState == MID_REQUEST_SUBMITTED) &&
892 ((ses->server->tcpStatus == CifsGood) ||
893 (ses->server->tcpStatus == CifsNew))) {
895 if (in_buf->Command == SMB_COM_TRANSACTION2) {
896 /* POSIX lock. We send a NT_CANCEL SMB to cause the
897 blocking lock to return. */
899 rc = send_nt_cancel(tcon, in_buf, midQ);
905 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
906 to cause the blocking lock to return. */
908 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
910 /* If we get -ENOLCK back the lock may have
911 already been removed. Don't exit in this case. */
912 if (rc && rc != -ENOLCK) {
918 /* Wait 5 seconds for the response. */
919 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {
920 /* We got the response - restart system call. */
925 rc = sync_mid_result(midQ, ses->server);
929 receive_len = midQ->resp_buf->smb_buf_length;
930 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
931 cERROR(1, "Frame too large received. Length: %d Xid: %d",
937 /* rcvd frame is ok */
939 if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
941 cERROR(1, "Bad MID state?");
945 out_buf->smb_buf_length = receive_len;
946 memcpy((char *)out_buf + 4,
947 (char *)midQ->resp_buf + 4,
950 dump_smb(out_buf, 92);
951 /* convert the length into a more usable form */
952 if ((receive_len > 24) &&
953 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
954 SECMODE_SIGN_ENABLED))) {
955 rc = cifs_verify_signature(out_buf,
957 midQ->sequence_number+1);
959 cERROR(1, "Unexpected SMB signature");
960 /* BB FIXME add code to kill session */
964 *pbytes_returned = out_buf->smb_buf_length;
966 /* BB special case reconnect tid and uid here? */
967 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
969 /* convert ByteCount if necessary */
970 if (receive_len >= sizeof(struct smb_hdr) - 4
971 /* do not count RFC1001 header */ +
972 (2 * out_buf->WordCount) + 2 /* bcc */ )
973 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
977 if (rstart && rc == -EACCES)