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