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