]> git.karo-electronics.de Git - mv-sheeva.git/blob - fs/cifs/transport.c
cifs: move mid result processing into common function
[mv-sheeva.git] / fs / cifs / transport.c
1 /*
2  *   fs/cifs/transport.c
3  *
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.
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #include <linux/fs.h>
24 #include <linux/list.h>
25 #include <linux/gfp.h>
26 #include <linux/wait.h>
27 #include <linux/net.h>
28 #include <linux/delay.h>
29 #include <asm/uaccess.h>
30 #include <asm/processor.h>
31 #include <linux/mempool.h>
32 #include "cifspdu.h"
33 #include "cifsglob.h"
34 #include "cifsproto.h"
35 #include "cifs_debug.h"
36
37 extern mempool_t *cifs_mid_poolp;
38
39 static struct mid_q_entry *
40 AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
41 {
42         struct mid_q_entry *temp;
43
44         if (server == NULL) {
45                 cERROR(1, "Null TCP session in AllocMidQEntry");
46                 return NULL;
47         }
48
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;
62         }
63
64         atomic_inc(&midCount);
65         temp->midState = MID_REQUEST_ALLOCATED;
66         return temp;
67 }
68
69 static void
70 DeleteMidQEntry(struct mid_q_entry *midEntry)
71 {
72 #ifdef CONFIG_CIFS_STATS2
73         unsigned long now;
74 #endif
75         midEntry->midState = MID_FREE;
76         atomic_dec(&midCount);
77         if (midEntry->largeBuf)
78                 cifs_buf_release(midEntry->resp_buf);
79         else
80                 cifs_small_buf_release(midEntry->resp_buf);
81 #ifdef CONFIG_CIFS_STATS2
82         now = jiffies;
83         /* commands taking longer than one second are indications that
84            something is wrong, unless it is quite a slow link or server */
85         if ((now - midEntry->when_alloc) > HZ) {
86                 if ((cifsFYI & CIFS_TIMER) &&
87                    (midEntry->command != SMB_COM_LOCKING_ANDX)) {
88                         printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
89                                midEntry->command, midEntry->mid);
90                         printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
91                                now - midEntry->when_alloc,
92                                now - midEntry->when_sent,
93                                now - midEntry->when_received);
94                 }
95         }
96 #endif
97         mempool_free(midEntry, cifs_mid_poolp);
98 }
99
100 static void
101 delete_mid(struct mid_q_entry *mid)
102 {
103         spin_lock(&GlobalMid_Lock);
104         list_del(&mid->qhead);
105         spin_unlock(&GlobalMid_Lock);
106
107         DeleteMidQEntry(mid);
108 }
109
110 static int
111 smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
112 {
113         int rc = 0;
114         int i = 0;
115         struct msghdr smb_msg;
116         struct smb_hdr *smb_buffer = iov[0].iov_base;
117         unsigned int len = iov[0].iov_len;
118         unsigned int total_len;
119         int first_vec = 0;
120         unsigned int smb_buf_length = smb_buffer->smb_buf_length;
121         struct socket *ssocket = server->ssocket;
122
123         if (ssocket == NULL)
124                 return -ENOTSOCK; /* BB eventually add reconnect code here */
125
126         smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
127         smb_msg.msg_namelen = sizeof(struct sockaddr);
128         smb_msg.msg_control = NULL;
129         smb_msg.msg_controllen = 0;
130         if (server->noblocksnd)
131                 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
132         else
133                 smb_msg.msg_flags = MSG_NOSIGNAL;
134
135         /* smb header is converted in header_assemble. bcc and rest of SMB word
136            area, and byte area if necessary, is converted to littleendian in
137            cifssmb.c and RFC1001 len is converted to bigendian in smb_send
138            Flags2 is converted in SendReceive */
139
140
141         total_len = 0;
142         for (i = 0; i < n_vec; i++)
143                 total_len += iov[i].iov_len;
144
145         smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
146         cFYI(1, "Sending smb:  total_len %d", total_len);
147         dump_smb(smb_buffer, len);
148
149         i = 0;
150         while (total_len) {
151                 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
152                                     n_vec - first_vec, total_len);
153                 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
154                         i++;
155                         /* if blocking send we try 3 times, since each can block
156                            for 5 seconds. For nonblocking  we have to try more
157                            but wait increasing amounts of time allowing time for
158                            socket to clear.  The overall time we wait in either
159                            case to send on the socket is about 15 seconds.
160                            Similarly we wait for 15 seconds for
161                            a response from the server in SendReceive[2]
162                            for the server to send a response back for
163                            most types of requests (except SMB Write
164                            past end of file which can be slow, and
165                            blocking lock operations). NFS waits slightly longer
166                            than CIFS, but this can make it take longer for
167                            nonresponsive servers to be detected and 15 seconds
168                            is more than enough time for modern networks to
169                            send a packet.  In most cases if we fail to send
170                            after the retries we will kill the socket and
171                            reconnect which may clear the network problem.
172                         */
173                         if ((i >= 14) || (!server->noblocksnd && (i > 2))) {
174                                 cERROR(1, "sends on sock %p stuck for 15 seconds",
175                                     ssocket);
176                                 rc = -EAGAIN;
177                                 break;
178                         }
179                         msleep(1 << i);
180                         continue;
181                 }
182                 if (rc < 0)
183                         break;
184
185                 if (rc == total_len) {
186                         total_len = 0;
187                         break;
188                 } else if (rc > total_len) {
189                         cERROR(1, "sent %d requested %d", rc, total_len);
190                         break;
191                 }
192                 if (rc == 0) {
193                         /* should never happen, letting socket clear before
194                            retrying is our only obvious option here */
195                         cERROR(1, "tcp sent no data");
196                         msleep(500);
197                         continue;
198                 }
199                 total_len -= rc;
200                 /* the line below resets i */
201                 for (i = first_vec; i < n_vec; i++) {
202                         if (iov[i].iov_len) {
203                                 if (rc > iov[i].iov_len) {
204                                         rc -= iov[i].iov_len;
205                                         iov[i].iov_len = 0;
206                                 } else {
207                                         iov[i].iov_base += rc;
208                                         iov[i].iov_len -= rc;
209                                         first_vec = i;
210                                         break;
211                                 }
212                         }
213                 }
214                 i = 0; /* in case we get ENOSPC on the next send */
215         }
216
217         if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
218                 cFYI(1, "partial send (%d remaining), terminating session",
219                         total_len);
220                 /* If we have only sent part of an SMB then the next SMB
221                    could be taken as the remainder of this one.  We need
222                    to kill the socket so the server throws away the partial
223                    SMB */
224                 server->tcpStatus = CifsNeedReconnect;
225         }
226
227         if (rc < 0) {
228                 cERROR(1, "Error %d sending data on socket to server", rc);
229         } else
230                 rc = 0;
231
232         /* Don't want to modify the buffer as a
233            side effect of this call. */
234         smb_buffer->smb_buf_length = smb_buf_length;
235
236         return rc;
237 }
238
239 int
240 smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
241          unsigned int smb_buf_length)
242 {
243         struct kvec iov;
244
245         iov.iov_base = smb_buffer;
246         iov.iov_len = smb_buf_length + 4;
247
248         return smb_sendv(server, &iov, 1);
249 }
250
251 static int wait_for_free_request(struct TCP_Server_Info *server,
252                                  const int long_op)
253 {
254         if (long_op == CIFS_ASYNC_OP) {
255                 /* oplock breaks must not be held up */
256                 atomic_inc(&server->inFlight);
257                 return 0;
258         }
259
260         spin_lock(&GlobalMid_Lock);
261         while (1) {
262                 if (atomic_read(&server->inFlight) >= cifs_max_pending) {
263                         spin_unlock(&GlobalMid_Lock);
264 #ifdef CONFIG_CIFS_STATS2
265                         atomic_inc(&server->num_waiters);
266 #endif
267                         wait_event(server->request_q,
268                                    atomic_read(&server->inFlight)
269                                      < cifs_max_pending);
270 #ifdef CONFIG_CIFS_STATS2
271                         atomic_dec(&server->num_waiters);
272 #endif
273                         spin_lock(&GlobalMid_Lock);
274                 } else {
275                         if (server->tcpStatus == CifsExiting) {
276                                 spin_unlock(&GlobalMid_Lock);
277                                 return -ENOENT;
278                         }
279
280                         /* can not count locking commands against total
281                            as they are allowed to block on server */
282
283                         /* update # of requests on the wire to server */
284                         if (long_op != CIFS_BLOCKING_OP)
285                                 atomic_inc(&server->inFlight);
286                         spin_unlock(&GlobalMid_Lock);
287                         break;
288                 }
289         }
290         return 0;
291 }
292
293 static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
294                         struct mid_q_entry **ppmidQ)
295 {
296         if (ses->server->tcpStatus == CifsExiting) {
297                 return -ENOENT;
298         }
299
300         if (ses->server->tcpStatus == CifsNeedReconnect) {
301                 cFYI(1, "tcp session dead - return to caller to retry");
302                 return -EAGAIN;
303         }
304
305         if (ses->status != CifsGood) {
306                 /* check if SMB session is bad because we are setting it up */
307                 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
308                         (in_buf->Command != SMB_COM_NEGOTIATE))
309                         return -EAGAIN;
310                 /* else ok - we are setting up session */
311         }
312         *ppmidQ = AllocMidQEntry(in_buf, ses->server);
313         if (*ppmidQ == NULL)
314                 return -ENOMEM;
315         spin_lock(&GlobalMid_Lock);
316         list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
317         spin_unlock(&GlobalMid_Lock);
318         return 0;
319 }
320
321 static int wait_for_response(struct cifsSesInfo *ses,
322                         struct mid_q_entry *midQ,
323                         unsigned long timeout,
324                         unsigned long time_to_wait)
325 {
326         unsigned long curr_timeout;
327
328         for (;;) {
329                 curr_timeout = timeout + jiffies;
330                 wait_event_timeout(ses->server->response_q,
331                         midQ->midState != MID_REQUEST_SUBMITTED, timeout);
332
333                 if (time_after(jiffies, curr_timeout) &&
334                         (midQ->midState == MID_REQUEST_SUBMITTED) &&
335                         ((ses->server->tcpStatus == CifsGood) ||
336                          (ses->server->tcpStatus == CifsNew))) {
337
338                         unsigned long lrt;
339
340                         /* We timed out. Is the server still
341                            sending replies ? */
342                         spin_lock(&GlobalMid_Lock);
343                         lrt = ses->server->lstrp;
344                         spin_unlock(&GlobalMid_Lock);
345
346                         /* Calculate time_to_wait past last receive time.
347                          Although we prefer not to time out if the
348                          server is still responding - we will time
349                          out if the server takes more than 15 (or 45
350                          or 180) seconds to respond to this request
351                          and has not responded to any request from
352                          other threads on the client within 10 seconds */
353                         lrt += time_to_wait;
354                         if (time_after(jiffies, lrt)) {
355                                 /* No replies for time_to_wait. */
356                                 cERROR(1, "server not responding");
357                                 return -1;
358                         }
359                 } else {
360                         return 0;
361                 }
362         }
363 }
364
365
366 /*
367  *
368  * Send an SMB Request.  No response info (other than return code)
369  * needs to be parsed.
370  *
371  * flags indicate the type of request buffer and how long to wait
372  * and whether to log NT STATUS code (error) before mapping it to POSIX error
373  *
374  */
375 int
376 SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
377                 struct smb_hdr *in_buf, int flags)
378 {
379         int rc;
380         struct kvec iov[1];
381         int resp_buf_type;
382
383         iov[0].iov_base = (char *)in_buf;
384         iov[0].iov_len = in_buf->smb_buf_length + 4;
385         flags |= CIFS_NO_RESP;
386         rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
387         cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
388
389         return rc;
390 }
391
392 static int
393 sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
394 {
395         int rc = 0;
396
397         spin_lock(&GlobalMid_Lock);
398
399         if (mid->resp_buf) {
400                 spin_unlock(&GlobalMid_Lock);
401                 return rc;
402         }
403
404         cERROR(1, "No response to cmd %d mid %d", mid->command, mid->mid);
405         if (mid->midState == MID_REQUEST_SUBMITTED) {
406                 if (server->tcpStatus == CifsExiting)
407                         rc = -EHOSTDOWN;
408                 else {
409                         server->tcpStatus = CifsNeedReconnect;
410                         mid->midState = MID_RETRY_NEEDED;
411                 }
412         }
413
414         if (rc != -EHOSTDOWN) {
415                 if (mid->midState == MID_RETRY_NEEDED) {
416                         rc = -EAGAIN;
417                         cFYI(1, "marking request for retry");
418                 } else {
419                         rc = -EIO;
420                 }
421         }
422         spin_unlock(&GlobalMid_Lock);
423
424         delete_mid(mid);
425         return rc;
426 }
427
428 int
429 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
430              struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
431              const int flags)
432 {
433         int rc = 0;
434         int long_op;
435         unsigned int receive_len;
436         unsigned long timeout;
437         struct mid_q_entry *midQ;
438         struct smb_hdr *in_buf = iov[0].iov_base;
439
440         long_op = flags & CIFS_TIMEOUT_MASK;
441
442         *pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
443
444         if ((ses == NULL) || (ses->server == NULL)) {
445                 cifs_small_buf_release(in_buf);
446                 cERROR(1, "Null session");
447                 return -EIO;
448         }
449
450         if (ses->server->tcpStatus == CifsExiting) {
451                 cifs_small_buf_release(in_buf);
452                 return -ENOENT;
453         }
454
455         /* Ensure that we do not send more than 50 overlapping requests
456            to the same server. We may make this configurable later or
457            use ses->maxReq */
458
459         rc = wait_for_free_request(ses->server, long_op);
460         if (rc) {
461                 cifs_small_buf_release(in_buf);
462                 return rc;
463         }
464
465         /* make sure that we sign in the same order that we send on this socket
466            and avoid races inside tcp sendmsg code that could cause corruption
467            of smb data */
468
469         mutex_lock(&ses->server->srv_mutex);
470
471         rc = allocate_mid(ses, in_buf, &midQ);
472         if (rc) {
473                 mutex_unlock(&ses->server->srv_mutex);
474                 cifs_small_buf_release(in_buf);
475                 /* Update # of requests on wire to server */
476                 atomic_dec(&ses->server->inFlight);
477                 wake_up(&ses->server->request_q);
478                 return rc;
479         }
480         rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
481         if (rc) {
482                 mutex_unlock(&ses->server->srv_mutex);
483                 cifs_small_buf_release(in_buf);
484                 goto out;
485         }
486
487         midQ->midState = MID_REQUEST_SUBMITTED;
488 #ifdef CONFIG_CIFS_STATS2
489         atomic_inc(&ses->server->inSend);
490 #endif
491         rc = smb_sendv(ses->server, iov, n_vec);
492 #ifdef CONFIG_CIFS_STATS2
493         atomic_dec(&ses->server->inSend);
494         midQ->when_sent = jiffies;
495 #endif
496
497         mutex_unlock(&ses->server->srv_mutex);
498         cifs_small_buf_release(in_buf);
499
500         if (rc < 0)
501                 goto out;
502
503         if (long_op == CIFS_STD_OP)
504                 timeout = 15 * HZ;
505         else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
506                 timeout = 180 * HZ;
507         else if (long_op == CIFS_LONG_OP)
508                 timeout = 45 * HZ; /* should be greater than
509                         servers oplock break timeout (about 43 seconds) */
510         else if (long_op == CIFS_ASYNC_OP)
511                 goto out;
512         else if (long_op == CIFS_BLOCKING_OP)
513                 timeout = 0x7FFFFFFF; /*  large, but not so large as to wrap */
514         else {
515                 cERROR(1, "unknown timeout flag %d", long_op);
516                 rc = -EIO;
517                 goto out;
518         }
519
520         /* wait for 15 seconds or until woken up due to response arriving or
521            due to last connection to this server being unmounted */
522         if (signal_pending(current)) {
523                 /* if signal pending do not hold up user for full smb timeout
524                 but we still give response a chance to complete */
525                 timeout = 2 * HZ;
526         }
527
528         /* No user interrupts in wait - wreaks havoc with performance */
529         wait_for_response(ses, midQ, timeout, 10 * HZ);
530
531         rc = sync_mid_result(midQ, ses->server);
532         if (rc != 0) {
533                 atomic_dec(&ses->server->inFlight);
534                 wake_up(&ses->server->request_q);
535                 return rc;
536         }
537
538         receive_len = midQ->resp_buf->smb_buf_length;
539
540         if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
541                 cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
542                         receive_len, xid);
543                 rc = -EIO;
544                 goto out;
545         }
546
547         /* rcvd frame is ok */
548
549         if (midQ->resp_buf &&
550             (midQ->midState == MID_RESPONSE_RECEIVED)) {
551
552                 iov[0].iov_base = (char *)midQ->resp_buf;
553                 if (midQ->largeBuf)
554                         *pRespBufType = CIFS_LARGE_BUFFER;
555                 else
556                         *pRespBufType = CIFS_SMALL_BUFFER;
557                 iov[0].iov_len = receive_len + 4;
558
559                 dump_smb(midQ->resp_buf, 80);
560                 /* convert the length into a more usable form */
561                 if ((receive_len > 24) &&
562                     (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
563                                              SECMODE_SIGN_ENABLED))) {
564                         rc = cifs_verify_signature(midQ->resp_buf,
565                                                 ses->server,
566                                                 midQ->sequence_number+1);
567                         if (rc) {
568                                 cERROR(1, "Unexpected SMB signature");
569                                 /* BB FIXME add code to kill session */
570                         }
571                 }
572
573                 /* BB special case reconnect tid and uid here? */
574                 rc = map_smb_to_linux_error(midQ->resp_buf,
575                                             flags & CIFS_LOG_ERROR);
576
577                 /* convert ByteCount if necessary */
578                 if (receive_len >= sizeof(struct smb_hdr) - 4
579                     /* do not count RFC1001 header */  +
580                     (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
581                         BCC(midQ->resp_buf) =
582                                 le16_to_cpu(BCC_LE(midQ->resp_buf));
583                 if ((flags & CIFS_NO_RESP) == 0)
584                         midQ->resp_buf = NULL;  /* mark it so buf will
585                                                    not be freed by
586                                                    delete_mid */
587         } else {
588                 rc = -EIO;
589                 cFYI(1, "Bad MID state?");
590         }
591
592 out:
593         delete_mid(midQ);
594         atomic_dec(&ses->server->inFlight);
595         wake_up(&ses->server->request_q);
596
597         return rc;
598 }
599
600 int
601 SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
602             struct smb_hdr *in_buf, struct smb_hdr *out_buf,
603             int *pbytes_returned, const int long_op)
604 {
605         int rc = 0;
606         unsigned int receive_len;
607         unsigned long timeout;
608         struct mid_q_entry *midQ;
609
610         if (ses == NULL) {
611                 cERROR(1, "Null smb session");
612                 return -EIO;
613         }
614         if (ses->server == NULL) {
615                 cERROR(1, "Null tcp session");
616                 return -EIO;
617         }
618
619         if (ses->server->tcpStatus == CifsExiting)
620                 return -ENOENT;
621
622         /* Ensure that we do not send more than 50 overlapping requests
623            to the same server. We may make this configurable later or
624            use ses->maxReq */
625
626         if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
627                 cERROR(1, "Illegal length, greater than maximum frame, %d",
628                            in_buf->smb_buf_length);
629                 return -EIO;
630         }
631
632         rc = wait_for_free_request(ses->server, long_op);
633         if (rc)
634                 return rc;
635
636         /* make sure that we sign in the same order that we send on this socket
637            and avoid races inside tcp sendmsg code that could cause corruption
638            of smb data */
639
640         mutex_lock(&ses->server->srv_mutex);
641
642         rc = allocate_mid(ses, in_buf, &midQ);
643         if (rc) {
644                 mutex_unlock(&ses->server->srv_mutex);
645                 /* Update # of requests on wire to server */
646                 atomic_dec(&ses->server->inFlight);
647                 wake_up(&ses->server->request_q);
648                 return rc;
649         }
650
651         rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
652         if (rc) {
653                 mutex_unlock(&ses->server->srv_mutex);
654                 goto out;
655         }
656
657         midQ->midState = MID_REQUEST_SUBMITTED;
658 #ifdef CONFIG_CIFS_STATS2
659         atomic_inc(&ses->server->inSend);
660 #endif
661         rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
662 #ifdef CONFIG_CIFS_STATS2
663         atomic_dec(&ses->server->inSend);
664         midQ->when_sent = jiffies;
665 #endif
666         mutex_unlock(&ses->server->srv_mutex);
667
668         if (rc < 0)
669                 goto out;
670
671         if (long_op == CIFS_STD_OP)
672                 timeout = 15 * HZ;
673         /* wait for 15 seconds or until woken up due to response arriving or
674            due to last connection to this server being unmounted */
675         else if (long_op == CIFS_ASYNC_OP)
676                 goto out;
677         else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
678                 timeout = 180 * HZ;
679         else if (long_op == CIFS_LONG_OP)
680                 timeout = 45 * HZ; /* should be greater than
681                         servers oplock break timeout (about 43 seconds) */
682         else if (long_op == CIFS_BLOCKING_OP)
683                 timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
684         else {
685                 cERROR(1, "unknown timeout flag %d", long_op);
686                 rc = -EIO;
687                 goto out;
688         }
689
690         if (signal_pending(current)) {
691                 /* if signal pending do not hold up user for full smb timeout
692                 but we still give response a chance to complete */
693                 timeout = 2 * HZ;
694         }
695
696         /* No user interrupts in wait - wreaks havoc with performance */
697         wait_for_response(ses, midQ, timeout, 10 * HZ);
698
699         rc = sync_mid_result(midQ, ses->server);
700         if (rc != 0) {
701                 atomic_dec(&ses->server->inFlight);
702                 wake_up(&ses->server->request_q);
703                 return rc;
704         }
705
706         receive_len = midQ->resp_buf->smb_buf_length;
707
708         if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
709                 cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
710                         receive_len, xid);
711                 rc = -EIO;
712                 goto out;
713         }
714
715         /* rcvd frame is ok */
716
717         if (midQ->resp_buf && out_buf
718             && (midQ->midState == MID_RESPONSE_RECEIVED)) {
719                 out_buf->smb_buf_length = receive_len;
720                 memcpy((char *)out_buf + 4,
721                        (char *)midQ->resp_buf + 4,
722                        receive_len);
723
724                 dump_smb(out_buf, 92);
725                 /* convert the length into a more usable form */
726                 if ((receive_len > 24) &&
727                     (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
728                                              SECMODE_SIGN_ENABLED))) {
729                         rc = cifs_verify_signature(out_buf,
730                                                 ses->server,
731                                                 midQ->sequence_number+1);
732                         if (rc) {
733                                 cERROR(1, "Unexpected SMB signature");
734                                 /* BB FIXME add code to kill session */
735                         }
736                 }
737
738                 *pbytes_returned = out_buf->smb_buf_length;
739
740                 /* BB special case reconnect tid and uid here? */
741                 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
742
743                 /* convert ByteCount if necessary */
744                 if (receive_len >= sizeof(struct smb_hdr) - 4
745                     /* do not count RFC1001 header */  +
746                     (2 * out_buf->WordCount) + 2 /* bcc */ )
747                         BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
748         } else {
749                 rc = -EIO;
750                 cERROR(1, "Bad MID state?");
751         }
752
753 out:
754         delete_mid(midQ);
755         atomic_dec(&ses->server->inFlight);
756         wake_up(&ses->server->request_q);
757
758         return rc;
759 }
760
761 /* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
762
763 static int
764 send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
765                 struct mid_q_entry *midQ)
766 {
767         int rc = 0;
768         struct cifsSesInfo *ses = tcon->ses;
769         __u16 mid = in_buf->Mid;
770
771         header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
772         in_buf->Mid = mid;
773         mutex_lock(&ses->server->srv_mutex);
774         rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
775         if (rc) {
776                 mutex_unlock(&ses->server->srv_mutex);
777                 return rc;
778         }
779         rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
780         mutex_unlock(&ses->server->srv_mutex);
781         return rc;
782 }
783
784 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
785    blocking lock to return. */
786
787 static int
788 send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
789                         struct smb_hdr *in_buf,
790                         struct smb_hdr *out_buf)
791 {
792         int bytes_returned;
793         struct cifsSesInfo *ses = tcon->ses;
794         LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
795
796         /* We just modify the current in_buf to change
797            the type of lock from LOCKING_ANDX_SHARED_LOCK
798            or LOCKING_ANDX_EXCLUSIVE_LOCK to
799            LOCKING_ANDX_CANCEL_LOCK. */
800
801         pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
802         pSMB->Timeout = 0;
803         pSMB->hdr.Mid = GetNextMid(ses->server);
804
805         return SendReceive(xid, ses, in_buf, out_buf,
806                         &bytes_returned, CIFS_STD_OP);
807 }
808
809 int
810 SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
811             struct smb_hdr *in_buf, struct smb_hdr *out_buf,
812             int *pbytes_returned)
813 {
814         int rc = 0;
815         int rstart = 0;
816         unsigned int receive_len;
817         struct mid_q_entry *midQ;
818         struct cifsSesInfo *ses;
819
820         if (tcon == NULL || tcon->ses == NULL) {
821                 cERROR(1, "Null smb session");
822                 return -EIO;
823         }
824         ses = tcon->ses;
825
826         if (ses->server == NULL) {
827                 cERROR(1, "Null tcp session");
828                 return -EIO;
829         }
830
831         if (ses->server->tcpStatus == CifsExiting)
832                 return -ENOENT;
833
834         /* Ensure that we do not send more than 50 overlapping requests
835            to the same server. We may make this configurable later or
836            use ses->maxReq */
837
838         if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
839                 cERROR(1, "Illegal length, greater than maximum frame, %d",
840                            in_buf->smb_buf_length);
841                 return -EIO;
842         }
843
844         rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP);
845         if (rc)
846                 return rc;
847
848         /* make sure that we sign in the same order that we send on this socket
849            and avoid races inside tcp sendmsg code that could cause corruption
850            of smb data */
851
852         mutex_lock(&ses->server->srv_mutex);
853
854         rc = allocate_mid(ses, in_buf, &midQ);
855         if (rc) {
856                 mutex_unlock(&ses->server->srv_mutex);
857                 return rc;
858         }
859
860         rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
861         if (rc) {
862                 delete_mid(midQ);
863                 mutex_unlock(&ses->server->srv_mutex);
864                 return rc;
865         }
866
867         midQ->midState = MID_REQUEST_SUBMITTED;
868 #ifdef CONFIG_CIFS_STATS2
869         atomic_inc(&ses->server->inSend);
870 #endif
871         rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
872 #ifdef CONFIG_CIFS_STATS2
873         atomic_dec(&ses->server->inSend);
874         midQ->when_sent = jiffies;
875 #endif
876         mutex_unlock(&ses->server->srv_mutex);
877
878         if (rc < 0) {
879                 delete_mid(midQ);
880                 return rc;
881         }
882
883         /* Wait for a reply - allow signals to interrupt. */
884         rc = wait_event_interruptible(ses->server->response_q,
885                 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
886                 ((ses->server->tcpStatus != CifsGood) &&
887                  (ses->server->tcpStatus != CifsNew)));
888
889         /* Were we interrupted by a signal ? */
890         if ((rc == -ERESTARTSYS) &&
891                 (midQ->midState == MID_REQUEST_SUBMITTED) &&
892                 ((ses->server->tcpStatus == CifsGood) ||
893                  (ses->server->tcpStatus == CifsNew))) {
894
895                 if (in_buf->Command == SMB_COM_TRANSACTION2) {
896                         /* POSIX lock. We send a NT_CANCEL SMB to cause the
897                            blocking lock to return. */
898
899                         rc = send_nt_cancel(tcon, in_buf, midQ);
900                         if (rc) {
901                                 delete_mid(midQ);
902                                 return rc;
903                         }
904                 } else {
905                         /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
906                            to cause the blocking lock to return. */
907
908                         rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
909
910                         /* If we get -ENOLCK back the lock may have
911                            already been removed. Don't exit in this case. */
912                         if (rc && rc != -ENOLCK) {
913                                 delete_mid(midQ);
914                                 return rc;
915                         }
916                 }
917
918                 /* Wait 5 seconds for the response. */
919                 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {
920                         /* We got the response - restart system call. */
921                         rstart = 1;
922                 }
923         }
924
925         rc = sync_mid_result(midQ, ses->server);
926         if (rc != 0)
927                 return rc;
928
929         receive_len = midQ->resp_buf->smb_buf_length;
930         if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
931                 cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
932                         receive_len, xid);
933                 rc = -EIO;
934                 goto out;
935         }
936
937         /* rcvd frame is ok */
938
939         if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
940                 rc = -EIO;
941                 cERROR(1, "Bad MID state?");
942                 goto out;
943         }
944
945         out_buf->smb_buf_length = receive_len;
946         memcpy((char *)out_buf + 4,
947                (char *)midQ->resp_buf + 4,
948                receive_len);
949
950         dump_smb(out_buf, 92);
951         /* convert the length into a more usable form */
952         if ((receive_len > 24) &&
953             (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
954                                      SECMODE_SIGN_ENABLED))) {
955                 rc = cifs_verify_signature(out_buf,
956                                            ses->server,
957                                            midQ->sequence_number+1);
958                 if (rc) {
959                         cERROR(1, "Unexpected SMB signature");
960                         /* BB FIXME add code to kill session */
961                 }
962         }
963
964         *pbytes_returned = out_buf->smb_buf_length;
965
966         /* BB special case reconnect tid and uid here? */
967         rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
968
969         /* convert ByteCount if necessary */
970         if (receive_len >= sizeof(struct smb_hdr) - 4
971             /* do not count RFC1001 header */  +
972             (2 * out_buf->WordCount) + 2 /* bcc */ )
973                 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
974
975 out:
976         delete_mid(midQ);
977         if (rstart && rc == -EACCES)
978                 return -ERESTARTSYS;
979         return rc;
980 }