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 time_after(jiffies
, ses
->server
->lstrp
+ HZ
)) ||
450 ((ses
->server
->tcpStatus
!= CifsGood
) &&
451 (ses
->server
->tcpStatus
!= CifsNew
)));
453 wait_event(ses
->server
->response_q
,
454 (!(midQ
->midState
& MID_REQUEST_SUBMITTED
)) ||
455 ((ses
->server
->tcpStatus
!= CifsGood
) &&
456 (ses
->server
->tcpStatus
!= CifsNew
)));
459 spin_lock(&GlobalMid_Lock
);
460 if (midQ
->resp_buf
) {
461 spin_unlock(&GlobalMid_Lock
);
462 receive_len
= midQ
->resp_buf
->smb_buf_length
;
464 cERROR(1,("No response to cmd %d mid %d",
465 midQ
->command
, midQ
->mid
));
466 if(midQ
->midState
== MID_REQUEST_SUBMITTED
) {
467 if(ses
->server
->tcpStatus
== CifsExiting
)
470 ses
->server
->tcpStatus
= CifsNeedReconnect
;
471 midQ
->midState
= MID_RETRY_NEEDED
;
475 if (rc
!= -EHOSTDOWN
) {
476 if(midQ
->midState
== MID_RETRY_NEEDED
) {
478 cFYI(1,("marking request for retry"));
483 spin_unlock(&GlobalMid_Lock
);
484 DeleteMidQEntry(midQ
);
485 /* If not lock req, update # of requests on wire to server */
487 atomic_dec(&ses
->server
->inFlight
);
488 wake_up(&ses
->server
->request_q
);
493 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
494 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
497 } else { /* rcvd frame is ok */
498 if (midQ
->resp_buf
&&
499 (midQ
->midState
== MID_RESPONSE_RECEIVED
)) {
501 iov
[0].iov_base
= (char *)midQ
->resp_buf
;
503 *pRespBufType
= CIFS_LARGE_BUFFER
;
505 *pRespBufType
= CIFS_SMALL_BUFFER
;
506 iov
[0].iov_len
= receive_len
+ 4;
508 dump_smb(midQ
->resp_buf
, 80);
509 /* convert the length into a more usable form */
510 if((receive_len
> 24) &&
511 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
512 SECMODE_SIGN_ENABLED
))) {
513 rc
= cifs_verify_signature(midQ
->resp_buf
,
514 ses
->server
->mac_signing_key
,
515 midQ
->sequence_number
+1);
517 cERROR(1,("Unexpected SMB signature"));
518 /* BB FIXME add code to kill session */
522 /* BB special case reconnect tid and uid here? */
523 /* BB special case Errbadpassword and pwdexpired here */
524 rc
= map_smb_to_linux_error(midQ
->resp_buf
);
526 /* convert ByteCount if necessary */
528 sizeof (struct smb_hdr
) -
529 4 /* do not count RFC1001 header */ +
530 (2 * midQ
->resp_buf
->WordCount
) + 2 /* bcc */ )
531 BCC(midQ
->resp_buf
) =
532 le16_to_cpu(BCC_LE(midQ
->resp_buf
));
533 midQ
->resp_buf
= NULL
; /* mark it so will not be freed
534 by DeleteMidQEntry */
537 cFYI(1,("Bad MID state?"));
540 cifs_no_response_exit2
:
541 DeleteMidQEntry(midQ
);
544 atomic_dec(&ses
->server
->inFlight
);
545 wake_up(&ses
->server
->request_q
);
551 up(&ses
->server
->tcpSem
);
552 cifs_small_buf_release(in_buf
);
553 /* If not lock req, update # of requests on wire to server */
555 atomic_dec(&ses
->server
->inFlight
);
556 wake_up(&ses
->server
->request_q
);
563 SendReceive(const unsigned int xid
, struct cifsSesInfo
*ses
,
564 struct smb_hdr
*in_buf
, struct smb_hdr
*out_buf
,
565 int *pbytes_returned
, const int long_op
)
568 unsigned int receive_len
;
569 unsigned long timeout
;
570 struct mid_q_entry
*midQ
;
573 cERROR(1,("Null smb session"));
576 if(ses
->server
== NULL
) {
577 cERROR(1,("Null tcp session"));
581 if(ses
->server
->tcpStatus
== CifsExiting
)
584 /* Ensure that we do not send more than 50 overlapping requests
585 to the same server. We may make this configurable later or
588 /* oplock breaks must not be held up */
589 atomic_inc(&ses
->server
->inFlight
);
591 spin_lock(&GlobalMid_Lock
);
593 if(atomic_read(&ses
->server
->inFlight
) >=
595 spin_unlock(&GlobalMid_Lock
);
596 #ifdef CONFIG_CIFS_STATS2
597 atomic_inc(&ses
->server
->num_waiters
);
599 wait_event(ses
->server
->request_q
,
600 atomic_read(&ses
->server
->inFlight
)
602 #ifdef CONFIG_CIFS_STATS2
603 atomic_dec(&ses
->server
->num_waiters
);
605 spin_lock(&GlobalMid_Lock
);
607 if(ses
->server
->tcpStatus
== CifsExiting
) {
608 spin_unlock(&GlobalMid_Lock
);
612 /* can not count locking commands against total since
613 they are allowed to block on server */
616 /* update # of requests on the wire to server */
617 atomic_inc(&ses
->server
->inFlight
);
619 spin_unlock(&GlobalMid_Lock
);
624 /* make sure that we sign in the same order that we send on this socket
625 and avoid races inside tcp sendmsg code that could cause corruption
628 down(&ses
->server
->tcpSem
);
630 if (ses
->server
->tcpStatus
== CifsExiting
) {
633 } else if (ses
->server
->tcpStatus
== CifsNeedReconnect
) {
634 cFYI(1,("tcp session dead - return to caller to retry"));
637 } else if (ses
->status
!= CifsGood
) {
638 /* check if SMB session is bad because we are setting it up */
639 if((in_buf
->Command
!= SMB_COM_SESSION_SETUP_ANDX
) &&
640 (in_buf
->Command
!= SMB_COM_NEGOTIATE
)) {
643 } /* else ok - we are setting up session */
645 midQ
= AllocMidQEntry(in_buf
, ses
);
647 up(&ses
->server
->tcpSem
);
648 /* If not lock req, update # of requests on wire to server */
650 atomic_dec(&ses
->server
->inFlight
);
651 wake_up(&ses
->server
->request_q
);
656 if (in_buf
->smb_buf_length
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
- 4) {
657 up(&ses
->server
->tcpSem
);
658 cERROR(1, ("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 /* although we prefer not to time out if the server is still
715 responding - we will time out if the server takes
716 more than 15 (or 45 or 180) seconds to respond to this request
717 and has not responded to any request from other threads
718 on this client within a second (note that it is not worth
719 grabbing the GlobalMid_Lock and slowing things down in this
720 wait event to more accurately check the lstrsp field on some
721 arch since we are already in an error path that will retry */
722 wait_event(ses
->server
->response_q
,
723 (!(midQ
->midState
& MID_REQUEST_SUBMITTED
)) ||
724 (time_after(jiffies
, timeout
) &&
725 time_after(jiffies
, ses
->server
->lstrp
+ HZ
)) ||
726 ((ses
->server
->tcpStatus
!= CifsGood
) &&
727 (ses
->server
->tcpStatus
!= CifsNew
)));
729 wait_event(ses
->server
->response_q
,
730 (!(midQ
->midState
& MID_REQUEST_SUBMITTED
)) ||
731 ((ses
->server
->tcpStatus
!= CifsGood
) &&
732 (ses
->server
->tcpStatus
!= CifsNew
)));
735 spin_lock(&GlobalMid_Lock
);
736 if (midQ
->resp_buf
) {
737 spin_unlock(&GlobalMid_Lock
);
738 receive_len
= midQ
->resp_buf
->smb_buf_length
;
740 cERROR(1,("No response for cmd %d mid %d",
741 midQ
->command
, midQ
->mid
));
742 if(midQ
->midState
== MID_REQUEST_SUBMITTED
) {
743 if(ses
->server
->tcpStatus
== CifsExiting
)
746 ses
->server
->tcpStatus
= CifsNeedReconnect
;
747 midQ
->midState
= MID_RETRY_NEEDED
;
751 if (rc
!= -EHOSTDOWN
) {
752 if(midQ
->midState
== MID_RETRY_NEEDED
) {
754 cFYI(1,("marking request for retry"));
759 spin_unlock(&GlobalMid_Lock
);
760 DeleteMidQEntry(midQ
);
761 /* If not lock req, update # of requests on wire to server */
763 atomic_dec(&ses
->server
->inFlight
);
764 wake_up(&ses
->server
->request_q
);
769 if (receive_len
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
) {
770 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
773 } else { /* rcvd frame is ok */
775 if (midQ
->resp_buf
&& out_buf
776 && (midQ
->midState
== MID_RESPONSE_RECEIVED
)) {
777 out_buf
->smb_buf_length
= receive_len
;
778 memcpy((char *)out_buf
+ 4,
779 (char *)midQ
->resp_buf
+ 4,
782 dump_smb(out_buf
, 92);
783 /* convert the length into a more usable form */
784 if((receive_len
> 24) &&
785 (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
|
786 SECMODE_SIGN_ENABLED
))) {
787 rc
= cifs_verify_signature(out_buf
,
788 ses
->server
->mac_signing_key
,
789 midQ
->sequence_number
+1);
791 cERROR(1,("Unexpected SMB signature"));
792 /* BB FIXME add code to kill session */
796 *pbytes_returned
= out_buf
->smb_buf_length
;
798 /* BB special case reconnect tid and uid here? */
799 rc
= map_smb_to_linux_error(out_buf
);
801 /* convert ByteCount if necessary */
803 sizeof (struct smb_hdr
) -
804 4 /* do not count RFC1001 header */ +
805 (2 * out_buf
->WordCount
) + 2 /* bcc */ )
806 BCC(out_buf
) = le16_to_cpu(BCC_LE(out_buf
));
809 cERROR(1,("Bad MID state?"));
812 cifs_no_response_exit
:
813 DeleteMidQEntry(midQ
);
816 atomic_dec(&ses
->server
->inFlight
);
817 wake_up(&ses
->server
->request_q
);
823 up(&ses
->server
->tcpSem
);
824 /* If not lock req, update # of requests on wire to server */
826 atomic_dec(&ses
->server
->inFlight
);
827 wake_up(&ses
->server
->request_q
);