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(&cifs_oplock_lock
);
123 list_add_tail(&temp
->qhead
, &cifs_oplock_list
);
124 spin_unlock(&cifs_oplock_lock
);
129 void DeleteOplockQEntry(struct oplock_q_entry
*oplockEntry
)
131 spin_lock(&cifs_oplock_lock
);
132 /* should we check if list empty first? */
133 list_del(&oplockEntry
->qhead
);
134 spin_unlock(&cifs_oplock_lock
);
135 kmem_cache_free(cifs_oplock_cachep
, oplockEntry
);
139 void DeleteTconOplockQEntries(struct cifsTconInfo
*tcon
)
141 struct oplock_q_entry
*temp
;
146 spin_lock(&cifs_oplock_lock
);
147 list_for_each_entry(temp
, &cifs_oplock_list
, qhead
) {
148 if ((temp
->tcon
) && (temp
->tcon
== tcon
)) {
149 list_del(&temp
->qhead
);
150 kmem_cache_free(cifs_oplock_cachep
, temp
);
153 spin_unlock(&cifs_oplock_lock
);
157 smb_sendv(struct TCP_Server_Info
*server
, struct kvec
*iov
, int n_vec
)
161 struct msghdr smb_msg
;
162 struct smb_hdr
*smb_buffer
= iov
[0].iov_base
;
163 unsigned int len
= iov
[0].iov_len
;
164 unsigned int total_len
;
166 unsigned int smb_buf_length
= smb_buffer
->smb_buf_length
;
167 struct socket
*ssocket
= server
->ssocket
;
170 return -ENOTSOCK
; /* BB eventually add reconnect code here */
172 smb_msg
.msg_name
= (struct sockaddr
*) &server
->addr
.sockAddr
;
173 smb_msg
.msg_namelen
= sizeof(struct sockaddr
);
174 smb_msg
.msg_control
= NULL
;
175 smb_msg
.msg_controllen
= 0;
176 if (server
->noblocksnd
)
177 smb_msg
.msg_flags
= MSG_DONTWAIT
+ MSG_NOSIGNAL
;
179 smb_msg
.msg_flags
= MSG_NOSIGNAL
;
181 /* smb header is converted in header_assemble. bcc and rest of SMB word
182 area, and byte area if necessary, is converted to littleendian in
183 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
184 Flags2 is converted in SendReceive */
188 for (i
= 0; i
< n_vec
; i
++)
189 total_len
+= iov
[i
].iov_len
;
191 smb_buffer
->smb_buf_length
= cpu_to_be32(smb_buffer
->smb_buf_length
);
192 cFYI(1, ("Sending smb: total_len %d", total_len
));
193 dump_smb(smb_buffer
, len
);
197 rc
= kernel_sendmsg(ssocket
, &smb_msg
, &iov
[first_vec
],
198 n_vec
- first_vec
, total_len
);
199 if ((rc
== -ENOSPC
) || (rc
== -EAGAIN
)) {
201 /* if blocking send we try 3 times, since each can block
202 for 5 seconds. For nonblocking we have to try more
203 but wait increasing amounts of time allowing time for
204 socket to clear. The overall time we wait in either
205 case to send on the socket is about 15 seconds.
206 Similarly we wait for 15 seconds for
207 a response from the server in SendReceive[2]
208 for the server to send a response back for
209 most types of requests (except SMB Write
210 past end of file which can be slow, and
211 blocking lock operations). NFS waits slightly longer
212 than CIFS, but this can make it take longer for
213 nonresponsive servers to be detected and 15 seconds
214 is more than enough time for modern networks to
215 send a packet. In most cases if we fail to send
216 after the retries we will kill the socket and
217 reconnect which may clear the network problem.
219 if ((i
>= 14) || (!server
->noblocksnd
&& (i
> 2))) {
221 ("sends on sock %p stuck for 15 seconds",
232 if (rc
== total_len
) {
235 } else if (rc
> total_len
) {
236 cERROR(1, ("sent %d requested %d", rc
, total_len
));
240 /* should never happen, letting socket clear before
241 retrying is our only obvious option here */
242 cERROR(1, ("tcp sent no data"));
247 /* the line below resets i */
248 for (i
= first_vec
; i
< n_vec
; i
++) {
249 if (iov
[i
].iov_len
) {
250 if (rc
> iov
[i
].iov_len
) {
251 rc
-= iov
[i
].iov_len
;
254 iov
[i
].iov_base
+= rc
;
255 iov
[i
].iov_len
-= rc
;
261 i
= 0; /* in case we get ENOSPC on the next send */
264 if ((total_len
> 0) && (total_len
!= smb_buf_length
+ 4)) {
265 cFYI(1, ("partial send (%d remaining), terminating session",
267 /* If we have only sent part of an SMB then the next SMB
268 could be taken as the remainder of this one. We need
269 to kill the socket so the server throws away the partial
271 server
->tcpStatus
= CifsNeedReconnect
;
275 cERROR(1, ("Error %d sending data on socket to server", rc
));
279 /* Don't want to modify the buffer as a
280 side effect of this call. */
281 smb_buffer
->smb_buf_length
= smb_buf_length
;
287 smb_send(struct TCP_Server_Info
*server
, struct smb_hdr
*smb_buffer
,
288 unsigned int smb_buf_length
)
292 iov
.iov_base
= smb_buffer
;
293 iov
.iov_len
= smb_buf_length
+ 4;
295 return smb_sendv(server
, &iov
, 1);
298 static int wait_for_free_request(struct cifsSesInfo
*ses
, const int long_op
)
300 if (long_op
== CIFS_ASYNC_OP
) {
301 /* oplock breaks must not be held up */
302 atomic_inc(&ses
->server
->inFlight
);
306 spin_lock(&GlobalMid_Lock
);
308 if (atomic_read(&ses
->server
->inFlight
) >=
310 spin_unlock(&GlobalMid_Lock
);
311 #ifdef CONFIG_CIFS_STATS2
312 atomic_inc(&ses
->server
->num_waiters
);
314 wait_event(ses
->server
->request_q
,
315 atomic_read(&ses
->server
->inFlight
)
317 #ifdef CONFIG_CIFS_STATS2
318 atomic_dec(&ses
->server
->num_waiters
);
320 spin_lock(&GlobalMid_Lock
);
322 if (ses
->server
->tcpStatus
== CifsExiting
) {
323 spin_unlock(&GlobalMid_Lock
);
327 /* can not count locking commands against total
328 as they are allowed to block on server */
330 /* update # of requests on the wire to server */
331 if (long_op
!= CIFS_BLOCKING_OP
)
332 atomic_inc(&ses
->server
->inFlight
);
333 spin_unlock(&GlobalMid_Lock
);
340 static int allocate_mid(struct cifsSesInfo
*ses
, struct smb_hdr
*in_buf
,
341 struct mid_q_entry
**ppmidQ
)
343 if (ses
->server
->tcpStatus
== CifsExiting
) {
347 if (ses
->server
->tcpStatus
== CifsNeedReconnect
) {
348 cFYI(1, ("tcp session dead - return to caller to retry"));
352 if (ses
->status
!= CifsGood
) {
353 /* check if SMB session is bad because we are setting it up */
354 if ((in_buf
->Command
!= SMB_COM_SESSION_SETUP_ANDX
) &&
355 (in_buf
->Command
!= SMB_COM_NEGOTIATE
))
357 /* else ok - we are setting up session */
359 *ppmidQ
= AllocMidQEntry(in_buf
, ses
->server
);
365 static int wait_for_response(struct cifsSesInfo
*ses
,
366 struct mid_q_entry
*midQ
,
367 unsigned long timeout
,
368 unsigned long time_to_wait
)
370 unsigned long curr_timeout
;
373 curr_timeout
= timeout
+ jiffies
;
374 wait_event_timeout(ses
->server
->response_q
,
375 midQ
->midState
!= MID_REQUEST_SUBMITTED
, timeout
);
377 if (time_after(jiffies
, curr_timeout
) &&
378 (midQ
->midState
== MID_REQUEST_SUBMITTED
) &&
379 ((ses
->server
->tcpStatus
== CifsGood
) ||
380 (ses
->server
->tcpStatus
== CifsNew
))) {
384 /* We timed out. Is the server still
386 spin_lock(&GlobalMid_Lock
);
387 lrt
= ses
->server
->lstrp
;
388 spin_unlock(&GlobalMid_Lock
);
390 /* Calculate time_to_wait past last receive time.
391 Although we prefer not to time out if the
392 server is still responding - we will time
393 out if the server takes more than 15 (or 45
394 or 180) seconds to respond to this request
395 and has not responded to any request from
396 other threads on the client within 10 seconds */
398 if (time_after(jiffies
, lrt
)) {
399 /* No replies for time_to_wait. */
400 cERROR(1, ("server not responding"));
412 * Send an SMB Request. No response info (other than return code)
413 * needs to be parsed.
415 * flags indicate the type of request buffer and how long to wait
416 * and whether to log NT STATUS code (error) before mapping it to POSIX error
420 SendReceiveNoRsp(const unsigned int xid
, struct cifsSesInfo
*ses
,
421 struct smb_hdr
*in_buf
, int flags
)
427 iov
[0].iov_base
= (char *)in_buf
;
428 iov
[0].iov_len
= in_buf
->smb_buf_length
+ 4;
429 flags
|= CIFS_NO_RESP
;
430 rc
= SendReceive2(xid
, ses
, iov
, 1, &resp_buf_type
, flags
);
431 cFYI(DBG2
, ("SendRcvNoRsp flags %d rc %d", flags
, rc
));
437 SendReceive2(const unsigned int xid
, struct cifsSesInfo
*ses
,
438 struct kvec
*iov
, int n_vec
, int *pRespBufType
/* ret */,
443 unsigned int receive_len
;
444 unsigned long timeout
;
445 struct mid_q_entry
*midQ
;
446 struct smb_hdr
*in_buf
= iov
[0].iov_base
;
448 long_op
= flags
& CIFS_TIMEOUT_MASK
;
450 *pRespBufType
= CIFS_NO_BUFFER
; /* no response buf yet */
452 if ((ses
== NULL
) || (ses
->server
== NULL
)) {
453 cifs_small_buf_release(in_buf
);
454 cERROR(1, ("Null session"));
458 if (ses
->server
->tcpStatus
== CifsExiting
) {
459 cifs_small_buf_release(in_buf
);
463 /* Ensure that we do not send more than 50 overlapping requests
464 to the same server. We may make this configurable later or
467 rc
= wait_for_free_request(ses
, long_op
);
469 cifs_small_buf_release(in_buf
);
473 /* make sure that we sign in the same order that we send on this socket
474 and avoid races inside tcp sendmsg code that could cause corruption
477 mutex_lock(&ses
->server
->srv_mutex
);
479 rc
= allocate_mid(ses
, in_buf
, &midQ
);
481 mutex_unlock(&ses
->server
->srv_mutex
);
482 cifs_small_buf_release(in_buf
);
483 /* Update # of requests on wire to server */
484 atomic_dec(&ses
->server
->inFlight
);
485 wake_up(&ses
->server
->request_q
);
488 rc
= cifs_sign_smb2(iov
, n_vec
, ses
->server
, &midQ
->sequence_number
);
490 mutex_unlock(&ses
->server
->srv_mutex
);
491 cifs_small_buf_release(in_buf
);
495 midQ
->midState
= MID_REQUEST_SUBMITTED
;
496 #ifdef CONFIG_CIFS_STATS2
497 atomic_inc(&ses
->server
->inSend
);
499 rc
= smb_sendv(ses
->server
, iov
, n_vec
);
500 #ifdef CONFIG_CIFS_STATS2
501 atomic_dec(&ses
->server
->inSend
);
502 midQ
->when_sent
= jiffies
;
505 mutex_unlock(&ses
->server
->srv_mutex
);
506 cifs_small_buf_release(in_buf
);
511 if (long_op
== CIFS_STD_OP
)
513 else if (long_op
== CIFS_VLONG_OP
) /* e.g. slow writes past EOF */
515 else if (long_op
== CIFS_LONG_OP
)
516 timeout
= 45 * HZ
; /* should be greater than
517 servers oplock break timeout (about 43 seconds) */
518 else if (long_op
== CIFS_ASYNC_OP
)
520 else if (long_op
== CIFS_BLOCKING_OP
)
521 timeout
= 0x7FFFFFFF; /* large, but not so large as to wrap */
523 cERROR(1, ("unknown timeout flag %d", long_op
));
528 /* wait for 15 seconds or until woken up due to response arriving or
529 due to last connection to this server being unmounted */
530 if (signal_pending(current
)) {
531 /* if signal pending do not hold up user for full smb timeout
532 but we still give response a chance to complete */
536 /* No user interrupts in wait - wreaks havoc with performance */
537 wait_for_response(ses
, midQ
, timeout
, 10 * HZ
);
539 spin_lock(&GlobalMid_Lock
);
541 if (midQ
->resp_buf
== NULL
) {
542 cERROR(1, ("No response to cmd %d mid %d",
543 midQ
->command
, midQ
->mid
));
544 if (midQ
->midState
== MID_REQUEST_SUBMITTED
) {
545 if (ses
->server
->tcpStatus
== CifsExiting
)
548 ses
->server
->tcpStatus
= CifsNeedReconnect
;
549 midQ
->midState
= MID_RETRY_NEEDED
;
553 if (rc
!= -EHOSTDOWN
) {
554 if (midQ
->midState
== MID_RETRY_NEEDED
) {
556 cFYI(1, ("marking request for retry"));
561 spin_unlock(&GlobalMid_Lock
);
562 DeleteMidQEntry(midQ
);
563 /* Update # of requests on wire to server */
564 atomic_dec(&ses
->server
->inFlight
);
565 wake_up(&ses
->server
->request_q
);
569 spin_unlock(&GlobalMid_Lock
);
570 receive_len
= midQ
->resp_buf
->smb_buf_length
;
572 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
573 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
579 /* rcvd frame is ok */
581 if (midQ
->resp_buf
&&
582 (midQ
->midState
== MID_RESPONSE_RECEIVED
)) {
584 iov
[0].iov_base
= (char *)midQ
->resp_buf
;
586 *pRespBufType
= CIFS_LARGE_BUFFER
;
588 *pRespBufType
= CIFS_SMALL_BUFFER
;
589 iov
[0].iov_len
= receive_len
+ 4;
591 dump_smb(midQ
->resp_buf
, 80);
592 /* convert the length into a more usable form */
593 if ((receive_len
> 24) &&
594 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
595 SECMODE_SIGN_ENABLED
))) {
596 rc
= cifs_verify_signature(midQ
->resp_buf
,
597 &ses
->server
->mac_signing_key
,
598 midQ
->sequence_number
+1);
600 cERROR(1, ("Unexpected SMB signature"));
601 /* BB FIXME add code to kill session */
605 /* BB special case reconnect tid and uid here? */
606 rc
= map_smb_to_linux_error(midQ
->resp_buf
,
607 flags
& CIFS_LOG_ERROR
);
609 /* convert ByteCount if necessary */
610 if (receive_len
>= sizeof(struct smb_hdr
) - 4
611 /* do not count RFC1001 header */ +
612 (2 * midQ
->resp_buf
->WordCount
) + 2 /* bcc */ )
613 BCC(midQ
->resp_buf
) =
614 le16_to_cpu(BCC_LE(midQ
->resp_buf
));
615 if ((flags
& CIFS_NO_RESP
) == 0)
616 midQ
->resp_buf
= NULL
; /* mark it so buf will
621 cFYI(1, ("Bad MID state?"));
625 DeleteMidQEntry(midQ
);
626 atomic_dec(&ses
->server
->inFlight
);
627 wake_up(&ses
->server
->request_q
);
633 SendReceive(const unsigned int xid
, struct cifsSesInfo
*ses
,
634 struct smb_hdr
*in_buf
, struct smb_hdr
*out_buf
,
635 int *pbytes_returned
, const int long_op
)
638 unsigned int receive_len
;
639 unsigned long timeout
;
640 struct mid_q_entry
*midQ
;
643 cERROR(1, ("Null smb session"));
646 if (ses
->server
== NULL
) {
647 cERROR(1, ("Null tcp session"));
651 if (ses
->server
->tcpStatus
== CifsExiting
)
654 /* Ensure that we do not send more than 50 overlapping requests
655 to the same server. We may make this configurable later or
658 if (in_buf
->smb_buf_length
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
- 4) {
659 cERROR(1, ("Illegal length, greater than maximum frame, %d",
660 in_buf
->smb_buf_length
));
664 rc
= wait_for_free_request(ses
, long_op
);
668 /* make sure that we sign in the same order that we send on this socket
669 and avoid races inside tcp sendmsg code that could cause corruption
672 mutex_lock(&ses
->server
->srv_mutex
);
674 rc
= allocate_mid(ses
, in_buf
, &midQ
);
676 mutex_unlock(&ses
->server
->srv_mutex
);
677 /* Update # of requests on wire to server */
678 atomic_dec(&ses
->server
->inFlight
);
679 wake_up(&ses
->server
->request_q
);
683 rc
= cifs_sign_smb(in_buf
, ses
->server
, &midQ
->sequence_number
);
685 mutex_unlock(&ses
->server
->srv_mutex
);
689 midQ
->midState
= MID_REQUEST_SUBMITTED
;
690 #ifdef CONFIG_CIFS_STATS2
691 atomic_inc(&ses
->server
->inSend
);
693 rc
= smb_send(ses
->server
, in_buf
, in_buf
->smb_buf_length
);
694 #ifdef CONFIG_CIFS_STATS2
695 atomic_dec(&ses
->server
->inSend
);
696 midQ
->when_sent
= jiffies
;
698 mutex_unlock(&ses
->server
->srv_mutex
);
703 if (long_op
== CIFS_STD_OP
)
705 /* wait for 15 seconds or until woken up due to response arriving or
706 due to last connection to this server being unmounted */
707 else if (long_op
== CIFS_ASYNC_OP
)
709 else if (long_op
== CIFS_VLONG_OP
) /* writes past EOF can be slow */
711 else if (long_op
== CIFS_LONG_OP
)
712 timeout
= 45 * HZ
; /* should be greater than
713 servers oplock break timeout (about 43 seconds) */
714 else if (long_op
== CIFS_BLOCKING_OP
)
715 timeout
= 0x7FFFFFFF; /* large but no so large as to wrap */
717 cERROR(1, ("unknown timeout flag %d", long_op
));
722 if (signal_pending(current
)) {
723 /* if signal pending do not hold up user for full smb timeout
724 but we still give response a chance to complete */
728 /* No user interrupts in wait - wreaks havoc with performance */
729 wait_for_response(ses
, midQ
, timeout
, 10 * HZ
);
731 spin_lock(&GlobalMid_Lock
);
732 if (midQ
->resp_buf
== NULL
) {
733 cERROR(1, ("No response for cmd %d mid %d",
734 midQ
->command
, midQ
->mid
));
735 if (midQ
->midState
== MID_REQUEST_SUBMITTED
) {
736 if (ses
->server
->tcpStatus
== CifsExiting
)
739 ses
->server
->tcpStatus
= CifsNeedReconnect
;
740 midQ
->midState
= MID_RETRY_NEEDED
;
744 if (rc
!= -EHOSTDOWN
) {
745 if (midQ
->midState
== MID_RETRY_NEEDED
) {
747 cFYI(1, ("marking request for retry"));
752 spin_unlock(&GlobalMid_Lock
);
753 DeleteMidQEntry(midQ
);
754 /* Update # of requests on wire to server */
755 atomic_dec(&ses
->server
->inFlight
);
756 wake_up(&ses
->server
->request_q
);
760 spin_unlock(&GlobalMid_Lock
);
761 receive_len
= midQ
->resp_buf
->smb_buf_length
;
763 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
764 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
770 /* rcvd frame is ok */
772 if (midQ
->resp_buf
&& out_buf
773 && (midQ
->midState
== MID_RESPONSE_RECEIVED
)) {
774 out_buf
->smb_buf_length
= receive_len
;
775 memcpy((char *)out_buf
+ 4,
776 (char *)midQ
->resp_buf
+ 4,
779 dump_smb(out_buf
, 92);
780 /* convert the length into a more usable form */
781 if ((receive_len
> 24) &&
782 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
783 SECMODE_SIGN_ENABLED
))) {
784 rc
= cifs_verify_signature(out_buf
,
785 &ses
->server
->mac_signing_key
,
786 midQ
->sequence_number
+1);
788 cERROR(1, ("Unexpected SMB signature"));
789 /* BB FIXME add code to kill session */
793 *pbytes_returned
= out_buf
->smb_buf_length
;
795 /* BB special case reconnect tid and uid here? */
796 rc
= map_smb_to_linux_error(out_buf
, 0 /* no log */ );
798 /* convert ByteCount if necessary */
799 if (receive_len
>= sizeof(struct smb_hdr
) - 4
800 /* do not count RFC1001 header */ +
801 (2 * out_buf
->WordCount
) + 2 /* bcc */ )
802 BCC(out_buf
) = le16_to_cpu(BCC_LE(out_buf
));
805 cERROR(1, ("Bad MID state?"));
809 DeleteMidQEntry(midQ
);
810 atomic_dec(&ses
->server
->inFlight
);
811 wake_up(&ses
->server
->request_q
);
816 /* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
819 send_nt_cancel(struct cifsTconInfo
*tcon
, struct smb_hdr
*in_buf
,
820 struct mid_q_entry
*midQ
)
823 struct cifsSesInfo
*ses
= tcon
->ses
;
824 __u16 mid
= in_buf
->Mid
;
826 header_assemble(in_buf
, SMB_COM_NT_CANCEL
, tcon
, 0);
828 mutex_lock(&ses
->server
->srv_mutex
);
829 rc
= cifs_sign_smb(in_buf
, ses
->server
, &midQ
->sequence_number
);
831 mutex_unlock(&ses
->server
->srv_mutex
);
834 rc
= smb_send(ses
->server
, in_buf
, in_buf
->smb_buf_length
);
835 mutex_unlock(&ses
->server
->srv_mutex
);
839 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
840 blocking lock to return. */
843 send_lock_cancel(const unsigned int xid
, struct cifsTconInfo
*tcon
,
844 struct smb_hdr
*in_buf
,
845 struct smb_hdr
*out_buf
)
848 struct cifsSesInfo
*ses
= tcon
->ses
;
849 LOCK_REQ
*pSMB
= (LOCK_REQ
*)in_buf
;
851 /* We just modify the current in_buf to change
852 the type of lock from LOCKING_ANDX_SHARED_LOCK
853 or LOCKING_ANDX_EXCLUSIVE_LOCK to
854 LOCKING_ANDX_CANCEL_LOCK. */
856 pSMB
->LockType
= LOCKING_ANDX_CANCEL_LOCK
|LOCKING_ANDX_LARGE_FILES
;
858 pSMB
->hdr
.Mid
= GetNextMid(ses
->server
);
860 return SendReceive(xid
, ses
, in_buf
, out_buf
,
861 &bytes_returned
, CIFS_STD_OP
);
865 SendReceiveBlockingLock(const unsigned int xid
, struct cifsTconInfo
*tcon
,
866 struct smb_hdr
*in_buf
, struct smb_hdr
*out_buf
,
867 int *pbytes_returned
)
871 unsigned int receive_len
;
872 struct mid_q_entry
*midQ
;
873 struct cifsSesInfo
*ses
;
875 if (tcon
== NULL
|| tcon
->ses
== NULL
) {
876 cERROR(1, ("Null smb session"));
881 if (ses
->server
== NULL
) {
882 cERROR(1, ("Null tcp session"));
886 if (ses
->server
->tcpStatus
== CifsExiting
)
889 /* Ensure that we do not send more than 50 overlapping requests
890 to the same server. We may make this configurable later or
893 if (in_buf
->smb_buf_length
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
- 4) {
894 cERROR(1, ("Illegal length, greater than maximum frame, %d",
895 in_buf
->smb_buf_length
));
899 rc
= wait_for_free_request(ses
, CIFS_BLOCKING_OP
);
903 /* make sure that we sign in the same order that we send on this socket
904 and avoid races inside tcp sendmsg code that could cause corruption
907 mutex_lock(&ses
->server
->srv_mutex
);
909 rc
= allocate_mid(ses
, in_buf
, &midQ
);
911 mutex_unlock(&ses
->server
->srv_mutex
);
915 rc
= cifs_sign_smb(in_buf
, ses
->server
, &midQ
->sequence_number
);
917 DeleteMidQEntry(midQ
);
918 mutex_unlock(&ses
->server
->srv_mutex
);
922 midQ
->midState
= MID_REQUEST_SUBMITTED
;
923 #ifdef CONFIG_CIFS_STATS2
924 atomic_inc(&ses
->server
->inSend
);
926 rc
= smb_send(ses
->server
, in_buf
, in_buf
->smb_buf_length
);
927 #ifdef CONFIG_CIFS_STATS2
928 atomic_dec(&ses
->server
->inSend
);
929 midQ
->when_sent
= jiffies
;
931 mutex_unlock(&ses
->server
->srv_mutex
);
934 DeleteMidQEntry(midQ
);
938 /* Wait for a reply - allow signals to interrupt. */
939 rc
= wait_event_interruptible(ses
->server
->response_q
,
940 (!(midQ
->midState
== MID_REQUEST_SUBMITTED
)) ||
941 ((ses
->server
->tcpStatus
!= CifsGood
) &&
942 (ses
->server
->tcpStatus
!= CifsNew
)));
944 /* Were we interrupted by a signal ? */
945 if ((rc
== -ERESTARTSYS
) &&
946 (midQ
->midState
== MID_REQUEST_SUBMITTED
) &&
947 ((ses
->server
->tcpStatus
== CifsGood
) ||
948 (ses
->server
->tcpStatus
== CifsNew
))) {
950 if (in_buf
->Command
== SMB_COM_TRANSACTION2
) {
951 /* POSIX lock. We send a NT_CANCEL SMB to cause the
952 blocking lock to return. */
954 rc
= send_nt_cancel(tcon
, in_buf
, midQ
);
956 DeleteMidQEntry(midQ
);
960 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
961 to cause the blocking lock to return. */
963 rc
= send_lock_cancel(xid
, tcon
, in_buf
, out_buf
);
965 /* If we get -ENOLCK back the lock may have
966 already been removed. Don't exit in this case. */
967 if (rc
&& rc
!= -ENOLCK
) {
968 DeleteMidQEntry(midQ
);
973 /* Wait 5 seconds for the response. */
974 if (wait_for_response(ses
, midQ
, 5 * HZ
, 5 * HZ
) == 0) {
975 /* We got the response - restart system call. */
980 spin_lock(&GlobalMid_Lock
);
981 if (midQ
->resp_buf
) {
982 spin_unlock(&GlobalMid_Lock
);
983 receive_len
= midQ
->resp_buf
->smb_buf_length
;
985 cERROR(1, ("No response for cmd %d mid %d",
986 midQ
->command
, midQ
->mid
));
987 if (midQ
->midState
== MID_REQUEST_SUBMITTED
) {
988 if (ses
->server
->tcpStatus
== CifsExiting
)
991 ses
->server
->tcpStatus
= CifsNeedReconnect
;
992 midQ
->midState
= MID_RETRY_NEEDED
;
996 if (rc
!= -EHOSTDOWN
) {
997 if (midQ
->midState
== MID_RETRY_NEEDED
) {
999 cFYI(1, ("marking request for retry"));
1004 spin_unlock(&GlobalMid_Lock
);
1005 DeleteMidQEntry(midQ
);
1009 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
1010 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
1016 /* rcvd frame is ok */
1018 if ((out_buf
== NULL
) || (midQ
->midState
!= MID_RESPONSE_RECEIVED
)) {
1020 cERROR(1, ("Bad MID state?"));
1024 out_buf
->smb_buf_length
= receive_len
;
1025 memcpy((char *)out_buf
+ 4,
1026 (char *)midQ
->resp_buf
+ 4,
1029 dump_smb(out_buf
, 92);
1030 /* convert the length into a more usable form */
1031 if ((receive_len
> 24) &&
1032 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
1033 SECMODE_SIGN_ENABLED
))) {
1034 rc
= cifs_verify_signature(out_buf
,
1035 &ses
->server
->mac_signing_key
,
1036 midQ
->sequence_number
+1);
1038 cERROR(1, ("Unexpected SMB signature"));
1039 /* BB FIXME add code to kill session */
1043 *pbytes_returned
= out_buf
->smb_buf_length
;
1045 /* BB special case reconnect tid and uid here? */
1046 rc
= map_smb_to_linux_error(out_buf
, 0 /* no log */ );
1048 /* convert ByteCount if necessary */
1049 if (receive_len
>= sizeof(struct smb_hdr
) - 4
1050 /* do not count RFC1001 header */ +
1051 (2 * out_buf
->WordCount
) + 2 /* bcc */ )
1052 BCC(out_buf
) = le16_to_cpu(BCC_LE(out_buf
));
1055 DeleteMidQEntry(midQ
);
1056 if (rstart
&& rc
== -EACCES
)
1057 return -ERESTARTSYS
;