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