4 * Copyright (C) International Business Machines Corp., 2002,2005
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/list.h>
24 #include <linux/wait.h>
25 #include <linux/net.h>
26 #include <linux/delay.h>
27 #include <asm/uaccess.h>
28 #include <asm/processor.h>
29 #include <linux/mempool.h>
32 #include "cifsproto.h"
33 #include "cifs_debug.h"
35 extern mempool_t
*cifs_mid_poolp
;
36 extern kmem_cache_t
*cifs_oplock_cachep
;
38 static struct mid_q_entry
*
39 AllocMidQEntry(struct smb_hdr
*smb_buffer
, struct cifsSesInfo
*ses
)
41 struct mid_q_entry
*temp
;
44 cERROR(1, ("Null session passed in to AllocMidQEntry"));
47 if (ses
->server
== NULL
) {
48 cERROR(1, ("Null TCP session in AllocMidQEntry"));
52 temp
= (struct mid_q_entry
*) mempool_alloc(cifs_mid_poolp
,
53 SLAB_KERNEL
| SLAB_NOFS
);
57 memset(temp
, 0, sizeof (struct mid_q_entry
));
58 temp
->mid
= smb_buffer
->Mid
; /* always LE */
59 temp
->pid
= current
->pid
;
60 temp
->command
= smb_buffer
->Command
;
61 cFYI(1, ("For smb_command %d", temp
->command
));
62 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
63 /* when mid allocated can be before when sent */
64 temp
->when_alloc
= jiffies
;
69 spin_lock(&GlobalMid_Lock
);
70 list_add_tail(&temp
->qhead
, &ses
->server
->pending_mid_q
);
71 atomic_inc(&midCount
);
72 temp
->midState
= MID_REQUEST_ALLOCATED
;
73 spin_unlock(&GlobalMid_Lock
);
78 DeleteMidQEntry(struct mid_q_entry
*midEntry
)
80 #ifdef CONFIG_CIFS_STATS2
83 spin_lock(&GlobalMid_Lock
);
84 midEntry
->midState
= MID_FREE
;
85 list_del(&midEntry
->qhead
);
86 atomic_dec(&midCount
);
87 spin_unlock(&GlobalMid_Lock
);
88 if(midEntry
->largeBuf
)
89 cifs_buf_release(midEntry
->resp_buf
);
91 cifs_small_buf_release(midEntry
->resp_buf
);
92 #ifdef CONFIG_CIFS_STATS2
94 /* commands taking longer than one second are indications that
95 something is wrong, unless it is quite a slow link or server */
96 if((now
- midEntry
->when_alloc
) > HZ
) {
97 if((cifsFYI
& CIFS_TIMER
) &&
98 (midEntry
->command
!= SMB_COM_LOCKING_ANDX
)) {
99 printk(KERN_DEBUG
" CIFS slow rsp: cmd %d mid %d",
100 midEntry
->command
, midEntry
->mid
);
101 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
102 now
- midEntry
->when_alloc
,
103 now
- midEntry
->when_sent
,
104 now
- midEntry
->when_received
);
108 mempool_free(midEntry
, cifs_mid_poolp
);
111 struct oplock_q_entry
*
112 AllocOplockQEntry(struct inode
* pinode
, __u16 fid
, struct cifsTconInfo
* tcon
)
114 struct oplock_q_entry
*temp
;
115 if ((pinode
== NULL
) || (tcon
== NULL
)) {
116 cERROR(1, ("Null parms passed to AllocOplockQEntry"));
119 temp
= (struct oplock_q_entry
*) kmem_cache_alloc(cifs_oplock_cachep
,
124 temp
->pinode
= pinode
;
127 spin_lock(&GlobalMid_Lock
);
128 list_add_tail(&temp
->qhead
, &GlobalOplock_Q
);
129 spin_unlock(&GlobalMid_Lock
);
135 void DeleteOplockQEntry(struct oplock_q_entry
* oplockEntry
)
137 spin_lock(&GlobalMid_Lock
);
138 /* should we check if list empty first? */
139 list_del(&oplockEntry
->qhead
);
140 spin_unlock(&GlobalMid_Lock
);
141 kmem_cache_free(cifs_oplock_cachep
, oplockEntry
);
145 smb_send(struct socket
*ssocket
, struct smb_hdr
*smb_buffer
,
146 unsigned int smb_buf_length
, struct sockaddr
*sin
)
150 struct msghdr smb_msg
;
152 unsigned len
= smb_buf_length
+ 4;
155 return -ENOTSOCK
; /* BB eventually add reconnect code here */
156 iov
.iov_base
= smb_buffer
;
159 smb_msg
.msg_name
= sin
;
160 smb_msg
.msg_namelen
= sizeof (struct sockaddr
);
161 smb_msg
.msg_control
= NULL
;
162 smb_msg
.msg_controllen
= 0;
163 smb_msg
.msg_flags
= MSG_DONTWAIT
+ MSG_NOSIGNAL
; /* BB add more flags?*/
165 /* smb header is converted in header_assemble. bcc and rest of SMB word
166 area, and byte area if necessary, is converted to littleendian in
167 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
168 Flags2 is converted in SendReceive */
170 smb_buffer
->smb_buf_length
= cpu_to_be32(smb_buffer
->smb_buf_length
);
171 cFYI(1, ("Sending smb of length %d", smb_buf_length
));
172 dump_smb(smb_buffer
, len
);
175 rc
= kernel_sendmsg(ssocket
, &smb_msg
, &iov
, 1, len
);
176 if ((rc
== -ENOSPC
) || (rc
== -EAGAIN
)) {
178 /* smaller timeout here than send2 since smaller size */
179 /* Although it may not be required, this also is smaller
183 ("sends on sock %p stuck for 7 seconds",
194 i
= 0; /* reset i after each successful send */
201 cERROR(1,("Error %d sending data on socket to server", rc
));
210 smb_send2(struct socket
*ssocket
, struct kvec
*iov
, int n_vec
,
211 struct sockaddr
*sin
)
215 struct msghdr smb_msg
;
216 struct smb_hdr
*smb_buffer
= iov
[0].iov_base
;
217 unsigned int len
= iov
[0].iov_len
;
218 unsigned int total_len
;
222 return -ENOTSOCK
; /* BB eventually add reconnect code here */
224 smb_msg
.msg_name
= sin
;
225 smb_msg
.msg_namelen
= sizeof (struct sockaddr
);
226 smb_msg
.msg_control
= NULL
;
227 smb_msg
.msg_controllen
= 0;
228 smb_msg
.msg_flags
= MSG_DONTWAIT
+ MSG_NOSIGNAL
; /* BB add more flags?*/
230 /* smb header is converted in header_assemble. bcc and rest of SMB word
231 area, and byte area if necessary, is converted to littleendian in
232 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
233 Flags2 is converted in SendReceive */
237 for (i
= 0; i
< n_vec
; i
++)
238 total_len
+= iov
[i
].iov_len
;
240 smb_buffer
->smb_buf_length
= cpu_to_be32(smb_buffer
->smb_buf_length
);
241 cFYI(1, ("Sending smb: total_len %d", total_len
));
242 dump_smb(smb_buffer
, len
);
245 rc
= kernel_sendmsg(ssocket
, &smb_msg
, &iov
[first_vec
],
246 n_vec
- first_vec
, total_len
);
247 if ((rc
== -ENOSPC
) || (rc
== -EAGAIN
)) {
251 ("sends on sock %p stuck for 15 seconds",
262 if (rc
>= total_len
) {
263 WARN_ON(rc
> total_len
);
267 /* should never happen, letting socket clear before
268 retrying is our only obvious option here */
269 cERROR(1,("tcp sent no data"));
274 /* the line below resets i */
275 for (i
= first_vec
; i
< n_vec
; i
++) {
276 if (iov
[i
].iov_len
) {
277 if (rc
> iov
[i
].iov_len
) {
278 rc
-= iov
[i
].iov_len
;
281 iov
[i
].iov_base
+= rc
;
282 iov
[i
].iov_len
-= rc
;
288 i
= 0; /* in case we get ENOSPC on the next send */
292 cERROR(1,("Error %d sending data on socket to server", rc
));
300 SendReceive2(const unsigned int xid
, struct cifsSesInfo
*ses
,
301 struct kvec
*iov
, int n_vec
, int * pRespBufType
/* ret */,
305 unsigned int receive_len
;
306 unsigned long timeout
;
307 struct mid_q_entry
*midQ
;
308 struct smb_hdr
*in_buf
= iov
[0].iov_base
;
310 *pRespBufType
= CIFS_NO_BUFFER
; /* no response buf yet */
312 if ((ses
== NULL
) || (ses
->server
== NULL
)) {
313 cifs_small_buf_release(in_buf
);
314 cERROR(1,("Null session"));
318 if(ses
->server
->tcpStatus
== CifsExiting
) {
319 cifs_small_buf_release(in_buf
);
323 /* Ensure that we do not send more than 50 overlapping requests
324 to the same server. We may make this configurable later or
327 /* oplock breaks must not be held up */
328 atomic_inc(&ses
->server
->inFlight
);
330 spin_lock(&GlobalMid_Lock
);
332 if(atomic_read(&ses
->server
->inFlight
) >=
334 spin_unlock(&GlobalMid_Lock
);
335 #ifdef CONFIG_CIFS_STATS2
336 atomic_inc(&ses
->server
->num_waiters
);
338 wait_event(ses
->server
->request_q
,
339 atomic_read(&ses
->server
->inFlight
)
341 #ifdef CONFIG_CIFS_STATS2
342 atomic_dec(&ses
->server
->num_waiters
);
344 spin_lock(&GlobalMid_Lock
);
346 if(ses
->server
->tcpStatus
== CifsExiting
) {
347 spin_unlock(&GlobalMid_Lock
);
348 cifs_small_buf_release(in_buf
);
352 /* can not count locking commands against total since
353 they are allowed to block on server */
356 /* update # of requests on the wire to server */
357 atomic_inc(&ses
->server
->inFlight
);
359 spin_unlock(&GlobalMid_Lock
);
364 /* make sure that we sign in the same order that we send on this socket
365 and avoid races inside tcp sendmsg code that could cause corruption
368 down(&ses
->server
->tcpSem
);
370 if (ses
->server
->tcpStatus
== CifsExiting
) {
373 } else if (ses
->server
->tcpStatus
== CifsNeedReconnect
) {
374 cFYI(1,("tcp session dead - return to caller to retry"));
377 } else if (ses
->status
!= CifsGood
) {
378 /* check if SMB session is bad because we are setting it up */
379 if((in_buf
->Command
!= SMB_COM_SESSION_SETUP_ANDX
) &&
380 (in_buf
->Command
!= SMB_COM_NEGOTIATE
)) {
383 } /* else ok - we are setting up session */
385 midQ
= AllocMidQEntry(in_buf
, ses
);
387 up(&ses
->server
->tcpSem
);
388 cifs_small_buf_release(in_buf
);
389 /* If not lock req, update # of requests on wire to server */
391 atomic_dec(&ses
->server
->inFlight
);
392 wake_up(&ses
->server
->request_q
);
397 rc
= cifs_sign_smb2(iov
, n_vec
, ses
->server
, &midQ
->sequence_number
);
399 midQ
->midState
= MID_REQUEST_SUBMITTED
;
400 #ifdef CONFIG_CIFS_STATS2
401 atomic_inc(&ses
->server
->inSend
);
403 rc
= smb_send2(ses
->server
->ssocket
, iov
, n_vec
,
404 (struct sockaddr
*) &(ses
->server
->addr
.sockAddr
));
405 #ifdef CONFIG_CIFS_STATS2
406 atomic_dec(&ses
->server
->inSend
);
407 midQ
->when_sent
= jiffies
;
410 DeleteMidQEntry(midQ
);
411 up(&ses
->server
->tcpSem
);
412 cifs_small_buf_release(in_buf
);
413 /* If not lock req, update # of requests on wire to server */
415 atomic_dec(&ses
->server
->inFlight
);
416 wake_up(&ses
->server
->request_q
);
420 up(&ses
->server
->tcpSem
);
421 cifs_small_buf_release(in_buf
);
425 goto cifs_no_response_exit2
;
426 else if (long_op
== 2) /* writes past end of file can take loong time */
428 else if (long_op
== 1)
429 timeout
= 45 * HZ
; /* should be greater than
430 servers oplock break timeout (about 43 seconds) */
431 else if (long_op
> 2) {
432 timeout
= MAX_SCHEDULE_TIMEOUT
;
435 /* wait for 15 seconds or until woken up due to response arriving or
436 due to last connection to this server being unmounted */
437 if (signal_pending(current
)) {
438 /* if signal pending do not hold up user for full smb timeout
439 but we still give response a change to complete */
443 /* No user interrupts in wait - wreaks havoc with performance */
444 if(timeout
!= MAX_SCHEDULE_TIMEOUT
) {
446 wait_event(ses
->server
->response_q
,
447 (!(midQ
->midState
& MID_REQUEST_SUBMITTED
)) ||
448 time_after(jiffies
, timeout
) ||
449 ((ses
->server
->tcpStatus
!= CifsGood
) &&
450 (ses
->server
->tcpStatus
!= CifsNew
)));
452 wait_event(ses
->server
->response_q
,
453 (!(midQ
->midState
& MID_REQUEST_SUBMITTED
)) ||
454 ((ses
->server
->tcpStatus
!= CifsGood
) &&
455 (ses
->server
->tcpStatus
!= CifsNew
)));
458 spin_lock(&GlobalMid_Lock
);
459 if (midQ
->resp_buf
) {
460 spin_unlock(&GlobalMid_Lock
);
461 receive_len
= midQ
->resp_buf
->smb_buf_length
;
463 cERROR(1,("No response to cmd %d mid %d",
464 midQ
->command
, midQ
->mid
));
465 if(midQ
->midState
== MID_REQUEST_SUBMITTED
) {
466 if(ses
->server
->tcpStatus
== CifsExiting
)
469 ses
->server
->tcpStatus
= CifsNeedReconnect
;
470 midQ
->midState
= MID_RETRY_NEEDED
;
474 if (rc
!= -EHOSTDOWN
) {
475 if(midQ
->midState
== MID_RETRY_NEEDED
) {
477 cFYI(1,("marking request for retry"));
482 spin_unlock(&GlobalMid_Lock
);
483 DeleteMidQEntry(midQ
);
484 /* If not lock req, update # of requests on wire to server */
486 atomic_dec(&ses
->server
->inFlight
);
487 wake_up(&ses
->server
->request_q
);
492 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
493 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
496 } else { /* rcvd frame is ok */
497 if (midQ
->resp_buf
&&
498 (midQ
->midState
== MID_RESPONSE_RECEIVED
)) {
500 iov
[0].iov_base
= (char *)midQ
->resp_buf
;
502 *pRespBufType
= CIFS_LARGE_BUFFER
;
504 *pRespBufType
= CIFS_SMALL_BUFFER
;
505 iov
[0].iov_len
= receive_len
+ 4;
507 dump_smb(midQ
->resp_buf
, 80);
508 /* convert the length into a more usable form */
509 if((receive_len
> 24) &&
510 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
511 SECMODE_SIGN_ENABLED
))) {
512 rc
= cifs_verify_signature(midQ
->resp_buf
,
513 ses
->server
->mac_signing_key
,
514 midQ
->sequence_number
+1);
516 cERROR(1,("Unexpected SMB signature"));
517 /* BB FIXME add code to kill session */
521 /* BB special case reconnect tid and uid here? */
522 /* BB special case Errbadpassword and pwdexpired here */
523 rc
= map_smb_to_linux_error(midQ
->resp_buf
);
525 /* convert ByteCount if necessary */
527 sizeof (struct smb_hdr
) -
528 4 /* do not count RFC1001 header */ +
529 (2 * midQ
->resp_buf
->WordCount
) + 2 /* bcc */ )
530 BCC(midQ
->resp_buf
) =
531 le16_to_cpu(BCC_LE(midQ
->resp_buf
));
532 midQ
->resp_buf
= NULL
; /* mark it so will not be freed
533 by DeleteMidQEntry */
536 cFYI(1,("Bad MID state?"));
539 cifs_no_response_exit2
:
540 DeleteMidQEntry(midQ
);
543 atomic_dec(&ses
->server
->inFlight
);
544 wake_up(&ses
->server
->request_q
);
550 up(&ses
->server
->tcpSem
);
551 cifs_small_buf_release(in_buf
);
552 /* If not lock req, update # of requests on wire to server */
554 atomic_dec(&ses
->server
->inFlight
);
555 wake_up(&ses
->server
->request_q
);
562 SendReceive(const unsigned int xid
, struct cifsSesInfo
*ses
,
563 struct smb_hdr
*in_buf
, struct smb_hdr
*out_buf
,
564 int *pbytes_returned
, const int long_op
)
567 unsigned int receive_len
;
568 unsigned long timeout
;
569 struct mid_q_entry
*midQ
;
572 cERROR(1,("Null smb session"));
575 if(ses
->server
== NULL
) {
576 cERROR(1,("Null tcp session"));
580 if(ses
->server
->tcpStatus
== CifsExiting
)
583 /* Ensure that we do not send more than 50 overlapping requests
584 to the same server. We may make this configurable later or
587 /* oplock breaks must not be held up */
588 atomic_inc(&ses
->server
->inFlight
);
590 spin_lock(&GlobalMid_Lock
);
592 if(atomic_read(&ses
->server
->inFlight
) >=
594 spin_unlock(&GlobalMid_Lock
);
595 #ifdef CONFIG_CIFS_STATS2
596 atomic_inc(&ses
->server
->num_waiters
);
598 wait_event(ses
->server
->request_q
,
599 atomic_read(&ses
->server
->inFlight
)
601 #ifdef CONFIG_CIFS_STATS2
602 atomic_dec(&ses
->server
->num_waiters
);
604 spin_lock(&GlobalMid_Lock
);
606 if(ses
->server
->tcpStatus
== CifsExiting
) {
607 spin_unlock(&GlobalMid_Lock
);
611 /* can not count locking commands against total since
612 they are allowed to block on server */
615 /* update # of requests on the wire to server */
616 atomic_inc(&ses
->server
->inFlight
);
618 spin_unlock(&GlobalMid_Lock
);
623 /* make sure that we sign in the same order that we send on this socket
624 and avoid races inside tcp sendmsg code that could cause corruption
627 down(&ses
->server
->tcpSem
);
629 if (ses
->server
->tcpStatus
== CifsExiting
) {
632 } else if (ses
->server
->tcpStatus
== CifsNeedReconnect
) {
633 cFYI(1,("tcp session dead - return to caller to retry"));
636 } else if (ses
->status
!= CifsGood
) {
637 /* check if SMB session is bad because we are setting it up */
638 if((in_buf
->Command
!= SMB_COM_SESSION_SETUP_ANDX
) &&
639 (in_buf
->Command
!= SMB_COM_NEGOTIATE
)) {
642 } /* else ok - we are setting up session */
644 midQ
= AllocMidQEntry(in_buf
, ses
);
646 up(&ses
->server
->tcpSem
);
647 /* If not lock req, update # of requests on wire to server */
649 atomic_dec(&ses
->server
->inFlight
);
650 wake_up(&ses
->server
->request_q
);
655 if (in_buf
->smb_buf_length
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
- 4) {
656 up(&ses
->server
->tcpSem
);
658 ("Illegal length, greater than maximum frame, %d ",
659 in_buf
->smb_buf_length
));
660 DeleteMidQEntry(midQ
);
661 /* If not lock req, update # of requests on wire to server */
663 atomic_dec(&ses
->server
->inFlight
);
664 wake_up(&ses
->server
->request_q
);
669 rc
= cifs_sign_smb(in_buf
, ses
->server
, &midQ
->sequence_number
);
671 midQ
->midState
= MID_REQUEST_SUBMITTED
;
672 #ifdef CONFIG_CIFS_STATS2
673 atomic_inc(&ses
->server
->inSend
);
675 rc
= smb_send(ses
->server
->ssocket
, in_buf
, in_buf
->smb_buf_length
,
676 (struct sockaddr
*) &(ses
->server
->addr
.sockAddr
));
677 #ifdef CONFIG_CIFS_STATS2
678 atomic_dec(&ses
->server
->inSend
);
679 midQ
->when_sent
= jiffies
;
682 DeleteMidQEntry(midQ
);
683 up(&ses
->server
->tcpSem
);
684 /* If not lock req, update # of requests on wire to server */
686 atomic_dec(&ses
->server
->inFlight
);
687 wake_up(&ses
->server
->request_q
);
691 up(&ses
->server
->tcpSem
);
693 goto cifs_no_response_exit
;
694 else if (long_op
== 2) /* writes past end of file can take loong time */
696 else if (long_op
== 1)
697 timeout
= 45 * HZ
; /* should be greater than
698 servers oplock break timeout (about 43 seconds) */
699 else if (long_op
> 2) {
700 timeout
= MAX_SCHEDULE_TIMEOUT
;
703 /* wait for 15 seconds or until woken up due to response arriving or
704 due to last connection to this server being unmounted */
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 change to complete */
711 /* No user interrupts in wait - wreaks havoc with performance */
712 if(timeout
!= MAX_SCHEDULE_TIMEOUT
) {
714 wait_event(ses
->server
->response_q
,
715 (!(midQ
->midState
& MID_REQUEST_SUBMITTED
)) ||
716 time_after(jiffies
, timeout
) ||
717 ((ses
->server
->tcpStatus
!= CifsGood
) &&
718 (ses
->server
->tcpStatus
!= CifsNew
)));
720 wait_event(ses
->server
->response_q
,
721 (!(midQ
->midState
& MID_REQUEST_SUBMITTED
)) ||
722 ((ses
->server
->tcpStatus
!= CifsGood
) &&
723 (ses
->server
->tcpStatus
!= CifsNew
)));
726 spin_lock(&GlobalMid_Lock
);
727 if (midQ
->resp_buf
) {
728 spin_unlock(&GlobalMid_Lock
);
729 receive_len
= midQ
->resp_buf
->smb_buf_length
;
731 cERROR(1,("No response for cmd %d mid %d",
732 midQ
->command
, midQ
->mid
));
733 if(midQ
->midState
== MID_REQUEST_SUBMITTED
) {
734 if(ses
->server
->tcpStatus
== CifsExiting
)
737 ses
->server
->tcpStatus
= CifsNeedReconnect
;
738 midQ
->midState
= MID_RETRY_NEEDED
;
742 if (rc
!= -EHOSTDOWN
) {
743 if(midQ
->midState
== MID_RETRY_NEEDED
) {
745 cFYI(1,("marking request for retry"));
750 spin_unlock(&GlobalMid_Lock
);
751 DeleteMidQEntry(midQ
);
752 /* If not lock req, update # of requests on wire to server */
754 atomic_dec(&ses
->server
->inFlight
);
755 wake_up(&ses
->server
->request_q
);
760 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
761 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
764 } else { /* rcvd frame is ok */
766 if (midQ
->resp_buf
&& out_buf
767 && (midQ
->midState
== MID_RESPONSE_RECEIVED
)) {
768 out_buf
->smb_buf_length
= receive_len
;
769 memcpy((char *)out_buf
+ 4,
770 (char *)midQ
->resp_buf
+ 4,
773 dump_smb(out_buf
, 92);
774 /* convert the length into a more usable form */
775 if((receive_len
> 24) &&
776 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
777 SECMODE_SIGN_ENABLED
))) {
778 rc
= cifs_verify_signature(out_buf
,
779 ses
->server
->mac_signing_key
,
780 midQ
->sequence_number
+1);
782 cERROR(1,("Unexpected SMB signature"));
783 /* BB FIXME add code to kill session */
787 *pbytes_returned
= out_buf
->smb_buf_length
;
789 /* BB special case reconnect tid and uid here? */
790 rc
= map_smb_to_linux_error(out_buf
);
792 /* convert ByteCount if necessary */
794 sizeof (struct smb_hdr
) -
795 4 /* do not count RFC1001 header */ +
796 (2 * out_buf
->WordCount
) + 2 /* bcc */ )
797 BCC(out_buf
) = le16_to_cpu(BCC_LE(out_buf
));
800 cERROR(1,("Bad MID state?"));
803 cifs_no_response_exit
:
804 DeleteMidQEntry(midQ
);
807 atomic_dec(&ses
->server
->inFlight
);
808 wake_up(&ses
->server
->request_q
);
814 up(&ses
->server
->tcpSem
);
815 /* If not lock req, update # of requests on wire to server */
817 atomic_dec(&ses
->server
->inFlight
);
818 wake_up(&ses
->server
->request_q
);