kmsg_dump: fix build for CONFIG_PRINTK=n
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / cifs / transport.c
blob1da4ab250eae327a5e9a8889b9e498b4bc4946eb
1 /*
2 * fs/cifs/transport.c
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
23 #include <linux/fs.h>
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>
31 #include "cifspdu.h"
32 #include "cifsglob.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;
44 if (server == NULL) {
45 cERROR(1, ("Null TCP session in AllocMidQEntry"));
46 return NULL;
49 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
50 if (temp == NULL)
51 return temp;
52 else {
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;
61 temp->tsk = current;
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);
69 return temp;
72 static void
73 DeleteMidQEntry(struct mid_q_entry *midEntry)
75 #ifdef CONFIG_CIFS_STATS2
76 unsigned long now;
77 #endif
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);
85 else
86 cifs_small_buf_release(midEntry->resp_buf);
87 #ifdef CONFIG_CIFS_STATS2
88 now = jiffies;
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);
102 #endif
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"));
112 return NULL;
114 temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep,
115 GFP_KERNEL);
116 if (temp == NULL)
117 return temp;
118 else {
119 temp->pinode = pinode;
120 temp->tcon = tcon;
121 temp->netfid = fid;
122 spin_lock(&cifs_oplock_lock);
123 list_add_tail(&temp->qhead, &cifs_oplock_list);
124 spin_unlock(&cifs_oplock_lock);
126 return temp;
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;
143 if (tcon == NULL)
144 return;
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);
156 static int
157 smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
159 int rc = 0;
160 int i = 0;
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;
165 int first_vec = 0;
166 unsigned int smb_buf_length = smb_buffer->smb_buf_length;
167 struct socket *ssocket = server->ssocket;
169 if (ssocket == NULL)
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;
178 else
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 */
187 total_len = 0;
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);
195 i = 0;
196 while (total_len) {
197 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
198 n_vec - first_vec, total_len);
199 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
200 i++;
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))) {
220 cERROR(1,
221 ("sends on sock %p stuck for 15 seconds",
222 ssocket));
223 rc = -EAGAIN;
224 break;
226 msleep(1 << i);
227 continue;
229 if (rc < 0)
230 break;
232 if (rc == total_len) {
233 total_len = 0;
234 break;
235 } else if (rc > total_len) {
236 cERROR(1, ("sent %d requested %d", rc, total_len));
237 break;
239 if (rc == 0) {
240 /* should never happen, letting socket clear before
241 retrying is our only obvious option here */
242 cERROR(1, ("tcp sent no data"));
243 msleep(500);
244 continue;
246 total_len -= rc;
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;
252 iov[i].iov_len = 0;
253 } else {
254 iov[i].iov_base += rc;
255 iov[i].iov_len -= rc;
256 first_vec = i;
257 break;
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",
266 total_len));
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
270 SMB */
271 server->tcpStatus = CifsNeedReconnect;
274 if (rc < 0) {
275 cERROR(1, ("Error %d sending data on socket to server", rc));
276 } else
277 rc = 0;
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;
283 return rc;
287 smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
288 unsigned int smb_buf_length)
290 struct kvec iov;
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);
303 return 0;
306 spin_lock(&GlobalMid_Lock);
307 while (1) {
308 if (atomic_read(&ses->server->inFlight) >=
309 cifs_max_pending){
310 spin_unlock(&GlobalMid_Lock);
311 #ifdef CONFIG_CIFS_STATS2
312 atomic_inc(&ses->server->num_waiters);
313 #endif
314 wait_event(ses->server->request_q,
315 atomic_read(&ses->server->inFlight)
316 < cifs_max_pending);
317 #ifdef CONFIG_CIFS_STATS2
318 atomic_dec(&ses->server->num_waiters);
319 #endif
320 spin_lock(&GlobalMid_Lock);
321 } else {
322 if (ses->server->tcpStatus == CifsExiting) {
323 spin_unlock(&GlobalMid_Lock);
324 return -ENOENT;
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);
334 break;
337 return 0;
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) {
344 return -ENOENT;
347 if (ses->server->tcpStatus == CifsNeedReconnect) {
348 cFYI(1, ("tcp session dead - return to caller to retry"));
349 return -EAGAIN;
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))
356 return -EAGAIN;
357 /* else ok - we are setting up session */
359 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
360 if (*ppmidQ == NULL)
361 return -ENOMEM;
362 return 0;
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;
372 for (;;) {
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))) {
382 unsigned long lrt;
384 /* We timed out. Is the server still
385 sending replies ? */
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 */
397 lrt += time_to_wait;
398 if (time_after(jiffies, lrt)) {
399 /* No replies for time_to_wait. */
400 cERROR(1, ("server not responding"));
401 return -1;
403 } else {
404 return 0;
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)
423 int rc;
424 struct kvec iov[1];
425 int resp_buf_type;
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));
433 return rc;
437 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
438 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
439 const int flags)
441 int rc = 0;
442 int long_op;
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"));
455 return -EIO;
458 if (ses->server->tcpStatus == CifsExiting) {
459 cifs_small_buf_release(in_buf);
460 return -ENOENT;
463 /* Ensure that we do not send more than 50 overlapping requests
464 to the same server. We may make this configurable later or
465 use ses->maxReq */
467 rc = wait_for_free_request(ses, long_op);
468 if (rc) {
469 cifs_small_buf_release(in_buf);
470 return rc;
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
475 of smb data */
477 mutex_lock(&ses->server->srv_mutex);
479 rc = allocate_mid(ses, in_buf, &midQ);
480 if (rc) {
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);
486 return rc;
488 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
489 if (rc) {
490 mutex_unlock(&ses->server->srv_mutex);
491 cifs_small_buf_release(in_buf);
492 goto out;
495 midQ->midState = MID_REQUEST_SUBMITTED;
496 #ifdef CONFIG_CIFS_STATS2
497 atomic_inc(&ses->server->inSend);
498 #endif
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;
503 #endif
505 mutex_unlock(&ses->server->srv_mutex);
506 cifs_small_buf_release(in_buf);
508 if (rc < 0)
509 goto out;
511 if (long_op == CIFS_STD_OP)
512 timeout = 15 * HZ;
513 else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
514 timeout = 180 * HZ;
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)
519 goto out;
520 else if (long_op == CIFS_BLOCKING_OP)
521 timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */
522 else {
523 cERROR(1, ("unknown timeout flag %d", long_op));
524 rc = -EIO;
525 goto out;
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 */
533 timeout = 2 * HZ;
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)
546 rc = -EHOSTDOWN;
547 else {
548 ses->server->tcpStatus = CifsNeedReconnect;
549 midQ->midState = MID_RETRY_NEEDED;
553 if (rc != -EHOSTDOWN) {
554 if (midQ->midState == MID_RETRY_NEEDED) {
555 rc = -EAGAIN;
556 cFYI(1, ("marking request for retry"));
557 } else {
558 rc = -EIO;
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);
566 return rc;
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",
574 receive_len, xid));
575 rc = -EIO;
576 goto out;
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;
585 if (midQ->largeBuf)
586 *pRespBufType = CIFS_LARGE_BUFFER;
587 else
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);
599 if (rc) {
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
617 not be freed by
618 DeleteMidQEntry */
619 } else {
620 rc = -EIO;
621 cFYI(1, ("Bad MID state?"));
624 out:
625 DeleteMidQEntry(midQ);
626 atomic_dec(&ses->server->inFlight);
627 wake_up(&ses->server->request_q);
629 return rc;
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)
637 int rc = 0;
638 unsigned int receive_len;
639 unsigned long timeout;
640 struct mid_q_entry *midQ;
642 if (ses == NULL) {
643 cERROR(1, ("Null smb session"));
644 return -EIO;
646 if (ses->server == NULL) {
647 cERROR(1, ("Null tcp session"));
648 return -EIO;
651 if (ses->server->tcpStatus == CifsExiting)
652 return -ENOENT;
654 /* Ensure that we do not send more than 50 overlapping requests
655 to the same server. We may make this configurable later or
656 use ses->maxReq */
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));
661 return -EIO;
664 rc = wait_for_free_request(ses, long_op);
665 if (rc)
666 return rc;
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
670 of smb data */
672 mutex_lock(&ses->server->srv_mutex);
674 rc = allocate_mid(ses, in_buf, &midQ);
675 if (rc) {
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);
680 return rc;
683 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
684 if (rc) {
685 mutex_unlock(&ses->server->srv_mutex);
686 goto out;
689 midQ->midState = MID_REQUEST_SUBMITTED;
690 #ifdef CONFIG_CIFS_STATS2
691 atomic_inc(&ses->server->inSend);
692 #endif
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;
697 #endif
698 mutex_unlock(&ses->server->srv_mutex);
700 if (rc < 0)
701 goto out;
703 if (long_op == CIFS_STD_OP)
704 timeout = 15 * HZ;
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)
708 goto out;
709 else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
710 timeout = 180 * HZ;
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 */
716 else {
717 cERROR(1, ("unknown timeout flag %d", long_op));
718 rc = -EIO;
719 goto out;
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 */
725 timeout = 2 * HZ;
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)
737 rc = -EHOSTDOWN;
738 else {
739 ses->server->tcpStatus = CifsNeedReconnect;
740 midQ->midState = MID_RETRY_NEEDED;
744 if (rc != -EHOSTDOWN) {
745 if (midQ->midState == MID_RETRY_NEEDED) {
746 rc = -EAGAIN;
747 cFYI(1, ("marking request for retry"));
748 } else {
749 rc = -EIO;
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);
757 return rc;
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",
765 receive_len, xid));
766 rc = -EIO;
767 goto out;
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,
777 receive_len);
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);
787 if (rc) {
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));
803 } else {
804 rc = -EIO;
805 cERROR(1, ("Bad MID state?"));
808 out:
809 DeleteMidQEntry(midQ);
810 atomic_dec(&ses->server->inFlight);
811 wake_up(&ses->server->request_q);
813 return rc;
816 /* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
818 static int
819 send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
820 struct mid_q_entry *midQ)
822 int rc = 0;
823 struct cifsSesInfo *ses = tcon->ses;
824 __u16 mid = in_buf->Mid;
826 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
827 in_buf->Mid = mid;
828 mutex_lock(&ses->server->srv_mutex);
829 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
830 if (rc) {
831 mutex_unlock(&ses->server->srv_mutex);
832 return rc;
834 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
835 mutex_unlock(&ses->server->srv_mutex);
836 return rc;
839 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
840 blocking lock to return. */
842 static int
843 send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
844 struct smb_hdr *in_buf,
845 struct smb_hdr *out_buf)
847 int bytes_returned;
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;
857 pSMB->Timeout = 0;
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)
869 int rc = 0;
870 int rstart = 0;
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"));
877 return -EIO;
879 ses = tcon->ses;
881 if (ses->server == NULL) {
882 cERROR(1, ("Null tcp session"));
883 return -EIO;
886 if (ses->server->tcpStatus == CifsExiting)
887 return -ENOENT;
889 /* Ensure that we do not send more than 50 overlapping requests
890 to the same server. We may make this configurable later or
891 use ses->maxReq */
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));
896 return -EIO;
899 rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
900 if (rc)
901 return rc;
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
905 of smb data */
907 mutex_lock(&ses->server->srv_mutex);
909 rc = allocate_mid(ses, in_buf, &midQ);
910 if (rc) {
911 mutex_unlock(&ses->server->srv_mutex);
912 return rc;
915 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
916 if (rc) {
917 DeleteMidQEntry(midQ);
918 mutex_unlock(&ses->server->srv_mutex);
919 return rc;
922 midQ->midState = MID_REQUEST_SUBMITTED;
923 #ifdef CONFIG_CIFS_STATS2
924 atomic_inc(&ses->server->inSend);
925 #endif
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;
930 #endif
931 mutex_unlock(&ses->server->srv_mutex);
933 if (rc < 0) {
934 DeleteMidQEntry(midQ);
935 return rc;
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);
955 if (rc) {
956 DeleteMidQEntry(midQ);
957 return rc;
959 } else {
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);
969 return rc;
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. */
976 rstart = 1;
980 spin_lock(&GlobalMid_Lock);
981 if (midQ->resp_buf) {
982 spin_unlock(&GlobalMid_Lock);
983 receive_len = midQ->resp_buf->smb_buf_length;
984 } else {
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)
989 rc = -EHOSTDOWN;
990 else {
991 ses->server->tcpStatus = CifsNeedReconnect;
992 midQ->midState = MID_RETRY_NEEDED;
996 if (rc != -EHOSTDOWN) {
997 if (midQ->midState == MID_RETRY_NEEDED) {
998 rc = -EAGAIN;
999 cFYI(1, ("marking request for retry"));
1000 } else {
1001 rc = -EIO;
1004 spin_unlock(&GlobalMid_Lock);
1005 DeleteMidQEntry(midQ);
1006 return rc;
1009 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
1010 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
1011 receive_len, xid));
1012 rc = -EIO;
1013 goto out;
1016 /* rcvd frame is ok */
1018 if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
1019 rc = -EIO;
1020 cERROR(1, ("Bad MID state?"));
1021 goto out;
1024 out_buf->smb_buf_length = receive_len;
1025 memcpy((char *)out_buf + 4,
1026 (char *)midQ->resp_buf + 4,
1027 receive_len);
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);
1037 if (rc) {
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));
1054 out:
1055 DeleteMidQEntry(midQ);
1056 if (rstart && rc == -EACCES)
1057 return -ERESTARTSYS;
1058 return rc;