Merge branch 'fixes-jgarzik' of git://git.kernel.org/pub/scm/linux/kernel/git/linvill...
[linux-2.6] / fs / cifs / transport.c
1 /*
2  *   fs/cifs/transport.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2007
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 cifsSesInfo *ses)
41 {
42         struct mid_q_entry *temp;
43
44         if (ses == NULL) {
45                 cERROR(1, ("Null session passed in to AllocMidQEntry"));
46                 return NULL;
47         }
48         if (ses->server == NULL) {
49                 cERROR(1, ("Null TCP session in AllocMidQEntry"));
50                 return NULL;
51         }
52
53         temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,
54                                                     GFP_KERNEL | GFP_NOFS);
55         if (temp == NULL)
56                 return temp;
57         else {
58                 memset(temp, 0, sizeof(struct mid_q_entry));
59                 temp->mid = smb_buffer->Mid;    /* always LE */
60                 temp->pid = current->pid;
61                 temp->command = smb_buffer->Command;
62                 cFYI(1, ("For smb_command %d", temp->command));
63         /*      do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
64                 /* when mid allocated can be before when sent */
65                 temp->when_alloc = jiffies;
66                 temp->ses = ses;
67                 temp->tsk = current;
68         }
69
70         spin_lock(&GlobalMid_Lock);
71         list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
72         atomic_inc(&midCount);
73         temp->midState = MID_REQUEST_ALLOCATED;
74         spin_unlock(&GlobalMid_Lock);
75         return temp;
76 }
77
78 static void
79 DeleteMidQEntry(struct mid_q_entry *midEntry)
80 {
81 #ifdef CONFIG_CIFS_STATS2
82         unsigned long now;
83 #endif
84         spin_lock(&GlobalMid_Lock);
85         midEntry->midState = MID_FREE;
86         list_del(&midEntry->qhead);
87         atomic_dec(&midCount);
88         spin_unlock(&GlobalMid_Lock);
89         if (midEntry->largeBuf)
90                 cifs_buf_release(midEntry->resp_buf);
91         else
92                 cifs_small_buf_release(midEntry->resp_buf);
93 #ifdef CONFIG_CIFS_STATS2
94         now = jiffies;
95         /* commands taking longer than one second are indications that
96            something is wrong, unless it is quite a slow link or server */
97         if ((now - midEntry->when_alloc) > HZ) {
98                 if ((cifsFYI & CIFS_TIMER) &&
99                    (midEntry->command != SMB_COM_LOCKING_ANDX)) {
100                         printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
101                                midEntry->command, midEntry->mid);
102                         printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
103                                now - midEntry->when_alloc,
104                                now - midEntry->when_sent,
105                                now - midEntry->when_received);
106                 }
107         }
108 #endif
109         mempool_free(midEntry, cifs_mid_poolp);
110 }
111
112 struct oplock_q_entry *
113 AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
114 {
115         struct oplock_q_entry *temp;
116         if ((pinode == NULL) || (tcon == NULL)) {
117                 cERROR(1, ("Null parms passed to AllocOplockQEntry"));
118                 return NULL;
119         }
120         temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep,
121                                                        GFP_KERNEL);
122         if (temp == NULL)
123                 return temp;
124         else {
125                 temp->pinode = pinode;
126                 temp->tcon = tcon;
127                 temp->netfid = fid;
128                 spin_lock(&GlobalMid_Lock);
129                 list_add_tail(&temp->qhead, &GlobalOplock_Q);
130                 spin_unlock(&GlobalMid_Lock);
131         }
132         return temp;
133
134 }
135
136 void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
137 {
138         spin_lock(&GlobalMid_Lock);
139     /* should we check if list empty first? */
140         list_del(&oplockEntry->qhead);
141         spin_unlock(&GlobalMid_Lock);
142         kmem_cache_free(cifs_oplock_cachep, oplockEntry);
143 }
144
145 int
146 smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
147          unsigned int smb_buf_length, struct sockaddr *sin)
148 {
149         int rc = 0;
150         int i = 0;
151         struct msghdr smb_msg;
152         struct kvec iov;
153         unsigned len = smb_buf_length + 4;
154
155         if (ssocket == NULL)
156                 return -ENOTSOCK; /* BB eventually add reconnect code here */
157         iov.iov_base = smb_buffer;
158         iov.iov_len = len;
159
160         smb_msg.msg_name = sin;
161         smb_msg.msg_namelen = sizeof(struct sockaddr);
162         smb_msg.msg_control = NULL;
163         smb_msg.msg_controllen = 0;
164         smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
165
166         /* smb header is converted in header_assemble. bcc and rest of SMB word
167            area, and byte area if necessary, is converted to littleendian in
168            cifssmb.c and RFC1001 len is converted to bigendian in smb_send
169            Flags2 is converted in SendReceive */
170
171         smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
172         cFYI(1, ("Sending smb of length %d", smb_buf_length));
173         dump_smb(smb_buffer, len);
174
175         while (len > 0) {
176                 rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len);
177                 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
178                         i++;
179                 /* smaller timeout here than send2 since smaller size */
180                 /* Although it may not be required, this also is smaller
181                    oplock break time */
182                         if (i > 12) {
183                                 cERROR(1,
184                                    ("sends on sock %p stuck for 7 seconds",
185                                     ssocket));
186                                 rc = -EAGAIN;
187                                 break;
188                         }
189                         msleep(1 << i);
190                         continue;
191                 }
192                 if (rc < 0)
193                         break;
194                 else
195                         i = 0; /* reset i after each successful send */
196                 iov.iov_base += rc;
197                 iov.iov_len -= rc;
198                 len -= rc;
199         }
200
201         if (rc < 0) {
202                 cERROR(1, ("Error %d sending data on socket to server", rc));
203         } else {
204                 rc = 0;
205         }
206
207         /* Don't want to modify the buffer as a
208            side effect of this call. */
209         smb_buffer->smb_buf_length = smb_buf_length;
210
211         return rc;
212 }
213
214 static int
215 smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
216           struct sockaddr *sin)
217 {
218         int rc = 0;
219         int i = 0;
220         struct msghdr smb_msg;
221         struct smb_hdr *smb_buffer = iov[0].iov_base;
222         unsigned int len = iov[0].iov_len;
223         unsigned int total_len;
224         int first_vec = 0;
225         unsigned int smb_buf_length = smb_buffer->smb_buf_length;
226
227         if (ssocket == NULL)
228                 return -ENOTSOCK; /* BB eventually add reconnect code here */
229
230         smb_msg.msg_name = sin;
231         smb_msg.msg_namelen = sizeof(struct sockaddr);
232         smb_msg.msg_control = NULL;
233         smb_msg.msg_controllen = 0;
234         smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
235
236         /* smb header is converted in header_assemble. bcc and rest of SMB word
237            area, and byte area if necessary, is converted to littleendian in
238            cifssmb.c and RFC1001 len is converted to bigendian in smb_send
239            Flags2 is converted in SendReceive */
240
241
242         total_len = 0;
243         for (i = 0; i < n_vec; i++)
244                 total_len += iov[i].iov_len;
245
246         smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
247         cFYI(1, ("Sending smb:  total_len %d", total_len));
248         dump_smb(smb_buffer, len);
249
250         while (total_len) {
251                 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
252                                     n_vec - first_vec, total_len);
253                 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
254                         i++;
255                         if (i >= 14) {
256                                 cERROR(1,
257                                    ("sends on sock %p stuck for 15 seconds",
258                                     ssocket));
259                                 rc = -EAGAIN;
260                                 break;
261                         }
262                         msleep(1 << i);
263                         continue;
264                 }
265                 if (rc < 0)
266                         break;
267
268                 if (rc >= total_len) {
269                         WARN_ON(rc > total_len);
270                         break;
271                 }
272                 if (rc == 0) {
273                         /* should never happen, letting socket clear before
274                            retrying is our only obvious option here */
275                         cERROR(1, ("tcp sent no data"));
276                         msleep(500);
277                         continue;
278                 }
279                 total_len -= rc;
280                 /* the line below resets i */
281                 for (i = first_vec; i < n_vec; i++) {
282                         if (iov[i].iov_len) {
283                                 if (rc > iov[i].iov_len) {
284                                         rc -= iov[i].iov_len;
285                                         iov[i].iov_len = 0;
286                                 } else {
287                                         iov[i].iov_base += rc;
288                                         iov[i].iov_len -= rc;
289                                         first_vec = i;
290                                         break;
291                                 }
292                         }
293                 }
294                 i = 0; /* in case we get ENOSPC on the next send */
295         }
296
297         if (rc < 0) {
298                 cERROR(1, ("Error %d sending data on socket to server", rc));
299         } else
300                 rc = 0;
301
302         /* Don't want to modify the buffer as a
303            side effect of this call. */
304         smb_buffer->smb_buf_length = smb_buf_length;
305
306         return rc;
307 }
308
309 static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
310 {
311         if (long_op == CIFS_ASYNC_OP) {
312                 /* oplock breaks must not be held up */
313                 atomic_inc(&ses->server->inFlight);
314         } else {
315                 spin_lock(&GlobalMid_Lock);
316                 while (1) {
317                         if (atomic_read(&ses->server->inFlight) >=
318                                         cifs_max_pending){
319                                 spin_unlock(&GlobalMid_Lock);
320 #ifdef CONFIG_CIFS_STATS2
321                                 atomic_inc(&ses->server->num_waiters);
322 #endif
323                                 wait_event(ses->server->request_q,
324                                         atomic_read(&ses->server->inFlight)
325                                          < cifs_max_pending);
326 #ifdef CONFIG_CIFS_STATS2
327                                 atomic_dec(&ses->server->num_waiters);
328 #endif
329                                 spin_lock(&GlobalMid_Lock);
330                         } else {
331                                 if (ses->server->tcpStatus == CifsExiting) {
332                                         spin_unlock(&GlobalMid_Lock);
333                                         return -ENOENT;
334                                 }
335
336                                 /* can not count locking commands against total
337                                    as they are allowed to block on server */
338
339                                 /* update # of requests on the wire to server */
340                                 if (long_op != CIFS_BLOCKING_OP)
341                                         atomic_inc(&ses->server->inFlight);
342                                 spin_unlock(&GlobalMid_Lock);
343                                 break;
344                         }
345                 }
346         }
347         return 0;
348 }
349
350 static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
351                         struct mid_q_entry **ppmidQ)
352 {
353         if (ses->server->tcpStatus == CifsExiting) {
354                 return -ENOENT;
355         } else if (ses->server->tcpStatus == CifsNeedReconnect) {
356                 cFYI(1, ("tcp session dead - return to caller to retry"));
357                 return -EAGAIN;
358         } else if (ses->status != CifsGood) {
359                 /* check if SMB session is bad because we are setting it up */
360                 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
361                         (in_buf->Command != SMB_COM_NEGOTIATE)) {
362                         return -EAGAIN;
363                 } /* else ok - we are setting up session */
364         }
365         *ppmidQ = AllocMidQEntry(in_buf, ses);
366         if (*ppmidQ == NULL)
367                 return -ENOMEM;
368         return 0;
369 }
370
371 static int wait_for_response(struct cifsSesInfo *ses,
372                         struct mid_q_entry *midQ,
373                         unsigned long timeout,
374                         unsigned long time_to_wait)
375 {
376         unsigned long curr_timeout;
377
378         for (;;) {
379                 curr_timeout = timeout + jiffies;
380                 wait_event(ses->server->response_q,
381                         (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
382                         time_after(jiffies, curr_timeout) ||
383                         ((ses->server->tcpStatus != CifsGood) &&
384                          (ses->server->tcpStatus != CifsNew)));
385
386                 if (time_after(jiffies, curr_timeout) &&
387                         (midQ->midState == MID_REQUEST_SUBMITTED) &&
388                         ((ses->server->tcpStatus == CifsGood) ||
389                          (ses->server->tcpStatus == CifsNew))) {
390
391                         unsigned long lrt;
392
393                         /* We timed out. Is the server still
394                            sending replies ? */
395                         spin_lock(&GlobalMid_Lock);
396                         lrt = ses->server->lstrp;
397                         spin_unlock(&GlobalMid_Lock);
398
399                         /* Calculate time_to_wait past last receive time.
400                          Although we prefer not to time out if the
401                          server is still responding - we will time
402                          out if the server takes more than 15 (or 45
403                          or 180) seconds to respond to this request
404                          and has not responded to any request from
405                          other threads on the client within 10 seconds */
406                         lrt += time_to_wait;
407                         if (time_after(jiffies, lrt)) {
408                                 /* No replies for time_to_wait. */
409                                 cERROR(1, ("server not responding"));
410                                 return -1;
411                         }
412                 } else {
413                         return 0;
414                 }
415         }
416 }
417
418
419 /*
420  *
421  * Send an SMB Request.  No response info (other than return code)
422  * needs to be parsed.
423  *
424  * flags indicate the type of request buffer and how long to wait
425  * and whether to log NT STATUS code (error) before mapping it to POSIX error
426  *
427  */
428 int
429 SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
430                 struct smb_hdr *in_buf, int flags)
431 {
432         int rc;
433         struct kvec iov[1];
434         int resp_buf_type;
435
436         iov[0].iov_base = (char *)in_buf;
437         iov[0].iov_len = in_buf->smb_buf_length + 4;
438         flags |= CIFS_NO_RESP;
439         rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
440 #ifdef CONFIG_CIFS_DEBUG2
441         cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc));
442 #endif
443         return rc;
444 }
445
446 int
447 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
448              struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
449              const int flags)
450 {
451         int rc = 0;
452         int long_op;
453         unsigned int receive_len;
454         unsigned long timeout;
455         struct mid_q_entry *midQ;
456         struct smb_hdr *in_buf = iov[0].iov_base;
457
458         long_op = flags & CIFS_TIMEOUT_MASK;
459
460         *pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
461
462         if ((ses == NULL) || (ses->server == NULL)) {
463                 cifs_small_buf_release(in_buf);
464                 cERROR(1, ("Null session"));
465                 return -EIO;
466         }
467
468         if (ses->server->tcpStatus == CifsExiting) {
469                 cifs_small_buf_release(in_buf);
470                 return -ENOENT;
471         }
472
473         /* Ensure that we do not send more than 50 overlapping requests
474            to the same server. We may make this configurable later or
475            use ses->maxReq */
476
477         rc = wait_for_free_request(ses, long_op);
478         if (rc) {
479                 cifs_small_buf_release(in_buf);
480                 return rc;
481         }
482
483         /* make sure that we sign in the same order that we send on this socket
484            and avoid races inside tcp sendmsg code that could cause corruption
485            of smb data */
486
487         down(&ses->server->tcpSem);
488
489         rc = allocate_mid(ses, in_buf, &midQ);
490         if (rc) {
491                 up(&ses->server->tcpSem);
492                 cifs_small_buf_release(in_buf);
493                 /* Update # of requests on wire to server */
494                 atomic_dec(&ses->server->inFlight);
495                 wake_up(&ses->server->request_q);
496                 return rc;
497         }
498         rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
499
500         midQ->midState = MID_REQUEST_SUBMITTED;
501 #ifdef CONFIG_CIFS_STATS2
502         atomic_inc(&ses->server->inSend);
503 #endif
504         rc = smb_send2(ses->server->ssocket, iov, n_vec,
505                       (struct sockaddr *) &(ses->server->addr.sockAddr));
506 #ifdef CONFIG_CIFS_STATS2
507         atomic_dec(&ses->server->inSend);
508         midQ->when_sent = jiffies;
509 #endif
510
511         up(&ses->server->tcpSem);
512         cifs_small_buf_release(in_buf);
513
514         if (rc < 0)
515                 goto out;
516
517         if (long_op == CIFS_STD_OP)
518                 timeout = 15 * HZ;
519         else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
520                 timeout = 180 * HZ;
521         else if (long_op == CIFS_LONG_OP)
522                 timeout = 45 * HZ; /* should be greater than
523                         servers oplock break timeout (about 43 seconds) */
524         else if (long_op == CIFS_ASYNC_OP)
525                 goto out;
526         else if (long_op == CIFS_BLOCKING_OP)
527                 timeout = 0x7FFFFFFF; /*  large, but not so large as to wrap */
528         else {
529                 cERROR(1, ("unknown timeout flag %d", long_op));
530                 rc = -EIO;
531                 goto out;
532         }
533
534         /* wait for 15 seconds or until woken up due to response arriving or
535            due to last connection to this server being unmounted */
536         if (signal_pending(current)) {
537                 /* if signal pending do not hold up user for full smb timeout
538                 but we still give response a chance to complete */
539                 timeout = 2 * HZ;
540         }
541
542         /* No user interrupts in wait - wreaks havoc with performance */
543         wait_for_response(ses, midQ, timeout, 10 * HZ);
544
545         spin_lock(&GlobalMid_Lock);
546         if (midQ->resp_buf) {
547                 spin_unlock(&GlobalMid_Lock);
548                 receive_len = midQ->resp_buf->smb_buf_length;
549         } else {
550                 cERROR(1, ("No response to cmd %d mid %d",
551                         midQ->command, midQ->mid));
552                 if (midQ->midState == MID_REQUEST_SUBMITTED) {
553                         if (ses->server->tcpStatus == CifsExiting)
554                                 rc = -EHOSTDOWN;
555                         else {
556                                 ses->server->tcpStatus = CifsNeedReconnect;
557                                 midQ->midState = MID_RETRY_NEEDED;
558                         }
559                 }
560
561                 if (rc != -EHOSTDOWN) {
562                         if (midQ->midState == MID_RETRY_NEEDED) {
563                                 rc = -EAGAIN;
564                                 cFYI(1, ("marking request for retry"));
565                         } else {
566                                 rc = -EIO;
567                         }
568                 }
569                 spin_unlock(&GlobalMid_Lock);
570                 DeleteMidQEntry(midQ);
571                 /* Update # of requests on wire to server */
572                 atomic_dec(&ses->server->inFlight);
573                 wake_up(&ses->server->request_q);
574                 return rc;
575         }
576
577         if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
578                 cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
579                         receive_len, xid));
580                 rc = -EIO;
581         } else {                /* rcvd frame is ok */
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
626 out:
627         DeleteMidQEntry(midQ);
628         atomic_dec(&ses->server->inFlight);
629         wake_up(&ses->server->request_q);
630
631         return rc;
632 }
633
634 int
635 SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
636             struct smb_hdr *in_buf, struct smb_hdr *out_buf,
637             int *pbytes_returned, const int long_op)
638 {
639         int rc = 0;
640         unsigned int receive_len;
641         unsigned long timeout;
642         struct mid_q_entry *midQ;
643
644         if (ses == NULL) {
645                 cERROR(1, ("Null smb session"));
646                 return -EIO;
647         }
648         if (ses->server == NULL) {
649                 cERROR(1, ("Null tcp session"));
650                 return -EIO;
651         }
652
653         if (ses->server->tcpStatus == CifsExiting)
654                 return -ENOENT;
655
656         /* Ensure that we do not send more than 50 overlapping requests
657            to the same server. We may make this configurable later or
658            use ses->maxReq */
659
660         rc = wait_for_free_request(ses, long_op);
661         if (rc)
662                 return rc;
663
664         /* make sure that we sign in the same order that we send on this socket
665            and avoid races inside tcp sendmsg code that could cause corruption
666            of smb data */
667
668         down(&ses->server->tcpSem);
669
670         rc = allocate_mid(ses, in_buf, &midQ);
671         if (rc) {
672                 up(&ses->server->tcpSem);
673                 /* Update # of requests on wire to server */
674                 atomic_dec(&ses->server->inFlight);
675                 wake_up(&ses->server->request_q);
676                 return rc;
677         }
678
679         if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
680                 cERROR(1, ("Illegal length, greater than maximum frame, %d",
681                         in_buf->smb_buf_length));
682                 DeleteMidQEntry(midQ);
683                 up(&ses->server->tcpSem);
684                 /* Update # of requests on wire to server */
685                 atomic_dec(&ses->server->inFlight);
686                 wake_up(&ses->server->request_q);
687                 return -EIO;
688         }
689
690         rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
691
692         midQ->midState = MID_REQUEST_SUBMITTED;
693 #ifdef CONFIG_CIFS_STATS2
694         atomic_inc(&ses->server->inSend);
695 #endif
696         rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
697                       (struct sockaddr *) &(ses->server->addr.sockAddr));
698 #ifdef CONFIG_CIFS_STATS2
699         atomic_dec(&ses->server->inSend);
700         midQ->when_sent = jiffies;
701 #endif
702         up(&ses->server->tcpSem);
703
704         if (rc < 0)
705                 goto out;
706
707         if (long_op == CIFS_STD_OP)
708                 timeout = 15 * HZ;
709         /* wait for 15 seconds or until woken up due to response arriving or
710            due to last connection to this server being unmounted */
711         else if (long_op == CIFS_ASYNC_OP)
712                 goto out;
713         else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
714                 timeout = 180 * HZ;
715         else if (long_op == CIFS_LONG_OP)
716                 timeout = 45 * HZ; /* should be greater than
717                         servers oplock break timeout (about 43 seconds) */
718         else if (long_op == CIFS_BLOCKING_OP)
719                 timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
720         else {
721                 cERROR(1, ("unknown timeout flag %d", long_op));
722                 rc = -EIO;
723                 goto out;
724         }
725
726         if (signal_pending(current)) {
727                 /* if signal pending do not hold up user for full smb timeout
728                 but we still give response a chance to complete */
729                 timeout = 2 * HZ;
730         }
731
732         /* No user interrupts in wait - wreaks havoc with performance */
733         wait_for_response(ses, midQ, timeout, 10 * HZ);
734
735         spin_lock(&GlobalMid_Lock);
736         if (midQ->resp_buf) {
737                 spin_unlock(&GlobalMid_Lock);
738                 receive_len = midQ->resp_buf->smb_buf_length;
739         } else {
740                 cERROR(1, ("No response for cmd %d mid %d",
741                           midQ->command, midQ->mid));
742                 if (midQ->midState == MID_REQUEST_SUBMITTED) {
743                         if (ses->server->tcpStatus == CifsExiting)
744                                 rc = -EHOSTDOWN;
745                         else {
746                                 ses->server->tcpStatus = CifsNeedReconnect;
747                                 midQ->midState = MID_RETRY_NEEDED;
748                         }
749                 }
750
751                 if (rc != -EHOSTDOWN) {
752                         if (midQ->midState == MID_RETRY_NEEDED) {
753                                 rc = -EAGAIN;
754                                 cFYI(1, ("marking request for retry"));
755                         } else {
756                                 rc = -EIO;
757                         }
758                 }
759                 spin_unlock(&GlobalMid_Lock);
760                 DeleteMidQEntry(midQ);
761                 /* Update # of requests on wire to server */
762                 atomic_dec(&ses->server->inFlight);
763                 wake_up(&ses->server->request_q);
764                 return rc;
765         }
766
767         if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
768                 cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
769                         receive_len, xid));
770                 rc = -EIO;
771         } else {                /* 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
810 out:
811         DeleteMidQEntry(midQ);
812         atomic_dec(&ses->server->inFlight);
813         wake_up(&ses->server->request_q);
814
815         return rc;
816 }
817
818 /* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
819
820 static int
821 send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
822                 struct mid_q_entry *midQ)
823 {
824         int rc = 0;
825         struct cifsSesInfo *ses = tcon->ses;
826         __u16 mid = in_buf->Mid;
827
828         header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
829         in_buf->Mid = mid;
830         down(&ses->server->tcpSem);
831         rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
832         if (rc) {
833                 up(&ses->server->tcpSem);
834                 return rc;
835         }
836         rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
837               (struct sockaddr *) &(ses->server->addr.sockAddr));
838         up(&ses->server->tcpSem);
839         return rc;
840 }
841
842 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
843    blocking lock to return. */
844
845 static int
846 send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
847                         struct smb_hdr *in_buf,
848                         struct smb_hdr *out_buf)
849 {
850         int bytes_returned;
851         struct cifsSesInfo *ses = tcon->ses;
852         LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
853
854         /* We just modify the current in_buf to change
855            the type of lock from LOCKING_ANDX_SHARED_LOCK
856            or LOCKING_ANDX_EXCLUSIVE_LOCK to
857            LOCKING_ANDX_CANCEL_LOCK. */
858
859         pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
860         pSMB->Timeout = 0;
861         pSMB->hdr.Mid = GetNextMid(ses->server);
862
863         return SendReceive(xid, ses, in_buf, out_buf,
864                         &bytes_returned, CIFS_STD_OP);
865 }
866
867 int
868 SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
869             struct smb_hdr *in_buf, struct smb_hdr *out_buf,
870             int *pbytes_returned)
871 {
872         int rc = 0;
873         int rstart = 0;
874         unsigned int receive_len;
875         struct mid_q_entry *midQ;
876         struct cifsSesInfo *ses;
877
878         if (tcon == NULL || tcon->ses == NULL) {
879                 cERROR(1, ("Null smb session"));
880                 return -EIO;
881         }
882         ses = tcon->ses;
883
884         if (ses->server == NULL) {
885                 cERROR(1, ("Null tcp session"));
886                 return -EIO;
887         }
888
889         if (ses->server->tcpStatus == CifsExiting)
890                 return -ENOENT;
891
892         /* Ensure that we do not send more than 50 overlapping requests
893            to the same server. We may make this configurable later or
894            use ses->maxReq */
895
896         rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
897         if (rc)
898                 return rc;
899
900         /* make sure that we sign in the same order that we send on this socket
901            and avoid races inside tcp sendmsg code that could cause corruption
902            of smb data */
903
904         down(&ses->server->tcpSem);
905
906         rc = allocate_mid(ses, in_buf, &midQ);
907         if (rc) {
908                 up(&ses->server->tcpSem);
909                 return rc;
910         }
911
912         if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
913                 up(&ses->server->tcpSem);
914                 cERROR(1, ("Illegal length, greater than maximum frame, %d",
915                         in_buf->smb_buf_length));
916                 DeleteMidQEntry(midQ);
917                 return -EIO;
918         }
919
920         rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
921
922         midQ->midState = MID_REQUEST_SUBMITTED;
923 #ifdef CONFIG_CIFS_STATS2
924         atomic_inc(&ses->server->inSend);
925 #endif
926         rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
927                       (struct sockaddr *) &(ses->server->addr.sockAddr));
928 #ifdef CONFIG_CIFS_STATS2
929         atomic_dec(&ses->server->inSend);
930         midQ->when_sent = jiffies;
931 #endif
932         up(&ses->server->tcpSem);
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         } else {                /* rcvd frame is ok */
1015
1016                 if (midQ->resp_buf && out_buf
1017                     && (midQ->midState == MID_RESPONSE_RECEIVED)) {
1018                         out_buf->smb_buf_length = receive_len;
1019                         memcpy((char *)out_buf + 4,
1020                                (char *)midQ->resp_buf + 4,
1021                                receive_len);
1022
1023                         dump_smb(out_buf, 92);
1024                         /* convert the length into a more usable form */
1025                         if ((receive_len > 24) &&
1026                            (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
1027                                         SECMODE_SIGN_ENABLED))) {
1028                                 rc = cifs_verify_signature(out_buf,
1029                                                 &ses->server->mac_signing_key,
1030                                                 midQ->sequence_number+1);
1031                                 if (rc) {
1032                                         cERROR(1, ("Unexpected SMB signature"));
1033                                         /* BB FIXME add code to kill session */
1034                                 }
1035                         }
1036
1037                         *pbytes_returned = out_buf->smb_buf_length;
1038
1039                         /* BB special case reconnect tid and uid here? */
1040                         rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
1041
1042                         /* convert ByteCount if necessary */
1043                         if (receive_len >= sizeof(struct smb_hdr) - 4
1044                             /* do not count RFC1001 header */  +
1045                             (2 * out_buf->WordCount) + 2 /* bcc */ )
1046                                 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
1047                 } else {
1048                         rc = -EIO;
1049                         cERROR(1, ("Bad MID state?"));
1050                 }
1051         }
1052         DeleteMidQEntry(midQ);
1053         if (rstart && rc == -EACCES)
1054                 return -ERESTARTSYS;
1055         return rc;
1056 }