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
);
107 smb_sendv(struct TCP_Server_Info
*server
, struct kvec
*iov
, int n_vec
)
111 struct msghdr smb_msg
;
112 struct smb_hdr
*smb_buffer
= iov
[0].iov_base
;
113 unsigned int len
= iov
[0].iov_len
;
114 unsigned int total_len
;
116 unsigned int smb_buf_length
= smb_buffer
->smb_buf_length
;
117 struct socket
*ssocket
= server
->ssocket
;
120 return -ENOTSOCK
; /* BB eventually add reconnect code here */
122 smb_msg
.msg_name
= (struct sockaddr
*) &server
->addr
.sockAddr
;
123 smb_msg
.msg_namelen
= sizeof(struct sockaddr
);
124 smb_msg
.msg_control
= NULL
;
125 smb_msg
.msg_controllen
= 0;
126 if (server
->noblocksnd
)
127 smb_msg
.msg_flags
= MSG_DONTWAIT
+ MSG_NOSIGNAL
;
129 smb_msg
.msg_flags
= MSG_NOSIGNAL
;
131 /* smb header is converted in header_assemble. bcc and rest of SMB word
132 area, and byte area if necessary, is converted to littleendian in
133 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
134 Flags2 is converted in SendReceive */
138 for (i
= 0; i
< n_vec
; i
++)
139 total_len
+= iov
[i
].iov_len
;
141 smb_buffer
->smb_buf_length
= cpu_to_be32(smb_buffer
->smb_buf_length
);
142 cFYI(1, ("Sending smb: total_len %d", total_len
));
143 dump_smb(smb_buffer
, len
);
147 rc
= kernel_sendmsg(ssocket
, &smb_msg
, &iov
[first_vec
],
148 n_vec
- first_vec
, total_len
);
149 if ((rc
== -ENOSPC
) || (rc
== -EAGAIN
)) {
151 /* if blocking send we try 3 times, since each can block
152 for 5 seconds. For nonblocking we have to try more
153 but wait increasing amounts of time allowing time for
154 socket to clear. The overall time we wait in either
155 case to send on the socket is about 15 seconds.
156 Similarly we wait for 15 seconds for
157 a response from the server in SendReceive[2]
158 for the server to send a response back for
159 most types of requests (except SMB Write
160 past end of file which can be slow, and
161 blocking lock operations). NFS waits slightly longer
162 than CIFS, but this can make it take longer for
163 nonresponsive servers to be detected and 15 seconds
164 is more than enough time for modern networks to
165 send a packet. In most cases if we fail to send
166 after the retries we will kill the socket and
167 reconnect which may clear the network problem.
169 if ((i
>= 14) || (!server
->noblocksnd
&& (i
> 2))) {
171 ("sends on sock %p stuck for 15 seconds",
182 if (rc
== total_len
) {
185 } else if (rc
> total_len
) {
186 cERROR(1, ("sent %d requested %d", rc
, total_len
));
190 /* should never happen, letting socket clear before
191 retrying is our only obvious option here */
192 cERROR(1, ("tcp sent no data"));
197 /* the line below resets i */
198 for (i
= first_vec
; i
< n_vec
; i
++) {
199 if (iov
[i
].iov_len
) {
200 if (rc
> iov
[i
].iov_len
) {
201 rc
-= iov
[i
].iov_len
;
204 iov
[i
].iov_base
+= rc
;
205 iov
[i
].iov_len
-= rc
;
211 i
= 0; /* in case we get ENOSPC on the next send */
214 if ((total_len
> 0) && (total_len
!= smb_buf_length
+ 4)) {
215 cFYI(1, ("partial send (%d remaining), terminating session",
217 /* If we have only sent part of an SMB then the next SMB
218 could be taken as the remainder of this one. We need
219 to kill the socket so the server throws away the partial
221 server
->tcpStatus
= CifsNeedReconnect
;
225 cERROR(1, ("Error %d sending data on socket to server", rc
));
229 /* Don't want to modify the buffer as a
230 side effect of this call. */
231 smb_buffer
->smb_buf_length
= smb_buf_length
;
237 smb_send(struct TCP_Server_Info
*server
, struct smb_hdr
*smb_buffer
,
238 unsigned int smb_buf_length
)
242 iov
.iov_base
= smb_buffer
;
243 iov
.iov_len
= smb_buf_length
+ 4;
245 return smb_sendv(server
, &iov
, 1);
248 static int wait_for_free_request(struct cifsSesInfo
*ses
, const int long_op
)
250 if (long_op
== CIFS_ASYNC_OP
) {
251 /* oplock breaks must not be held up */
252 atomic_inc(&ses
->server
->inFlight
);
256 spin_lock(&GlobalMid_Lock
);
258 if (atomic_read(&ses
->server
->inFlight
) >=
260 spin_unlock(&GlobalMid_Lock
);
261 #ifdef CONFIG_CIFS_STATS2
262 atomic_inc(&ses
->server
->num_waiters
);
264 wait_event(ses
->server
->request_q
,
265 atomic_read(&ses
->server
->inFlight
)
267 #ifdef CONFIG_CIFS_STATS2
268 atomic_dec(&ses
->server
->num_waiters
);
270 spin_lock(&GlobalMid_Lock
);
272 if (ses
->server
->tcpStatus
== CifsExiting
) {
273 spin_unlock(&GlobalMid_Lock
);
277 /* can not count locking commands against total
278 as they are allowed to block on server */
280 /* update # of requests on the wire to server */
281 if (long_op
!= CIFS_BLOCKING_OP
)
282 atomic_inc(&ses
->server
->inFlight
);
283 spin_unlock(&GlobalMid_Lock
);
290 static int allocate_mid(struct cifsSesInfo
*ses
, struct smb_hdr
*in_buf
,
291 struct mid_q_entry
**ppmidQ
)
293 if (ses
->server
->tcpStatus
== CifsExiting
) {
297 if (ses
->server
->tcpStatus
== CifsNeedReconnect
) {
298 cFYI(1, ("tcp session dead - return to caller to retry"));
302 if (ses
->status
!= CifsGood
) {
303 /* check if SMB session is bad because we are setting it up */
304 if ((in_buf
->Command
!= SMB_COM_SESSION_SETUP_ANDX
) &&
305 (in_buf
->Command
!= SMB_COM_NEGOTIATE
))
307 /* else ok - we are setting up session */
309 *ppmidQ
= AllocMidQEntry(in_buf
, ses
->server
);
315 static int wait_for_response(struct cifsSesInfo
*ses
,
316 struct mid_q_entry
*midQ
,
317 unsigned long timeout
,
318 unsigned long time_to_wait
)
320 unsigned long curr_timeout
;
323 curr_timeout
= timeout
+ jiffies
;
324 wait_event_timeout(ses
->server
->response_q
,
325 midQ
->midState
!= MID_REQUEST_SUBMITTED
, timeout
);
327 if (time_after(jiffies
, curr_timeout
) &&
328 (midQ
->midState
== MID_REQUEST_SUBMITTED
) &&
329 ((ses
->server
->tcpStatus
== CifsGood
) ||
330 (ses
->server
->tcpStatus
== CifsNew
))) {
334 /* We timed out. Is the server still
336 spin_lock(&GlobalMid_Lock
);
337 lrt
= ses
->server
->lstrp
;
338 spin_unlock(&GlobalMid_Lock
);
340 /* Calculate time_to_wait past last receive time.
341 Although we prefer not to time out if the
342 server is still responding - we will time
343 out if the server takes more than 15 (or 45
344 or 180) seconds to respond to this request
345 and has not responded to any request from
346 other threads on the client within 10 seconds */
348 if (time_after(jiffies
, lrt
)) {
349 /* No replies for time_to_wait. */
350 cERROR(1, ("server not responding"));
362 * Send an SMB Request. No response info (other than return code)
363 * needs to be parsed.
365 * flags indicate the type of request buffer and how long to wait
366 * and whether to log NT STATUS code (error) before mapping it to POSIX error
370 SendReceiveNoRsp(const unsigned int xid
, struct cifsSesInfo
*ses
,
371 struct smb_hdr
*in_buf
, int flags
)
377 iov
[0].iov_base
= (char *)in_buf
;
378 iov
[0].iov_len
= in_buf
->smb_buf_length
+ 4;
379 flags
|= CIFS_NO_RESP
;
380 rc
= SendReceive2(xid
, ses
, iov
, 1, &resp_buf_type
, flags
);
381 cFYI(DBG2
, ("SendRcvNoRsp flags %d rc %d", flags
, rc
));
387 SendReceive2(const unsigned int xid
, struct cifsSesInfo
*ses
,
388 struct kvec
*iov
, int n_vec
, int *pRespBufType
/* ret */,
393 unsigned int receive_len
;
394 unsigned long timeout
;
395 struct mid_q_entry
*midQ
;
396 struct smb_hdr
*in_buf
= iov
[0].iov_base
;
398 long_op
= flags
& CIFS_TIMEOUT_MASK
;
400 *pRespBufType
= CIFS_NO_BUFFER
; /* no response buf yet */
402 if ((ses
== NULL
) || (ses
->server
== NULL
)) {
403 cifs_small_buf_release(in_buf
);
404 cERROR(1, ("Null session"));
408 if (ses
->server
->tcpStatus
== CifsExiting
) {
409 cifs_small_buf_release(in_buf
);
413 /* Ensure that we do not send more than 50 overlapping requests
414 to the same server. We may make this configurable later or
417 rc
= wait_for_free_request(ses
, long_op
);
419 cifs_small_buf_release(in_buf
);
423 /* make sure that we sign in the same order that we send on this socket
424 and avoid races inside tcp sendmsg code that could cause corruption
427 mutex_lock(&ses
->server
->srv_mutex
);
429 rc
= allocate_mid(ses
, in_buf
, &midQ
);
431 mutex_unlock(&ses
->server
->srv_mutex
);
432 cifs_small_buf_release(in_buf
);
433 /* Update # of requests on wire to server */
434 atomic_dec(&ses
->server
->inFlight
);
435 wake_up(&ses
->server
->request_q
);
438 rc
= cifs_sign_smb2(iov
, n_vec
, ses
->server
, &midQ
->sequence_number
);
440 mutex_unlock(&ses
->server
->srv_mutex
);
441 cifs_small_buf_release(in_buf
);
445 midQ
->midState
= MID_REQUEST_SUBMITTED
;
446 #ifdef CONFIG_CIFS_STATS2
447 atomic_inc(&ses
->server
->inSend
);
449 rc
= smb_sendv(ses
->server
, iov
, n_vec
);
450 #ifdef CONFIG_CIFS_STATS2
451 atomic_dec(&ses
->server
->inSend
);
452 midQ
->when_sent
= jiffies
;
455 mutex_unlock(&ses
->server
->srv_mutex
);
456 cifs_small_buf_release(in_buf
);
461 if (long_op
== CIFS_STD_OP
)
463 else if (long_op
== CIFS_VLONG_OP
) /* e.g. slow writes past EOF */
465 else if (long_op
== CIFS_LONG_OP
)
466 timeout
= 45 * HZ
; /* should be greater than
467 servers oplock break timeout (about 43 seconds) */
468 else if (long_op
== CIFS_ASYNC_OP
)
470 else if (long_op
== CIFS_BLOCKING_OP
)
471 timeout
= 0x7FFFFFFF; /* large, but not so large as to wrap */
473 cERROR(1, ("unknown timeout flag %d", long_op
));
478 /* wait for 15 seconds or until woken up due to response arriving or
479 due to last connection to this server being unmounted */
480 if (signal_pending(current
)) {
481 /* if signal pending do not hold up user for full smb timeout
482 but we still give response a chance to complete */
486 /* No user interrupts in wait - wreaks havoc with performance */
487 wait_for_response(ses
, midQ
, timeout
, 10 * HZ
);
489 spin_lock(&GlobalMid_Lock
);
491 if (midQ
->resp_buf
== NULL
) {
492 cERROR(1, ("No response to cmd %d mid %d",
493 midQ
->command
, midQ
->mid
));
494 if (midQ
->midState
== MID_REQUEST_SUBMITTED
) {
495 if (ses
->server
->tcpStatus
== CifsExiting
)
498 ses
->server
->tcpStatus
= CifsNeedReconnect
;
499 midQ
->midState
= MID_RETRY_NEEDED
;
503 if (rc
!= -EHOSTDOWN
) {
504 if (midQ
->midState
== MID_RETRY_NEEDED
) {
506 cFYI(1, ("marking request for retry"));
511 spin_unlock(&GlobalMid_Lock
);
512 DeleteMidQEntry(midQ
);
513 /* Update # of requests on wire to server */
514 atomic_dec(&ses
->server
->inFlight
);
515 wake_up(&ses
->server
->request_q
);
519 spin_unlock(&GlobalMid_Lock
);
520 receive_len
= midQ
->resp_buf
->smb_buf_length
;
522 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
523 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
529 /* rcvd frame is ok */
531 if (midQ
->resp_buf
&&
532 (midQ
->midState
== MID_RESPONSE_RECEIVED
)) {
534 iov
[0].iov_base
= (char *)midQ
->resp_buf
;
536 *pRespBufType
= CIFS_LARGE_BUFFER
;
538 *pRespBufType
= CIFS_SMALL_BUFFER
;
539 iov
[0].iov_len
= receive_len
+ 4;
541 dump_smb(midQ
->resp_buf
, 80);
542 /* convert the length into a more usable form */
543 if ((receive_len
> 24) &&
544 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
545 SECMODE_SIGN_ENABLED
))) {
546 rc
= cifs_verify_signature(midQ
->resp_buf
,
547 &ses
->server
->mac_signing_key
,
548 midQ
->sequence_number
+1);
550 cERROR(1, ("Unexpected SMB signature"));
551 /* BB FIXME add code to kill session */
555 /* BB special case reconnect tid and uid here? */
556 rc
= map_smb_to_linux_error(midQ
->resp_buf
,
557 flags
& CIFS_LOG_ERROR
);
559 /* convert ByteCount if necessary */
560 if (receive_len
>= sizeof(struct smb_hdr
) - 4
561 /* do not count RFC1001 header */ +
562 (2 * midQ
->resp_buf
->WordCount
) + 2 /* bcc */ )
563 BCC(midQ
->resp_buf
) =
564 le16_to_cpu(BCC_LE(midQ
->resp_buf
));
565 if ((flags
& CIFS_NO_RESP
) == 0)
566 midQ
->resp_buf
= NULL
; /* mark it so buf will
571 cFYI(1, ("Bad MID state?"));
575 DeleteMidQEntry(midQ
);
576 atomic_dec(&ses
->server
->inFlight
);
577 wake_up(&ses
->server
->request_q
);
583 SendReceive(const unsigned int xid
, struct cifsSesInfo
*ses
,
584 struct smb_hdr
*in_buf
, struct smb_hdr
*out_buf
,
585 int *pbytes_returned
, const int long_op
)
588 unsigned int receive_len
;
589 unsigned long timeout
;
590 struct mid_q_entry
*midQ
;
593 cERROR(1, ("Null smb session"));
596 if (ses
->server
== NULL
) {
597 cERROR(1, ("Null tcp session"));
601 if (ses
->server
->tcpStatus
== CifsExiting
)
604 /* Ensure that we do not send more than 50 overlapping requests
605 to the same server. We may make this configurable later or
608 if (in_buf
->smb_buf_length
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
- 4) {
609 cERROR(1, ("Illegal length, greater than maximum frame, %d",
610 in_buf
->smb_buf_length
));
614 rc
= wait_for_free_request(ses
, long_op
);
618 /* make sure that we sign in the same order that we send on this socket
619 and avoid races inside tcp sendmsg code that could cause corruption
622 mutex_lock(&ses
->server
->srv_mutex
);
624 rc
= allocate_mid(ses
, in_buf
, &midQ
);
626 mutex_unlock(&ses
->server
->srv_mutex
);
627 /* Update # of requests on wire to server */
628 atomic_dec(&ses
->server
->inFlight
);
629 wake_up(&ses
->server
->request_q
);
633 rc
= cifs_sign_smb(in_buf
, ses
->server
, &midQ
->sequence_number
);
635 mutex_unlock(&ses
->server
->srv_mutex
);
639 midQ
->midState
= MID_REQUEST_SUBMITTED
;
640 #ifdef CONFIG_CIFS_STATS2
641 atomic_inc(&ses
->server
->inSend
);
643 rc
= smb_send(ses
->server
, in_buf
, in_buf
->smb_buf_length
);
644 #ifdef CONFIG_CIFS_STATS2
645 atomic_dec(&ses
->server
->inSend
);
646 midQ
->when_sent
= jiffies
;
648 mutex_unlock(&ses
->server
->srv_mutex
);
653 if (long_op
== CIFS_STD_OP
)
655 /* wait for 15 seconds or until woken up due to response arriving or
656 due to last connection to this server being unmounted */
657 else if (long_op
== CIFS_ASYNC_OP
)
659 else if (long_op
== CIFS_VLONG_OP
) /* writes past EOF can be slow */
661 else if (long_op
== CIFS_LONG_OP
)
662 timeout
= 45 * HZ
; /* should be greater than
663 servers oplock break timeout (about 43 seconds) */
664 else if (long_op
== CIFS_BLOCKING_OP
)
665 timeout
= 0x7FFFFFFF; /* large but no so large as to wrap */
667 cERROR(1, ("unknown timeout flag %d", long_op
));
672 if (signal_pending(current
)) {
673 /* if signal pending do not hold up user for full smb timeout
674 but we still give response a chance to complete */
678 /* No user interrupts in wait - wreaks havoc with performance */
679 wait_for_response(ses
, midQ
, timeout
, 10 * HZ
);
681 spin_lock(&GlobalMid_Lock
);
682 if (midQ
->resp_buf
== NULL
) {
683 cERROR(1, ("No response for cmd %d mid %d",
684 midQ
->command
, midQ
->mid
));
685 if (midQ
->midState
== MID_REQUEST_SUBMITTED
) {
686 if (ses
->server
->tcpStatus
== CifsExiting
)
689 ses
->server
->tcpStatus
= CifsNeedReconnect
;
690 midQ
->midState
= MID_RETRY_NEEDED
;
694 if (rc
!= -EHOSTDOWN
) {
695 if (midQ
->midState
== MID_RETRY_NEEDED
) {
697 cFYI(1, ("marking request for retry"));
702 spin_unlock(&GlobalMid_Lock
);
703 DeleteMidQEntry(midQ
);
704 /* Update # of requests on wire to server */
705 atomic_dec(&ses
->server
->inFlight
);
706 wake_up(&ses
->server
->request_q
);
710 spin_unlock(&GlobalMid_Lock
);
711 receive_len
= midQ
->resp_buf
->smb_buf_length
;
713 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
714 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
720 /* rcvd frame is ok */
722 if (midQ
->resp_buf
&& out_buf
723 && (midQ
->midState
== MID_RESPONSE_RECEIVED
)) {
724 out_buf
->smb_buf_length
= receive_len
;
725 memcpy((char *)out_buf
+ 4,
726 (char *)midQ
->resp_buf
+ 4,
729 dump_smb(out_buf
, 92);
730 /* convert the length into a more usable form */
731 if ((receive_len
> 24) &&
732 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
733 SECMODE_SIGN_ENABLED
))) {
734 rc
= cifs_verify_signature(out_buf
,
735 &ses
->server
->mac_signing_key
,
736 midQ
->sequence_number
+1);
738 cERROR(1, ("Unexpected SMB signature"));
739 /* BB FIXME add code to kill session */
743 *pbytes_returned
= out_buf
->smb_buf_length
;
745 /* BB special case reconnect tid and uid here? */
746 rc
= map_smb_to_linux_error(out_buf
, 0 /* no log */ );
748 /* convert ByteCount if necessary */
749 if (receive_len
>= sizeof(struct smb_hdr
) - 4
750 /* do not count RFC1001 header */ +
751 (2 * out_buf
->WordCount
) + 2 /* bcc */ )
752 BCC(out_buf
) = le16_to_cpu(BCC_LE(out_buf
));
755 cERROR(1, ("Bad MID state?"));
759 DeleteMidQEntry(midQ
);
760 atomic_dec(&ses
->server
->inFlight
);
761 wake_up(&ses
->server
->request_q
);
766 /* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
769 send_nt_cancel(struct cifsTconInfo
*tcon
, struct smb_hdr
*in_buf
,
770 struct mid_q_entry
*midQ
)
773 struct cifsSesInfo
*ses
= tcon
->ses
;
774 __u16 mid
= in_buf
->Mid
;
776 header_assemble(in_buf
, SMB_COM_NT_CANCEL
, tcon
, 0);
778 mutex_lock(&ses
->server
->srv_mutex
);
779 rc
= cifs_sign_smb(in_buf
, ses
->server
, &midQ
->sequence_number
);
781 mutex_unlock(&ses
->server
->srv_mutex
);
784 rc
= smb_send(ses
->server
, in_buf
, in_buf
->smb_buf_length
);
785 mutex_unlock(&ses
->server
->srv_mutex
);
789 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
790 blocking lock to return. */
793 send_lock_cancel(const unsigned int xid
, struct cifsTconInfo
*tcon
,
794 struct smb_hdr
*in_buf
,
795 struct smb_hdr
*out_buf
)
798 struct cifsSesInfo
*ses
= tcon
->ses
;
799 LOCK_REQ
*pSMB
= (LOCK_REQ
*)in_buf
;
801 /* We just modify the current in_buf to change
802 the type of lock from LOCKING_ANDX_SHARED_LOCK
803 or LOCKING_ANDX_EXCLUSIVE_LOCK to
804 LOCKING_ANDX_CANCEL_LOCK. */
806 pSMB
->LockType
= LOCKING_ANDX_CANCEL_LOCK
|LOCKING_ANDX_LARGE_FILES
;
808 pSMB
->hdr
.Mid
= GetNextMid(ses
->server
);
810 return SendReceive(xid
, ses
, in_buf
, out_buf
,
811 &bytes_returned
, CIFS_STD_OP
);
815 SendReceiveBlockingLock(const unsigned int xid
, struct cifsTconInfo
*tcon
,
816 struct smb_hdr
*in_buf
, struct smb_hdr
*out_buf
,
817 int *pbytes_returned
)
821 unsigned int receive_len
;
822 struct mid_q_entry
*midQ
;
823 struct cifsSesInfo
*ses
;
825 if (tcon
== NULL
|| tcon
->ses
== NULL
) {
826 cERROR(1, ("Null smb session"));
831 if (ses
->server
== NULL
) {
832 cERROR(1, ("Null tcp session"));
836 if (ses
->server
->tcpStatus
== CifsExiting
)
839 /* Ensure that we do not send more than 50 overlapping requests
840 to the same server. We may make this configurable later or
843 if (in_buf
->smb_buf_length
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
- 4) {
844 cERROR(1, ("Illegal length, greater than maximum frame, %d",
845 in_buf
->smb_buf_length
));
849 rc
= wait_for_free_request(ses
, CIFS_BLOCKING_OP
);
853 /* make sure that we sign in the same order that we send on this socket
854 and avoid races inside tcp sendmsg code that could cause corruption
857 mutex_lock(&ses
->server
->srv_mutex
);
859 rc
= allocate_mid(ses
, in_buf
, &midQ
);
861 mutex_unlock(&ses
->server
->srv_mutex
);
865 rc
= cifs_sign_smb(in_buf
, ses
->server
, &midQ
->sequence_number
);
867 DeleteMidQEntry(midQ
);
868 mutex_unlock(&ses
->server
->srv_mutex
);
872 midQ
->midState
= MID_REQUEST_SUBMITTED
;
873 #ifdef CONFIG_CIFS_STATS2
874 atomic_inc(&ses
->server
->inSend
);
876 rc
= smb_send(ses
->server
, in_buf
, in_buf
->smb_buf_length
);
877 #ifdef CONFIG_CIFS_STATS2
878 atomic_dec(&ses
->server
->inSend
);
879 midQ
->when_sent
= jiffies
;
881 mutex_unlock(&ses
->server
->srv_mutex
);
884 DeleteMidQEntry(midQ
);
888 /* Wait for a reply - allow signals to interrupt. */
889 rc
= wait_event_interruptible(ses
->server
->response_q
,
890 (!(midQ
->midState
== MID_REQUEST_SUBMITTED
)) ||
891 ((ses
->server
->tcpStatus
!= CifsGood
) &&
892 (ses
->server
->tcpStatus
!= CifsNew
)));
894 /* Were we interrupted by a signal ? */
895 if ((rc
== -ERESTARTSYS
) &&
896 (midQ
->midState
== MID_REQUEST_SUBMITTED
) &&
897 ((ses
->server
->tcpStatus
== CifsGood
) ||
898 (ses
->server
->tcpStatus
== CifsNew
))) {
900 if (in_buf
->Command
== SMB_COM_TRANSACTION2
) {
901 /* POSIX lock. We send a NT_CANCEL SMB to cause the
902 blocking lock to return. */
904 rc
= send_nt_cancel(tcon
, in_buf
, midQ
);
906 DeleteMidQEntry(midQ
);
910 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
911 to cause the blocking lock to return. */
913 rc
= send_lock_cancel(xid
, tcon
, in_buf
, out_buf
);
915 /* If we get -ENOLCK back the lock may have
916 already been removed. Don't exit in this case. */
917 if (rc
&& rc
!= -ENOLCK
) {
918 DeleteMidQEntry(midQ
);
923 /* Wait 5 seconds for the response. */
924 if (wait_for_response(ses
, midQ
, 5 * HZ
, 5 * HZ
) == 0) {
925 /* We got the response - restart system call. */
930 spin_lock(&GlobalMid_Lock
);
931 if (midQ
->resp_buf
) {
932 spin_unlock(&GlobalMid_Lock
);
933 receive_len
= midQ
->resp_buf
->smb_buf_length
;
935 cERROR(1, ("No response for cmd %d mid %d",
936 midQ
->command
, midQ
->mid
));
937 if (midQ
->midState
== MID_REQUEST_SUBMITTED
) {
938 if (ses
->server
->tcpStatus
== CifsExiting
)
941 ses
->server
->tcpStatus
= CifsNeedReconnect
;
942 midQ
->midState
= MID_RETRY_NEEDED
;
946 if (rc
!= -EHOSTDOWN
) {
947 if (midQ
->midState
== MID_RETRY_NEEDED
) {
949 cFYI(1, ("marking request for retry"));
954 spin_unlock(&GlobalMid_Lock
);
955 DeleteMidQEntry(midQ
);
959 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
960 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
966 /* rcvd frame is ok */
968 if ((out_buf
== NULL
) || (midQ
->midState
!= MID_RESPONSE_RECEIVED
)) {
970 cERROR(1, ("Bad MID state?"));
974 out_buf
->smb_buf_length
= receive_len
;
975 memcpy((char *)out_buf
+ 4,
976 (char *)midQ
->resp_buf
+ 4,
979 dump_smb(out_buf
, 92);
980 /* convert the length into a more usable form */
981 if ((receive_len
> 24) &&
982 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
983 SECMODE_SIGN_ENABLED
))) {
984 rc
= cifs_verify_signature(out_buf
,
985 &ses
->server
->mac_signing_key
,
986 midQ
->sequence_number
+1);
988 cERROR(1, ("Unexpected SMB signature"));
989 /* BB FIXME add code to kill session */
993 *pbytes_returned
= out_buf
->smb_buf_length
;
995 /* BB special case reconnect tid and uid here? */
996 rc
= map_smb_to_linux_error(out_buf
, 0 /* no log */ );
998 /* convert ByteCount if necessary */
999 if (receive_len
>= sizeof(struct smb_hdr
) - 4
1000 /* do not count RFC1001 header */ +
1001 (2 * out_buf
->WordCount
) + 2 /* bcc */ )
1002 BCC(out_buf
) = le16_to_cpu(BCC_LE(out_buf
));
1005 DeleteMidQEntry(midQ
);
1006 if (rstart
&& rc
== -EACCES
)
1007 return -ERESTARTSYS
;