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