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/wait.h>
26 #include <linux/net.h>
27 #include <linux/delay.h>
28 #include <asm/uaccess.h>
29 #include <asm/processor.h>
30 #include <linux/mempool.h>
33 #include "cifsproto.h"
34 #include "cifs_debug.h"
36 extern mempool_t *cifs_mid_poolp;
37 extern struct kmem_cache *cifs_oplock_cachep;
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 spin_lock(&GlobalMid_Lock);
65 list_add_tail(&temp->qhead, &server->pending_mid_q);
66 atomic_inc(&midCount);
67 temp->midState = MID_REQUEST_ALLOCATED;
68 spin_unlock(&GlobalMid_Lock);
73 DeleteMidQEntry(struct mid_q_entry *midEntry)
75 #ifdef CONFIG_CIFS_STATS2
78 spin_lock(&GlobalMid_Lock);
79 midEntry->midState = MID_FREE;
80 list_del(&midEntry->qhead);
81 atomic_dec(&midCount);
82 spin_unlock(&GlobalMid_Lock);
83 if (midEntry->largeBuf)
84 cifs_buf_release(midEntry->resp_buf);
86 cifs_small_buf_release(midEntry->resp_buf);
87 #ifdef CONFIG_CIFS_STATS2
89 /* commands taking longer than one second are indications that
90 something is wrong, unless it is quite a slow link or server */
91 if ((now - midEntry->when_alloc) > HZ) {
92 if ((cifsFYI & CIFS_TIMER) &&
93 (midEntry->command != SMB_COM_LOCKING_ANDX)) {
94 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
95 midEntry->command, midEntry->mid);
96 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
97 now - midEntry->when_alloc,
98 now - midEntry->when_sent,
99 now - midEntry->when_received);
103 mempool_free(midEntry, cifs_mid_poolp);
106 struct oplock_q_entry *
107 AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
109 struct oplock_q_entry *temp;
110 if ((pinode == NULL) || (tcon == NULL)) {
111 cERROR(1, ("Null parms passed to AllocOplockQEntry"));
114 temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep,
119 temp->pinode = pinode;
122 spin_lock(&GlobalMid_Lock);
123 list_add_tail(&temp->qhead, &GlobalOplock_Q);
124 spin_unlock(&GlobalMid_Lock);
130 void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
132 spin_lock(&GlobalMid_Lock);
133 /* should we check if list empty first? */
134 list_del(&oplockEntry->qhead);
135 spin_unlock(&GlobalMid_Lock);
136 kmem_cache_free(cifs_oplock_cachep, oplockEntry);
140 void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
142 struct oplock_q_entry *temp;
147 spin_lock(&GlobalMid_Lock);
148 list_for_each_entry(temp, &GlobalOplock_Q, qhead) {
149 if ((temp->tcon) && (temp->tcon == tcon)) {
150 list_del(&temp->qhead);
151 kmem_cache_free(cifs_oplock_cachep, temp);
154 spin_unlock(&GlobalMid_Lock);
158 smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
162 struct msghdr smb_msg;
163 struct smb_hdr *smb_buffer = iov[0].iov_base;
164 unsigned int len = iov[0].iov_len;
165 unsigned int total_len;
167 unsigned int smb_buf_length = smb_buffer->smb_buf_length;
168 struct socket *ssocket = server->ssocket;
171 return -ENOTSOCK; /* BB eventually add reconnect code here */
173 smb_msg.msg_name = (struct sockaddr *) &server->addr.sockAddr;
174 smb_msg.msg_namelen = sizeof(struct sockaddr);
175 smb_msg.msg_control = NULL;
176 smb_msg.msg_controllen = 0;
177 if (server->noblocksnd)
178 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
180 smb_msg.msg_flags = MSG_NOSIGNAL;
182 /* smb header is converted in header_assemble. bcc and rest of SMB word
183 area, and byte area if necessary, is converted to littleendian in
184 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
185 Flags2 is converted in SendReceive */
189 for (i = 0; i < n_vec; i++)
190 total_len += iov[i].iov_len;
192 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
193 cFYI(1, ("Sending smb: total_len %d", total_len));
194 dump_smb(smb_buffer, len);
198 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
199 n_vec - first_vec, total_len);
200 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
204 ("sends on sock %p stuck for 15 seconds",
215 if (rc == total_len) {
218 } else if (rc > total_len) {
219 cERROR(1, ("sent %d requested %d", rc, total_len));
223 /* should never happen, letting socket clear before
224 retrying is our only obvious option here */
225 cERROR(1, ("tcp sent no data"));
230 /* the line below resets i */
231 for (i = first_vec; i < n_vec; i++) {
232 if (iov[i].iov_len) {
233 if (rc > iov[i].iov_len) {
234 rc -= iov[i].iov_len;
237 iov[i].iov_base += rc;
238 iov[i].iov_len -= rc;
244 i = 0; /* in case we get ENOSPC on the next send */
247 if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
248 cFYI(1, ("partial send (%d remaining), terminating session",
250 /* If we have only sent part of an SMB then the next SMB
251 could be taken as the remainder of this one. We need
252 to kill the socket so the server throws away the partial
254 server->tcpStatus = CifsNeedReconnect;
258 cERROR(1, ("Error %d sending data on socket to server", rc));
262 /* Don't want to modify the buffer as a
263 side effect of this call. */
264 smb_buffer->smb_buf_length = smb_buf_length;
270 smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
271 unsigned int smb_buf_length)
275 iov.iov_base = smb_buffer;
276 iov.iov_len = smb_buf_length + 4;
278 return smb_sendv(server, &iov, 1);
281 static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
283 if (long_op == CIFS_ASYNC_OP) {
284 /* oplock breaks must not be held up */
285 atomic_inc(&ses->server->inFlight);
289 spin_lock(&GlobalMid_Lock);
291 if (atomic_read(&ses->server->inFlight) >=
293 spin_unlock(&GlobalMid_Lock);
294 #ifdef CONFIG_CIFS_STATS2
295 atomic_inc(&ses->server->num_waiters);
297 wait_event(ses->server->request_q,
298 atomic_read(&ses->server->inFlight)
300 #ifdef CONFIG_CIFS_STATS2
301 atomic_dec(&ses->server->num_waiters);
303 spin_lock(&GlobalMid_Lock);
305 if (ses->server->tcpStatus == CifsExiting) {
306 spin_unlock(&GlobalMid_Lock);
310 /* can not count locking commands against total
311 as they are allowed to block on server */
313 /* update # of requests on the wire to server */
314 if (long_op != CIFS_BLOCKING_OP)
315 atomic_inc(&ses->server->inFlight);
316 spin_unlock(&GlobalMid_Lock);
323 static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
324 struct mid_q_entry **ppmidQ)
326 if (ses->server->tcpStatus == CifsExiting) {
330 if (ses->server->tcpStatus == CifsNeedReconnect) {
331 cFYI(1, ("tcp session dead - return to caller to retry"));
335 if (ses->status != CifsGood) {
336 /* check if SMB session is bad because we are setting it up */
337 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
338 (in_buf->Command != SMB_COM_NEGOTIATE))
340 /* else ok - we are setting up session */
342 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
348 static int wait_for_response(struct cifsSesInfo *ses,
349 struct mid_q_entry *midQ,
350 unsigned long timeout,
351 unsigned long time_to_wait)
353 unsigned long curr_timeout;
356 curr_timeout = timeout + jiffies;
357 wait_event_timeout(ses->server->response_q,
358 midQ->midState != MID_REQUEST_SUBMITTED, timeout);
360 if (time_after(jiffies, curr_timeout) &&
361 (midQ->midState == MID_REQUEST_SUBMITTED) &&
362 ((ses->server->tcpStatus == CifsGood) ||
363 (ses->server->tcpStatus == CifsNew))) {
367 /* We timed out. Is the server still
369 spin_lock(&GlobalMid_Lock);
370 lrt = ses->server->lstrp;
371 spin_unlock(&GlobalMid_Lock);
373 /* Calculate time_to_wait past last receive time.
374 Although we prefer not to time out if the
375 server is still responding - we will time
376 out if the server takes more than 15 (or 45
377 or 180) seconds to respond to this request
378 and has not responded to any request from
379 other threads on the client within 10 seconds */
381 if (time_after(jiffies, lrt)) {
382 /* No replies for time_to_wait. */
383 cERROR(1, ("server not responding"));
395 * Send an SMB Request. No response info (other than return code)
396 * needs to be parsed.
398 * flags indicate the type of request buffer and how long to wait
399 * and whether to log NT STATUS code (error) before mapping it to POSIX error
403 SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
404 struct smb_hdr *in_buf, int flags)
410 iov[0].iov_base = (char *)in_buf;
411 iov[0].iov_len = in_buf->smb_buf_length + 4;
412 flags |= CIFS_NO_RESP;
413 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
414 cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc));
420 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
421 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
426 unsigned int receive_len;
427 unsigned long timeout;
428 struct mid_q_entry *midQ;
429 struct smb_hdr *in_buf = iov[0].iov_base;
431 long_op = flags & CIFS_TIMEOUT_MASK;
433 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
435 if ((ses == NULL) || (ses->server == NULL)) {
436 cifs_small_buf_release(in_buf);
437 cERROR(1, ("Null session"));
441 if (ses->server->tcpStatus == CifsExiting) {
442 cifs_small_buf_release(in_buf);
446 /* Ensure that we do not send more than 50 overlapping requests
447 to the same server. We may make this configurable later or
450 rc = wait_for_free_request(ses, long_op);
452 cifs_small_buf_release(in_buf);
456 /* make sure that we sign in the same order that we send on this socket
457 and avoid races inside tcp sendmsg code that could cause corruption
460 mutex_lock(&ses->server->srv_mutex);
462 rc = allocate_mid(ses, in_buf, &midQ);
464 mutex_unlock(&ses->server->srv_mutex);
465 cifs_small_buf_release(in_buf);
466 /* Update # of requests on wire to server */
467 atomic_dec(&ses->server->inFlight);
468 wake_up(&ses->server->request_q);
471 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
473 mutex_unlock(&ses->server->srv_mutex);
474 cifs_small_buf_release(in_buf);
478 midQ->midState = MID_REQUEST_SUBMITTED;
479 #ifdef CONFIG_CIFS_STATS2
480 atomic_inc(&ses->server->inSend);
482 rc = smb_sendv(ses->server, iov, n_vec);
483 #ifdef CONFIG_CIFS_STATS2
484 atomic_dec(&ses->server->inSend);
485 midQ->when_sent = jiffies;
488 mutex_unlock(&ses->server->srv_mutex);
489 cifs_small_buf_release(in_buf);
494 if (long_op == CIFS_STD_OP)
496 else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
498 else if (long_op == CIFS_LONG_OP)
499 timeout = 45 * HZ; /* should be greater than
500 servers oplock break timeout (about 43 seconds) */
501 else if (long_op == CIFS_ASYNC_OP)
503 else if (long_op == CIFS_BLOCKING_OP)
504 timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */
506 cERROR(1, ("unknown timeout flag %d", long_op));
511 /* wait for 15 seconds or until woken up due to response arriving or
512 due to last connection to this server being unmounted */
513 if (signal_pending(current)) {
514 /* if signal pending do not hold up user for full smb timeout
515 but we still give response a chance to complete */
519 /* No user interrupts in wait - wreaks havoc with performance */
520 wait_for_response(ses, midQ, timeout, 10 * HZ);
522 spin_lock(&GlobalMid_Lock);
524 if (midQ->resp_buf == NULL) {
525 cERROR(1, ("No response to cmd %d mid %d",
526 midQ->command, midQ->mid));
527 if (midQ->midState == MID_REQUEST_SUBMITTED) {
528 if (ses->server->tcpStatus == CifsExiting)
531 ses->server->tcpStatus = CifsNeedReconnect;
532 midQ->midState = MID_RETRY_NEEDED;
536 if (rc != -EHOSTDOWN) {
537 if (midQ->midState == MID_RETRY_NEEDED) {
539 cFYI(1, ("marking request for retry"));
544 spin_unlock(&GlobalMid_Lock);
545 DeleteMidQEntry(midQ);
546 /* Update # of requests on wire to server */
547 atomic_dec(&ses->server->inFlight);
548 wake_up(&ses->server->request_q);
552 spin_unlock(&GlobalMid_Lock);
553 receive_len = midQ->resp_buf->smb_buf_length;
555 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
556 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
562 /* rcvd frame is ok */
564 if (midQ->resp_buf &&
565 (midQ->midState == MID_RESPONSE_RECEIVED)) {
567 iov[0].iov_base = (char *)midQ->resp_buf;
569 *pRespBufType = CIFS_LARGE_BUFFER;
571 *pRespBufType = CIFS_SMALL_BUFFER;
572 iov[0].iov_len = receive_len + 4;
574 dump_smb(midQ->resp_buf, 80);
575 /* convert the length into a more usable form */
576 if ((receive_len > 24) &&
577 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
578 SECMODE_SIGN_ENABLED))) {
579 rc = cifs_verify_signature(midQ->resp_buf,
580 &ses->server->mac_signing_key,
581 midQ->sequence_number+1);
583 cERROR(1, ("Unexpected SMB signature"));
584 /* BB FIXME add code to kill session */
588 /* BB special case reconnect tid and uid here? */
589 rc = map_smb_to_linux_error(midQ->resp_buf,
590 flags & CIFS_LOG_ERROR);
592 /* convert ByteCount if necessary */
593 if (receive_len >= sizeof(struct smb_hdr) - 4
594 /* do not count RFC1001 header */ +
595 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
596 BCC(midQ->resp_buf) =
597 le16_to_cpu(BCC_LE(midQ->resp_buf));
598 if ((flags & CIFS_NO_RESP) == 0)
599 midQ->resp_buf = NULL; /* mark it so buf will
604 cFYI(1, ("Bad MID state?"));
608 DeleteMidQEntry(midQ);
609 atomic_dec(&ses->server->inFlight);
610 wake_up(&ses->server->request_q);
616 SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
617 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
618 int *pbytes_returned, const int long_op)
621 unsigned int receive_len;
622 unsigned long timeout;
623 struct mid_q_entry *midQ;
626 cERROR(1, ("Null smb session"));
629 if (ses->server == NULL) {
630 cERROR(1, ("Null tcp session"));
634 if (ses->server->tcpStatus == CifsExiting)
637 /* Ensure that we do not send more than 50 overlapping requests
638 to the same server. We may make this configurable later or
641 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
642 cERROR(1, ("Illegal length, greater than maximum frame, %d",
643 in_buf->smb_buf_length));
647 rc = wait_for_free_request(ses, long_op);
651 /* make sure that we sign in the same order that we send on this socket
652 and avoid races inside tcp sendmsg code that could cause corruption
655 mutex_lock(&ses->server->srv_mutex);
657 rc = allocate_mid(ses, in_buf, &midQ);
659 mutex_unlock(&ses->server->srv_mutex);
660 /* Update # of requests on wire to server */
661 atomic_dec(&ses->server->inFlight);
662 wake_up(&ses->server->request_q);
666 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
668 mutex_unlock(&ses->server->srv_mutex);
672 midQ->midState = MID_REQUEST_SUBMITTED;
673 #ifdef CONFIG_CIFS_STATS2
674 atomic_inc(&ses->server->inSend);
676 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
677 #ifdef CONFIG_CIFS_STATS2
678 atomic_dec(&ses->server->inSend);
679 midQ->when_sent = jiffies;
681 mutex_unlock(&ses->server->srv_mutex);
686 if (long_op == CIFS_STD_OP)
688 /* wait for 15 seconds or until woken up due to response arriving or
689 due to last connection to this server being unmounted */
690 else if (long_op == CIFS_ASYNC_OP)
692 else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
694 else if (long_op == CIFS_LONG_OP)
695 timeout = 45 * HZ; /* should be greater than
696 servers oplock break timeout (about 43 seconds) */
697 else if (long_op == CIFS_BLOCKING_OP)
698 timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
700 cERROR(1, ("unknown timeout flag %d", long_op));
705 if (signal_pending(current)) {
706 /* if signal pending do not hold up user for full smb timeout
707 but we still give response a chance to complete */
711 /* No user interrupts in wait - wreaks havoc with performance */
712 wait_for_response(ses, midQ, timeout, 10 * HZ);
714 spin_lock(&GlobalMid_Lock);
715 if (midQ->resp_buf == NULL) {
716 cERROR(1, ("No response for cmd %d mid %d",
717 midQ->command, midQ->mid));
718 if (midQ->midState == MID_REQUEST_SUBMITTED) {
719 if (ses->server->tcpStatus == CifsExiting)
722 ses->server->tcpStatus = CifsNeedReconnect;
723 midQ->midState = MID_RETRY_NEEDED;
727 if (rc != -EHOSTDOWN) {
728 if (midQ->midState == MID_RETRY_NEEDED) {
730 cFYI(1, ("marking request for retry"));
735 spin_unlock(&GlobalMid_Lock);
736 DeleteMidQEntry(midQ);
737 /* Update # of requests on wire to server */
738 atomic_dec(&ses->server->inFlight);
739 wake_up(&ses->server->request_q);
743 spin_unlock(&GlobalMid_Lock);
744 receive_len = midQ->resp_buf->smb_buf_length;
746 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
747 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
753 /* rcvd frame is ok */
755 if (midQ->resp_buf && out_buf
756 && (midQ->midState == MID_RESPONSE_RECEIVED)) {
757 out_buf->smb_buf_length = receive_len;
758 memcpy((char *)out_buf + 4,
759 (char *)midQ->resp_buf + 4,
762 dump_smb(out_buf, 92);
763 /* convert the length into a more usable form */
764 if ((receive_len > 24) &&
765 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
766 SECMODE_SIGN_ENABLED))) {
767 rc = cifs_verify_signature(out_buf,
768 &ses->server->mac_signing_key,
769 midQ->sequence_number+1);
771 cERROR(1, ("Unexpected SMB signature"));
772 /* BB FIXME add code to kill session */
776 *pbytes_returned = out_buf->smb_buf_length;
778 /* BB special case reconnect tid and uid here? */
779 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
781 /* convert ByteCount if necessary */
782 if (receive_len >= sizeof(struct smb_hdr) - 4
783 /* do not count RFC1001 header */ +
784 (2 * out_buf->WordCount) + 2 /* bcc */ )
785 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
788 cERROR(1, ("Bad MID state?"));
792 DeleteMidQEntry(midQ);
793 atomic_dec(&ses->server->inFlight);
794 wake_up(&ses->server->request_q);
799 /* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
802 send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
803 struct mid_q_entry *midQ)
806 struct cifsSesInfo *ses = tcon->ses;
807 __u16 mid = in_buf->Mid;
809 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
811 mutex_lock(&ses->server->srv_mutex);
812 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
814 mutex_unlock(&ses->server->srv_mutex);
817 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
818 mutex_unlock(&ses->server->srv_mutex);
822 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
823 blocking lock to return. */
826 send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
827 struct smb_hdr *in_buf,
828 struct smb_hdr *out_buf)
831 struct cifsSesInfo *ses = tcon->ses;
832 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
834 /* We just modify the current in_buf to change
835 the type of lock from LOCKING_ANDX_SHARED_LOCK
836 or LOCKING_ANDX_EXCLUSIVE_LOCK to
837 LOCKING_ANDX_CANCEL_LOCK. */
839 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
841 pSMB->hdr.Mid = GetNextMid(ses->server);
843 return SendReceive(xid, ses, in_buf, out_buf,
844 &bytes_returned, CIFS_STD_OP);
848 SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
849 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
850 int *pbytes_returned)
854 unsigned int receive_len;
855 struct mid_q_entry *midQ;
856 struct cifsSesInfo *ses;
858 if (tcon == NULL || tcon->ses == NULL) {
859 cERROR(1, ("Null smb session"));
864 if (ses->server == NULL) {
865 cERROR(1, ("Null tcp session"));
869 if (ses->server->tcpStatus == CifsExiting)
872 /* Ensure that we do not send more than 50 overlapping requests
873 to the same server. We may make this configurable later or
876 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
877 cERROR(1, ("Illegal length, greater than maximum frame, %d",
878 in_buf->smb_buf_length));
882 rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
886 /* make sure that we sign in the same order that we send on this socket
887 and avoid races inside tcp sendmsg code that could cause corruption
890 mutex_lock(&ses->server->srv_mutex);
892 rc = allocate_mid(ses, in_buf, &midQ);
894 mutex_unlock(&ses->server->srv_mutex);
898 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
900 DeleteMidQEntry(midQ);
901 mutex_unlock(&ses->server->srv_mutex);
905 midQ->midState = MID_REQUEST_SUBMITTED;
906 #ifdef CONFIG_CIFS_STATS2
907 atomic_inc(&ses->server->inSend);
909 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
910 #ifdef CONFIG_CIFS_STATS2
911 atomic_dec(&ses->server->inSend);
912 midQ->when_sent = jiffies;
914 mutex_unlock(&ses->server->srv_mutex);
917 DeleteMidQEntry(midQ);
921 /* Wait for a reply - allow signals to interrupt. */
922 rc = wait_event_interruptible(ses->server->response_q,
923 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
924 ((ses->server->tcpStatus != CifsGood) &&
925 (ses->server->tcpStatus != CifsNew)));
927 /* Were we interrupted by a signal ? */
928 if ((rc == -ERESTARTSYS) &&
929 (midQ->midState == MID_REQUEST_SUBMITTED) &&
930 ((ses->server->tcpStatus == CifsGood) ||
931 (ses->server->tcpStatus == CifsNew))) {
933 if (in_buf->Command == SMB_COM_TRANSACTION2) {
934 /* POSIX lock. We send a NT_CANCEL SMB to cause the
935 blocking lock to return. */
937 rc = send_nt_cancel(tcon, in_buf, midQ);
939 DeleteMidQEntry(midQ);
943 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
944 to cause the blocking lock to return. */
946 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
948 /* If we get -ENOLCK back the lock may have
949 already been removed. Don't exit in this case. */
950 if (rc && rc != -ENOLCK) {
951 DeleteMidQEntry(midQ);
956 /* Wait 5 seconds for the response. */
957 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {
958 /* We got the response - restart system call. */
963 spin_lock(&GlobalMid_Lock);
964 if (midQ->resp_buf) {
965 spin_unlock(&GlobalMid_Lock);
966 receive_len = midQ->resp_buf->smb_buf_length;
968 cERROR(1, ("No response for cmd %d mid %d",
969 midQ->command, midQ->mid));
970 if (midQ->midState == MID_REQUEST_SUBMITTED) {
971 if (ses->server->tcpStatus == CifsExiting)
974 ses->server->tcpStatus = CifsNeedReconnect;
975 midQ->midState = MID_RETRY_NEEDED;
979 if (rc != -EHOSTDOWN) {
980 if (midQ->midState == MID_RETRY_NEEDED) {
982 cFYI(1, ("marking request for retry"));
987 spin_unlock(&GlobalMid_Lock);
988 DeleteMidQEntry(midQ);
992 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
993 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
999 /* rcvd frame is ok */
1001 if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
1003 cERROR(1, ("Bad MID state?"));
1007 out_buf->smb_buf_length = receive_len;
1008 memcpy((char *)out_buf + 4,
1009 (char *)midQ->resp_buf + 4,
1012 dump_smb(out_buf, 92);
1013 /* convert the length into a more usable form */
1014 if ((receive_len > 24) &&
1015 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
1016 SECMODE_SIGN_ENABLED))) {
1017 rc = cifs_verify_signature(out_buf,
1018 &ses->server->mac_signing_key,
1019 midQ->sequence_number+1);
1021 cERROR(1, ("Unexpected SMB signature"));
1022 /* BB FIXME add code to kill session */
1026 *pbytes_returned = out_buf->smb_buf_length;
1028 /* BB special case reconnect tid and uid here? */
1029 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
1031 /* convert ByteCount if necessary */
1032 if (receive_len >= sizeof(struct smb_hdr) - 4
1033 /* do not count RFC1001 header */ +
1034 (2 * out_buf->WordCount) + 2 /* bcc */ )
1035 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
1038 DeleteMidQEntry(midQ);
1039 if (rstart && rc == -EACCES)
1040 return -ERESTARTSYS;