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