]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/cifs/transport.c
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
[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/gfp.h>
26 #include <linux/wait.h>
27 #include <linux/net.h>
28 #include <linux/delay.h>
29 #include <linux/freezer.h>
30 #include <asm/uaccess.h>
31 #include <asm/processor.h>
32 #include <linux/mempool.h>
33 #include "cifspdu.h"
34 #include "cifsglob.h"
35 #include "cifsproto.h"
36 #include "cifs_debug.h"
37
38 extern mempool_t *cifs_mid_poolp;
39
40 static void
41 wake_up_task(struct mid_q_entry *mid)
42 {
43         wake_up_process(mid->callback_data);
44 }
45
46 struct mid_q_entry *
47 AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
48 {
49         struct mid_q_entry *temp;
50
51         if (server == NULL) {
52                 cERROR(1, "Null TCP session in AllocMidQEntry");
53                 return NULL;
54         }
55
56         temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
57         if (temp == NULL)
58                 return temp;
59         else {
60                 memset(temp, 0, sizeof(struct mid_q_entry));
61                 temp->mid = smb_buffer->Mid;    /* always LE */
62                 temp->pid = current->pid;
63                 temp->command = smb_buffer->Command;
64                 cFYI(1, "For smb_command %d", temp->command);
65         /*      do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
66                 /* when mid allocated can be before when sent */
67                 temp->when_alloc = jiffies;
68
69                 /*
70                  * The default is for the mid to be synchronous, so the
71                  * default callback just wakes up the current task.
72                  */
73                 temp->callback = wake_up_task;
74                 temp->callback_data = current;
75         }
76
77         atomic_inc(&midCount);
78         temp->midState = MID_REQUEST_ALLOCATED;
79         return temp;
80 }
81
82 void
83 DeleteMidQEntry(struct mid_q_entry *midEntry)
84 {
85 #ifdef CONFIG_CIFS_STATS2
86         unsigned long now;
87 #endif
88         midEntry->midState = MID_FREE;
89         atomic_dec(&midCount);
90         if (midEntry->largeBuf)
91                 cifs_buf_release(midEntry->resp_buf);
92         else
93                 cifs_small_buf_release(midEntry->resp_buf);
94 #ifdef CONFIG_CIFS_STATS2
95         now = jiffies;
96         /* commands taking longer than one second are indications that
97            something is wrong, unless it is quite a slow link or server */
98         if ((now - midEntry->when_alloc) > HZ) {
99                 if ((cifsFYI & CIFS_TIMER) &&
100                    (midEntry->command != SMB_COM_LOCKING_ANDX)) {
101                         printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
102                                midEntry->command, midEntry->mid);
103                         printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
104                                now - midEntry->when_alloc,
105                                now - midEntry->when_sent,
106                                now - midEntry->when_received);
107                 }
108         }
109 #endif
110         mempool_free(midEntry, cifs_mid_poolp);
111 }
112
113 static void
114 delete_mid(struct mid_q_entry *mid)
115 {
116         spin_lock(&GlobalMid_Lock);
117         list_del(&mid->qhead);
118         spin_unlock(&GlobalMid_Lock);
119
120         DeleteMidQEntry(mid);
121 }
122
123 static int
124 smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
125 {
126         int rc = 0;
127         int i = 0;
128         struct msghdr smb_msg;
129         struct smb_hdr *smb_buffer = iov[0].iov_base;
130         unsigned int len = iov[0].iov_len;
131         unsigned int total_len;
132         int first_vec = 0;
133         unsigned int smb_buf_length = be32_to_cpu(smb_buffer->smb_buf_length);
134         struct socket *ssocket = server->ssocket;
135
136         if (ssocket == NULL)
137                 return -ENOTSOCK; /* BB eventually add reconnect code here */
138
139         smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
140         smb_msg.msg_namelen = sizeof(struct sockaddr);
141         smb_msg.msg_control = NULL;
142         smb_msg.msg_controllen = 0;
143         if (server->noblocksnd)
144                 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
145         else
146                 smb_msg.msg_flags = MSG_NOSIGNAL;
147
148         total_len = 0;
149         for (i = 0; i < n_vec; i++)
150                 total_len += iov[i].iov_len;
151
152         cFYI(1, "Sending smb:  total_len %d", total_len);
153         dump_smb(smb_buffer, len);
154
155         i = 0;
156         while (total_len) {
157                 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
158                                     n_vec - first_vec, total_len);
159                 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
160                         i++;
161                         /* if blocking send we try 3 times, since each can block
162                            for 5 seconds. For nonblocking  we have to try more
163                            but wait increasing amounts of time allowing time for
164                            socket to clear.  The overall time we wait in either
165                            case to send on the socket is about 15 seconds.
166                            Similarly we wait for 15 seconds for
167                            a response from the server in SendReceive[2]
168                            for the server to send a response back for
169                            most types of requests (except SMB Write
170                            past end of file which can be slow, and
171                            blocking lock operations). NFS waits slightly longer
172                            than CIFS, but this can make it take longer for
173                            nonresponsive servers to be detected and 15 seconds
174                            is more than enough time for modern networks to
175                            send a packet.  In most cases if we fail to send
176                            after the retries we will kill the socket and
177                            reconnect which may clear the network problem.
178                         */
179                         if ((i >= 14) || (!server->noblocksnd && (i > 2))) {
180                                 cERROR(1, "sends on sock %p stuck for 15 seconds",
181                                     ssocket);
182                                 rc = -EAGAIN;
183                                 break;
184                         }
185                         msleep(1 << i);
186                         continue;
187                 }
188                 if (rc < 0)
189                         break;
190
191                 if (rc == total_len) {
192                         total_len = 0;
193                         break;
194                 } else if (rc > total_len) {
195                         cERROR(1, "sent %d requested %d", rc, total_len);
196                         break;
197                 }
198                 if (rc == 0) {
199                         /* should never happen, letting socket clear before
200                            retrying is our only obvious option here */
201                         cERROR(1, "tcp sent no data");
202                         msleep(500);
203                         continue;
204                 }
205                 total_len -= rc;
206                 /* the line below resets i */
207                 for (i = first_vec; i < n_vec; i++) {
208                         if (iov[i].iov_len) {
209                                 if (rc > iov[i].iov_len) {
210                                         rc -= iov[i].iov_len;
211                                         iov[i].iov_len = 0;
212                                 } else {
213                                         iov[i].iov_base += rc;
214                                         iov[i].iov_len -= rc;
215                                         first_vec = i;
216                                         break;
217                                 }
218                         }
219                 }
220                 i = 0; /* in case we get ENOSPC on the next send */
221         }
222
223         if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
224                 cFYI(1, "partial send (%d remaining), terminating session",
225                         total_len);
226                 /* If we have only sent part of an SMB then the next SMB
227                    could be taken as the remainder of this one.  We need
228                    to kill the socket so the server throws away the partial
229                    SMB */
230                 server->tcpStatus = CifsNeedReconnect;
231         }
232
233         if (rc < 0 && rc != -EINTR)
234                 cERROR(1, "Error %d sending data on socket to server", rc);
235         else
236                 rc = 0;
237
238         /* Don't want to modify the buffer as a
239            side effect of this call. */
240         smb_buffer->smb_buf_length = cpu_to_be32(smb_buf_length);
241
242         return rc;
243 }
244
245 int
246 smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
247          unsigned int smb_buf_length)
248 {
249         struct kvec iov;
250
251         iov.iov_base = smb_buffer;
252         iov.iov_len = smb_buf_length + 4;
253
254         return smb_sendv(server, &iov, 1);
255 }
256
257 static int
258 wait_for_free_credits(struct TCP_Server_Info *server, const int optype,
259                       int *credits)
260 {
261         int rc;
262
263         spin_lock(&server->req_lock);
264         if (optype == CIFS_ASYNC_OP) {
265                 /* oplock breaks must not be held up */
266                 server->in_flight++;
267                 *credits -= 1;
268                 spin_unlock(&server->req_lock);
269                 return 0;
270         }
271
272         while (1) {
273                 if (*credits <= 0) {
274                         spin_unlock(&server->req_lock);
275                         cifs_num_waiters_inc(server);
276                         rc = wait_event_killable(server->request_q,
277                                                  has_credits(server, credits));
278                         cifs_num_waiters_dec(server);
279                         if (rc)
280                                 return rc;
281                         spin_lock(&server->req_lock);
282                 } else {
283                         if (server->tcpStatus == CifsExiting) {
284                                 spin_unlock(&server->req_lock);
285                                 return -ENOENT;
286                         }
287
288                         /*
289                          * Can not count locking commands against total
290                          * as they are allowed to block on server.
291                          */
292
293                         /* update # of requests on the wire to server */
294                         if (optype != CIFS_BLOCKING_OP) {
295                                 *credits -= 1;
296                                 server->in_flight++;
297                         }
298                         spin_unlock(&server->req_lock);
299                         break;
300                 }
301         }
302         return 0;
303 }
304
305 static int
306 wait_for_free_request(struct TCP_Server_Info *server, const int optype)
307 {
308         return wait_for_free_credits(server, optype, get_credits_field(server));
309 }
310
311 static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
312                         struct mid_q_entry **ppmidQ)
313 {
314         if (ses->server->tcpStatus == CifsExiting) {
315                 return -ENOENT;
316         }
317
318         if (ses->server->tcpStatus == CifsNeedReconnect) {
319                 cFYI(1, "tcp session dead - return to caller to retry");
320                 return -EAGAIN;
321         }
322
323         if (ses->status != CifsGood) {
324                 /* check if SMB session is bad because we are setting it up */
325                 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
326                         (in_buf->Command != SMB_COM_NEGOTIATE))
327                         return -EAGAIN;
328                 /* else ok - we are setting up session */
329         }
330         *ppmidQ = AllocMidQEntry(in_buf, ses->server);
331         if (*ppmidQ == NULL)
332                 return -ENOMEM;
333         spin_lock(&GlobalMid_Lock);
334         list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
335         spin_unlock(&GlobalMid_Lock);
336         return 0;
337 }
338
339 static int
340 wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
341 {
342         int error;
343
344         error = wait_event_freezekillable(server->response_q,
345                                     midQ->midState != MID_REQUEST_SUBMITTED);
346         if (error < 0)
347                 return -ERESTARTSYS;
348
349         return 0;
350 }
351
352
353 /*
354  * Send a SMB request and set the callback function in the mid to handle
355  * the result. Caller is responsible for dealing with timeouts.
356  */
357 int
358 cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
359                 unsigned int nvec, mid_receive_t *receive,
360                 mid_callback_t *callback, void *cbdata, bool ignore_pend)
361 {
362         int rc;
363         struct mid_q_entry *mid;
364         struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
365
366         rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0);
367         if (rc)
368                 return rc;
369
370         /* enable signing if server requires it */
371         if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
372                 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
373
374         mutex_lock(&server->srv_mutex);
375         mid = AllocMidQEntry(hdr, server);
376         if (mid == NULL) {
377                 mutex_unlock(&server->srv_mutex);
378                 cifs_add_credits(server, 1);
379                 wake_up(&server->request_q);
380                 return -ENOMEM;
381         }
382
383         /* put it on the pending_mid_q */
384         spin_lock(&GlobalMid_Lock);
385         list_add_tail(&mid->qhead, &server->pending_mid_q);
386         spin_unlock(&GlobalMid_Lock);
387
388         rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
389         if (rc) {
390                 mutex_unlock(&server->srv_mutex);
391                 goto out_err;
392         }
393
394         mid->receive = receive;
395         mid->callback = callback;
396         mid->callback_data = cbdata;
397         mid->midState = MID_REQUEST_SUBMITTED;
398
399         cifs_in_send_inc(server);
400         rc = smb_sendv(server, iov, nvec);
401         cifs_in_send_dec(server);
402         cifs_save_when_sent(mid);
403         mutex_unlock(&server->srv_mutex);
404
405         if (rc)
406                 goto out_err;
407
408         return rc;
409 out_err:
410         delete_mid(mid);
411         cifs_add_credits(server, 1);
412         wake_up(&server->request_q);
413         return rc;
414 }
415
416 /*
417  *
418  * Send an SMB Request.  No response info (other than return code)
419  * needs to be parsed.
420  *
421  * flags indicate the type of request buffer and how long to wait
422  * and whether to log NT STATUS code (error) before mapping it to POSIX error
423  *
424  */
425 int
426 SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
427                 struct smb_hdr *in_buf, int flags)
428 {
429         int rc;
430         struct kvec iov[1];
431         int resp_buf_type;
432
433         iov[0].iov_base = (char *)in_buf;
434         iov[0].iov_len = be32_to_cpu(in_buf->smb_buf_length) + 4;
435         flags |= CIFS_NO_RESP;
436         rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
437         cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
438
439         return rc;
440 }
441
442 static int
443 cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
444 {
445         int rc = 0;
446
447         cFYI(1, "%s: cmd=%d mid=%d state=%d", __func__, mid->command,
448                 mid->mid, mid->midState);
449
450         spin_lock(&GlobalMid_Lock);
451         switch (mid->midState) {
452         case MID_RESPONSE_RECEIVED:
453                 spin_unlock(&GlobalMid_Lock);
454                 return rc;
455         case MID_RETRY_NEEDED:
456                 rc = -EAGAIN;
457                 break;
458         case MID_RESPONSE_MALFORMED:
459                 rc = -EIO;
460                 break;
461         case MID_SHUTDOWN:
462                 rc = -EHOSTDOWN;
463                 break;
464         default:
465                 list_del_init(&mid->qhead);
466                 cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
467                         mid->mid, mid->midState);
468                 rc = -EIO;
469         }
470         spin_unlock(&GlobalMid_Lock);
471
472         DeleteMidQEntry(mid);
473         return rc;
474 }
475
476 /*
477  * An NT cancel request header looks just like the original request except:
478  *
479  * The Command is SMB_COM_NT_CANCEL
480  * The WordCount is zeroed out
481  * The ByteCount is zeroed out
482  *
483  * This function mangles an existing request buffer into a
484  * SMB_COM_NT_CANCEL request and then sends it.
485  */
486 static int
487 send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
488                 struct mid_q_entry *mid)
489 {
490         int rc = 0;
491
492         /* -4 for RFC1001 length and +2 for BCC field */
493         in_buf->smb_buf_length = cpu_to_be32(sizeof(struct smb_hdr) - 4  + 2);
494         in_buf->Command = SMB_COM_NT_CANCEL;
495         in_buf->WordCount = 0;
496         put_bcc(0, in_buf);
497
498         mutex_lock(&server->srv_mutex);
499         rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
500         if (rc) {
501                 mutex_unlock(&server->srv_mutex);
502                 return rc;
503         }
504         rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
505         mutex_unlock(&server->srv_mutex);
506
507         cFYI(1, "issued NT_CANCEL for mid %u, rc = %d",
508                 in_buf->Mid, rc);
509
510         return rc;
511 }
512
513 int
514 cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
515                    bool log_error)
516 {
517         unsigned int len = be32_to_cpu(mid->resp_buf->smb_buf_length) + 4;
518
519         dump_smb(mid->resp_buf, min_t(u32, 92, len));
520
521         /* convert the length into a more usable form */
522         if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
523                 struct kvec iov;
524
525                 iov.iov_base = mid->resp_buf;
526                 iov.iov_len = len;
527                 /* FIXME: add code to kill session */
528                 if (cifs_verify_signature(&iov, 1, server,
529                                           mid->sequence_number + 1) != 0)
530                         cERROR(1, "Unexpected SMB signature");
531         }
532
533         /* BB special case reconnect tid and uid here? */
534         return map_smb_to_linux_error(mid->resp_buf, log_error);
535 }
536
537 int
538 SendReceive2(const unsigned int xid, struct cifs_ses *ses,
539              struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
540              const int flags)
541 {
542         int rc = 0;
543         int long_op;
544         struct mid_q_entry *midQ;
545         struct smb_hdr *in_buf = iov[0].iov_base;
546
547         long_op = flags & CIFS_TIMEOUT_MASK;
548
549         *pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */
550
551         if ((ses == NULL) || (ses->server == NULL)) {
552                 cifs_small_buf_release(in_buf);
553                 cERROR(1, "Null session");
554                 return -EIO;
555         }
556
557         if (ses->server->tcpStatus == CifsExiting) {
558                 cifs_small_buf_release(in_buf);
559                 return -ENOENT;
560         }
561
562         /* Ensure that we do not send more than 50 overlapping requests
563            to the same server. We may make this configurable later or
564            use ses->maxReq */
565
566         rc = wait_for_free_request(ses->server, long_op);
567         if (rc) {
568                 cifs_small_buf_release(in_buf);
569                 return rc;
570         }
571
572         /* make sure that we sign in the same order that we send on this socket
573            and avoid races inside tcp sendmsg code that could cause corruption
574            of smb data */
575
576         mutex_lock(&ses->server->srv_mutex);
577
578         rc = allocate_mid(ses, in_buf, &midQ);
579         if (rc) {
580                 mutex_unlock(&ses->server->srv_mutex);
581                 cifs_small_buf_release(in_buf);
582                 /* Update # of requests on wire to server */
583                 cifs_add_credits(ses->server, 1);
584                 return rc;
585         }
586         rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
587         if (rc) {
588                 mutex_unlock(&ses->server->srv_mutex);
589                 cifs_small_buf_release(in_buf);
590                 goto out;
591         }
592
593         midQ->midState = MID_REQUEST_SUBMITTED;
594         cifs_in_send_inc(ses->server);
595         rc = smb_sendv(ses->server, iov, n_vec);
596         cifs_in_send_dec(ses->server);
597         cifs_save_when_sent(midQ);
598
599         mutex_unlock(&ses->server->srv_mutex);
600
601         if (rc < 0) {
602                 cifs_small_buf_release(in_buf);
603                 goto out;
604         }
605
606         if (long_op == CIFS_ASYNC_OP) {
607                 cifs_small_buf_release(in_buf);
608                 goto out;
609         }
610
611         rc = wait_for_response(ses->server, midQ);
612         if (rc != 0) {
613                 send_nt_cancel(ses->server, in_buf, midQ);
614                 spin_lock(&GlobalMid_Lock);
615                 if (midQ->midState == MID_REQUEST_SUBMITTED) {
616                         midQ->callback = DeleteMidQEntry;
617                         spin_unlock(&GlobalMid_Lock);
618                         cifs_small_buf_release(in_buf);
619                         cifs_add_credits(ses->server, 1);
620                         return rc;
621                 }
622                 spin_unlock(&GlobalMid_Lock);
623         }
624
625         cifs_small_buf_release(in_buf);
626
627         rc = cifs_sync_mid_result(midQ, ses->server);
628         if (rc != 0) {
629                 cifs_add_credits(ses->server, 1);
630                 return rc;
631         }
632
633         if (!midQ->resp_buf || midQ->midState != MID_RESPONSE_RECEIVED) {
634                 rc = -EIO;
635                 cFYI(1, "Bad MID state?");
636                 goto out;
637         }
638
639         iov[0].iov_base = (char *)midQ->resp_buf;
640         iov[0].iov_len = be32_to_cpu(midQ->resp_buf->smb_buf_length) + 4;
641         if (midQ->largeBuf)
642                 *pRespBufType = CIFS_LARGE_BUFFER;
643         else
644                 *pRespBufType = CIFS_SMALL_BUFFER;
645
646         rc = cifs_check_receive(midQ, ses->server, flags & CIFS_LOG_ERROR);
647
648         /* mark it so buf will not be freed by delete_mid */
649         if ((flags & CIFS_NO_RESP) == 0)
650                 midQ->resp_buf = NULL;
651 out:
652         delete_mid(midQ);
653         cifs_add_credits(ses->server, 1);
654
655         return rc;
656 }
657
658 int
659 SendReceive(const unsigned int xid, struct cifs_ses *ses,
660             struct smb_hdr *in_buf, struct smb_hdr *out_buf,
661             int *pbytes_returned, const int long_op)
662 {
663         int rc = 0;
664         struct mid_q_entry *midQ;
665
666         if (ses == NULL) {
667                 cERROR(1, "Null smb session");
668                 return -EIO;
669         }
670         if (ses->server == NULL) {
671                 cERROR(1, "Null tcp session");
672                 return -EIO;
673         }
674
675         if (ses->server->tcpStatus == CifsExiting)
676                 return -ENOENT;
677
678         /* Ensure that we do not send more than 50 overlapping requests
679            to the same server. We may make this configurable later or
680            use ses->maxReq */
681
682         if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
683                         MAX_CIFS_HDR_SIZE - 4) {
684                 cERROR(1, "Illegal length, greater than maximum frame, %d",
685                            be32_to_cpu(in_buf->smb_buf_length));
686                 return -EIO;
687         }
688
689         rc = wait_for_free_request(ses->server, long_op);
690         if (rc)
691                 return rc;
692
693         /* make sure that we sign in the same order that we send on this socket
694            and avoid races inside tcp sendmsg code that could cause corruption
695            of smb data */
696
697         mutex_lock(&ses->server->srv_mutex);
698
699         rc = allocate_mid(ses, in_buf, &midQ);
700         if (rc) {
701                 mutex_unlock(&ses->server->srv_mutex);
702                 /* Update # of requests on wire to server */
703                 cifs_add_credits(ses->server, 1);
704                 return rc;
705         }
706
707         rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
708         if (rc) {
709                 mutex_unlock(&ses->server->srv_mutex);
710                 goto out;
711         }
712
713         midQ->midState = MID_REQUEST_SUBMITTED;
714
715         cifs_in_send_inc(ses->server);
716         rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
717         cifs_in_send_dec(ses->server);
718         cifs_save_when_sent(midQ);
719         mutex_unlock(&ses->server->srv_mutex);
720
721         if (rc < 0)
722                 goto out;
723
724         if (long_op == CIFS_ASYNC_OP)
725                 goto out;
726
727         rc = wait_for_response(ses->server, midQ);
728         if (rc != 0) {
729                 send_nt_cancel(ses->server, in_buf, midQ);
730                 spin_lock(&GlobalMid_Lock);
731                 if (midQ->midState == MID_REQUEST_SUBMITTED) {
732                         /* no longer considered to be "in-flight" */
733                         midQ->callback = DeleteMidQEntry;
734                         spin_unlock(&GlobalMid_Lock);
735                         cifs_add_credits(ses->server, 1);
736                         return rc;
737                 }
738                 spin_unlock(&GlobalMid_Lock);
739         }
740
741         rc = cifs_sync_mid_result(midQ, ses->server);
742         if (rc != 0) {
743                 cifs_add_credits(ses->server, 1);
744                 return rc;
745         }
746
747         if (!midQ->resp_buf || !out_buf ||
748             midQ->midState != MID_RESPONSE_RECEIVED) {
749                 rc = -EIO;
750                 cERROR(1, "Bad MID state?");
751                 goto out;
752         }
753
754         *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
755         memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
756         rc = cifs_check_receive(midQ, ses->server, 0);
757 out:
758         delete_mid(midQ);
759         cifs_add_credits(ses->server, 1);
760
761         return rc;
762 }
763
764 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
765    blocking lock to return. */
766
767 static int
768 send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
769                         struct smb_hdr *in_buf,
770                         struct smb_hdr *out_buf)
771 {
772         int bytes_returned;
773         struct cifs_ses *ses = tcon->ses;
774         LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
775
776         /* We just modify the current in_buf to change
777            the type of lock from LOCKING_ANDX_SHARED_LOCK
778            or LOCKING_ANDX_EXCLUSIVE_LOCK to
779            LOCKING_ANDX_CANCEL_LOCK. */
780
781         pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
782         pSMB->Timeout = 0;
783         pSMB->hdr.Mid = GetNextMid(ses->server);
784
785         return SendReceive(xid, ses, in_buf, out_buf,
786                         &bytes_returned, 0);
787 }
788
789 int
790 SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
791             struct smb_hdr *in_buf, struct smb_hdr *out_buf,
792             int *pbytes_returned)
793 {
794         int rc = 0;
795         int rstart = 0;
796         struct mid_q_entry *midQ;
797         struct cifs_ses *ses;
798
799         if (tcon == NULL || tcon->ses == NULL) {
800                 cERROR(1, "Null smb session");
801                 return -EIO;
802         }
803         ses = tcon->ses;
804
805         if (ses->server == NULL) {
806                 cERROR(1, "Null tcp session");
807                 return -EIO;
808         }
809
810         if (ses->server->tcpStatus == CifsExiting)
811                 return -ENOENT;
812
813         /* Ensure that we do not send more than 50 overlapping requests
814            to the same server. We may make this configurable later or
815            use ses->maxReq */
816
817         if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
818                         MAX_CIFS_HDR_SIZE - 4) {
819                 cERROR(1, "Illegal length, greater than maximum frame, %d",
820                            be32_to_cpu(in_buf->smb_buf_length));
821                 return -EIO;
822         }
823
824         rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP);
825         if (rc)
826                 return rc;
827
828         /* make sure that we sign in the same order that we send on this socket
829            and avoid races inside tcp sendmsg code that could cause corruption
830            of smb data */
831
832         mutex_lock(&ses->server->srv_mutex);
833
834         rc = allocate_mid(ses, in_buf, &midQ);
835         if (rc) {
836                 mutex_unlock(&ses->server->srv_mutex);
837                 return rc;
838         }
839
840         rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
841         if (rc) {
842                 delete_mid(midQ);
843                 mutex_unlock(&ses->server->srv_mutex);
844                 return rc;
845         }
846
847         midQ->midState = MID_REQUEST_SUBMITTED;
848         cifs_in_send_inc(ses->server);
849         rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
850         cifs_in_send_dec(ses->server);
851         cifs_save_when_sent(midQ);
852         mutex_unlock(&ses->server->srv_mutex);
853
854         if (rc < 0) {
855                 delete_mid(midQ);
856                 return rc;
857         }
858
859         /* Wait for a reply - allow signals to interrupt. */
860         rc = wait_event_interruptible(ses->server->response_q,
861                 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
862                 ((ses->server->tcpStatus != CifsGood) &&
863                  (ses->server->tcpStatus != CifsNew)));
864
865         /* Were we interrupted by a signal ? */
866         if ((rc == -ERESTARTSYS) &&
867                 (midQ->midState == MID_REQUEST_SUBMITTED) &&
868                 ((ses->server->tcpStatus == CifsGood) ||
869                  (ses->server->tcpStatus == CifsNew))) {
870
871                 if (in_buf->Command == SMB_COM_TRANSACTION2) {
872                         /* POSIX lock. We send a NT_CANCEL SMB to cause the
873                            blocking lock to return. */
874                         rc = send_nt_cancel(ses->server, in_buf, midQ);
875                         if (rc) {
876                                 delete_mid(midQ);
877                                 return rc;
878                         }
879                 } else {
880                         /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
881                            to cause the blocking lock to return. */
882
883                         rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
884
885                         /* If we get -ENOLCK back the lock may have
886                            already been removed. Don't exit in this case. */
887                         if (rc && rc != -ENOLCK) {
888                                 delete_mid(midQ);
889                                 return rc;
890                         }
891                 }
892
893                 rc = wait_for_response(ses->server, midQ);
894                 if (rc) {
895                         send_nt_cancel(ses->server, in_buf, midQ);
896                         spin_lock(&GlobalMid_Lock);
897                         if (midQ->midState == MID_REQUEST_SUBMITTED) {
898                                 /* no longer considered to be "in-flight" */
899                                 midQ->callback = DeleteMidQEntry;
900                                 spin_unlock(&GlobalMid_Lock);
901                                 return rc;
902                         }
903                         spin_unlock(&GlobalMid_Lock);
904                 }
905
906                 /* We got the response - restart system call. */
907                 rstart = 1;
908         }
909
910         rc = cifs_sync_mid_result(midQ, ses->server);
911         if (rc != 0)
912                 return rc;
913
914         /* rcvd frame is ok */
915         if (out_buf == NULL || midQ->midState != MID_RESPONSE_RECEIVED) {
916                 rc = -EIO;
917                 cERROR(1, "Bad MID state?");
918                 goto out;
919         }
920
921         *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
922         memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
923         rc = cifs_check_receive(midQ, ses->server, 0);
924 out:
925         delete_mid(midQ);
926         if (rstart && rc == -EACCES)
927                 return -ERESTARTSYS;
928         return rc;
929 }