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