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