[CIFS] Rename three structures to avoid camel case
[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);
131afd0b 269#ifdef CONFIG_CIFS_STATS2
c5797a94 270 atomic_inc(&server->num_waiters);
131afd0b 271#endif
c5797a94
JL
272 wait_event(server->request_q,
273 atomic_read(&server->inFlight)
27a97a61 274 < cifs_max_pending);
131afd0b 275#ifdef CONFIG_CIFS_STATS2
c5797a94 276 atomic_dec(&server->num_waiters);
131afd0b 277#endif
27a97a61
VL
278 spin_lock(&GlobalMid_Lock);
279 } else {
c5797a94 280 if (server->tcpStatus == CifsExiting) {
1da177e4 281 spin_unlock(&GlobalMid_Lock);
27a97a61 282 return -ENOENT;
1da177e4 283 }
27a97a61
VL
284
285 /* can not count locking commands against total
286 as they are allowed to block on server */
287
288 /* update # of requests on the wire to server */
289 if (long_op != CIFS_BLOCKING_OP)
c5797a94 290 atomic_inc(&server->inFlight);
27a97a61
VL
291 spin_unlock(&GlobalMid_Lock);
292 break;
1da177e4
LT
293 }
294 }
7ee1af76
JA
295 return 0;
296}
1da177e4 297
96daf2b0 298static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
7ee1af76
JA
299 struct mid_q_entry **ppmidQ)
300{
1da177e4 301 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 302 return -ENOENT;
8fbbd365
VL
303 }
304
305 if (ses->server->tcpStatus == CifsNeedReconnect) {
b6b38f70 306 cFYI(1, "tcp session dead - return to caller to retry");
7ee1af76 307 return -EAGAIN;
8fbbd365
VL
308 }
309
310 if (ses->status != CifsGood) {
1da177e4 311 /* check if SMB session is bad because we are setting it up */
79a58d1f 312 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 313 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 314 return -EAGAIN;
ad7a2926 315 /* else ok - we are setting up session */
1da177e4 316 }
24b9b06b 317 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 318 if (*ppmidQ == NULL)
7ee1af76 319 return -ENOMEM;
ddc8cf8f
JL
320 spin_lock(&GlobalMid_Lock);
321 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
322 spin_unlock(&GlobalMid_Lock);
7ee1af76
JA
323 return 0;
324}
325
0ade640e
JL
326static int
327wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
7ee1af76 328{
0ade640e 329 int error;
7ee1af76 330
0ade640e
JL
331 error = wait_event_killable(server->response_q,
332 midQ->midState != MID_REQUEST_SUBMITTED);
333 if (error < 0)
334 return -ERESTARTSYS;
7ee1af76 335
0ade640e 336 return 0;
7ee1af76
JA
337}
338
133672ef 339
a6827c18
JL
340/*
341 * Send a SMB request and set the callback function in the mid to handle
342 * the result. Caller is responsible for dealing with timeouts.
343 */
344int
fcc31cb6 345cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
59ffd841
JL
346 unsigned int nvec, mid_callback_t *callback, void *cbdata,
347 bool ignore_pend)
a6827c18
JL
348{
349 int rc;
350 struct mid_q_entry *mid;
fcc31cb6 351 struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
a6827c18 352
59ffd841 353 rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0);
a6827c18
JL
354 if (rc)
355 return rc;
356
e3f0dadb 357 /* enable signing if server requires it */
96daf2b0 358 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
fcc31cb6 359 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
e3f0dadb 360
a6827c18 361 mutex_lock(&server->srv_mutex);
fcc31cb6 362 mid = AllocMidQEntry(hdr, server);
a6827c18
JL
363 if (mid == NULL) {
364 mutex_unlock(&server->srv_mutex);
365 return -ENOMEM;
366 }
367
368 /* put it on the pending_mid_q */
369 spin_lock(&GlobalMid_Lock);
370 list_add_tail(&mid->qhead, &server->pending_mid_q);
371 spin_unlock(&GlobalMid_Lock);
372
fcc31cb6 373 rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
a6827c18
JL
374 if (rc) {
375 mutex_unlock(&server->srv_mutex);
376 goto out_err;
377 }
378
379 mid->callback = callback;
380 mid->callback_data = cbdata;
381 mid->midState = MID_REQUEST_SUBMITTED;
382#ifdef CONFIG_CIFS_STATS2
383 atomic_inc(&server->inSend);
384#endif
fcc31cb6 385 rc = smb_sendv(server, iov, nvec);
a6827c18
JL
386#ifdef CONFIG_CIFS_STATS2
387 atomic_dec(&server->inSend);
388 mid->when_sent = jiffies;
389#endif
390 mutex_unlock(&server->srv_mutex);
391 if (rc)
392 goto out_err;
393
394 return rc;
395out_err:
396 delete_mid(mid);
397 atomic_dec(&server->inFlight);
398 wake_up(&server->request_q);
399 return rc;
400}
401
133672ef
SF
402/*
403 *
404 * Send an SMB Request. No response info (other than return code)
405 * needs to be parsed.
406 *
407 * flags indicate the type of request buffer and how long to wait
408 * and whether to log NT STATUS code (error) before mapping it to POSIX error
409 *
410 */
411int
96daf2b0 412SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
133672ef
SF
413 struct smb_hdr *in_buf, int flags)
414{
415 int rc;
416 struct kvec iov[1];
417 int resp_buf_type;
418
419 iov[0].iov_base = (char *)in_buf;
be8e3b00 420 iov[0].iov_len = be32_to_cpu(in_buf->smb_buf_length) + 4;
133672ef
SF
421 flags |= CIFS_NO_RESP;
422 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
b6b38f70 423 cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
90c81e0b 424
133672ef
SF
425 return rc;
426}
427
053d5034 428static int
3c1105df 429cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
053d5034
JL
430{
431 int rc = 0;
432
74dd92a8
JL
433 cFYI(1, "%s: cmd=%d mid=%d state=%d", __func__, mid->command,
434 mid->mid, mid->midState);
053d5034 435
74dd92a8
JL
436 spin_lock(&GlobalMid_Lock);
437 switch (mid->midState) {
438 case MID_RESPONSE_RECEIVED:
053d5034
JL
439 spin_unlock(&GlobalMid_Lock);
440 return rc;
74dd92a8
JL
441 case MID_RETRY_NEEDED:
442 rc = -EAGAIN;
443 break;
71823baf
JL
444 case MID_RESPONSE_MALFORMED:
445 rc = -EIO;
446 break;
3c1105df
JL
447 case MID_SHUTDOWN:
448 rc = -EHOSTDOWN;
449 break;
74dd92a8 450 default:
3c1105df 451 list_del_init(&mid->qhead);
74dd92a8
JL
452 cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
453 mid->mid, mid->midState);
454 rc = -EIO;
053d5034
JL
455 }
456 spin_unlock(&GlobalMid_Lock);
457
2b84a36c 458 DeleteMidQEntry(mid);
053d5034
JL
459 return rc;
460}
461
76dcc26f
JL
462/*
463 * An NT cancel request header looks just like the original request except:
464 *
465 * The Command is SMB_COM_NT_CANCEL
466 * The WordCount is zeroed out
467 * The ByteCount is zeroed out
468 *
469 * This function mangles an existing request buffer into a
470 * SMB_COM_NT_CANCEL request and then sends it.
471 */
472static int
473send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
474 struct mid_q_entry *mid)
475{
476 int rc = 0;
477
478 /* -4 for RFC1001 length and +2 for BCC field */
be8e3b00 479 in_buf->smb_buf_length = cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2);
76dcc26f
JL
480 in_buf->Command = SMB_COM_NT_CANCEL;
481 in_buf->WordCount = 0;
820a803f 482 put_bcc(0, in_buf);
76dcc26f
JL
483
484 mutex_lock(&server->srv_mutex);
485 rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
486 if (rc) {
487 mutex_unlock(&server->srv_mutex);
488 return rc;
489 }
be8e3b00 490 rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
76dcc26f
JL
491 mutex_unlock(&server->srv_mutex);
492
493 cFYI(1, "issued NT_CANCEL for mid %u, rc = %d",
494 in_buf->Mid, rc);
495
496 return rc;
497}
498
2c8f981d
JL
499int
500cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
501 bool log_error)
502{
503 dump_smb(mid->resp_buf,
504 min_t(u32, 92, be32_to_cpu(mid->resp_buf->smb_buf_length)));
505
506 /* convert the length into a more usable form */
96daf2b0 507 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
2c8f981d
JL
508 /* FIXME: add code to kill session */
509 if (cifs_verify_signature(mid->resp_buf, server,
510 mid->sequence_number + 1) != 0)
511 cERROR(1, "Unexpected SMB signature");
512 }
513
514 /* BB special case reconnect tid and uid here? */
515 return map_smb_to_linux_error(mid->resp_buf, log_error);
516}
517
7ee1af76 518int
96daf2b0 519SendReceive2(const unsigned int xid, struct cifs_ses *ses,
79a58d1f 520 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
133672ef 521 const int flags)
7ee1af76
JA
522{
523 int rc = 0;
133672ef 524 int long_op;
7ee1af76
JA
525 struct mid_q_entry *midQ;
526 struct smb_hdr *in_buf = iov[0].iov_base;
50c2f753 527
133672ef
SF
528 long_op = flags & CIFS_TIMEOUT_MASK;
529
7ee1af76
JA
530 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
531
532 if ((ses == NULL) || (ses->server == NULL)) {
533 cifs_small_buf_release(in_buf);
b6b38f70 534 cERROR(1, "Null session");
7ee1af76
JA
535 return -EIO;
536 }
537
79a58d1f 538 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76
JA
539 cifs_small_buf_release(in_buf);
540 return -ENOENT;
541 }
542
79a58d1f 543 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
544 to the same server. We may make this configurable later or
545 use ses->maxReq */
546
c5797a94 547 rc = wait_for_free_request(ses->server, long_op);
7ee1af76
JA
548 if (rc) {
549 cifs_small_buf_release(in_buf);
550 return rc;
551 }
552
79a58d1f 553 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
554 and avoid races inside tcp sendmsg code that could cause corruption
555 of smb data */
556
72ca545b 557 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
558
559 rc = allocate_mid(ses, in_buf, &midQ);
560 if (rc) {
72ca545b 561 mutex_unlock(&ses->server->srv_mutex);
4b8f930f 562 cifs_small_buf_release(in_buf);
7ee1af76 563 /* Update # of requests on wire to server */
79a58d1f 564 atomic_dec(&ses->server->inFlight);
7ee1af76
JA
565 wake_up(&ses->server->request_q);
566 return rc;
1da177e4 567 }
79a58d1f 568 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
829049cb
VL
569 if (rc) {
570 mutex_unlock(&ses->server->srv_mutex);
571 cifs_small_buf_release(in_buf);
572 goto out;
573 }
1da177e4
LT
574
575 midQ->midState = MID_REQUEST_SUBMITTED;
131afd0b
SF
576#ifdef CONFIG_CIFS_STATS2
577 atomic_inc(&ses->server->inSend);
578#endif
0496e02d 579 rc = smb_sendv(ses->server, iov, n_vec);
131afd0b
SF
580#ifdef CONFIG_CIFS_STATS2
581 atomic_dec(&ses->server->inSend);
1047abc1 582 midQ->when_sent = jiffies;
131afd0b 583#endif
7ee1af76 584
72ca545b 585 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 586
2db7c581
JL
587 if (rc < 0) {
588 cifs_small_buf_release(in_buf);
7ee1af76 589 goto out;
2db7c581 590 }
4b8f930f 591
2db7c581
JL
592 if (long_op == CIFS_ASYNC_OP) {
593 cifs_small_buf_release(in_buf);
133672ef 594 goto out;
2db7c581 595 }
d6e04ae6 596
0ade640e 597 rc = wait_for_response(ses->server, midQ);
1be912dd 598 if (rc != 0) {
2db7c581 599 send_nt_cancel(ses->server, in_buf, midQ);
1be912dd
JL
600 spin_lock(&GlobalMid_Lock);
601 if (midQ->midState == MID_REQUEST_SUBMITTED) {
602 midQ->callback = DeleteMidQEntry;
603 spin_unlock(&GlobalMid_Lock);
2db7c581 604 cifs_small_buf_release(in_buf);
1be912dd
JL
605 atomic_dec(&ses->server->inFlight);
606 wake_up(&ses->server->request_q);
607 return rc;
608 }
609 spin_unlock(&GlobalMid_Lock);
610 }
d6e04ae6 611
2db7c581
JL
612 cifs_small_buf_release(in_buf);
613
3c1105df 614 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 615 if (rc != 0) {
79a58d1f 616 atomic_dec(&ses->server->inFlight);
7ee1af76 617 wake_up(&ses->server->request_q);
d6e04ae6
SF
618 return rc;
619 }
50c2f753 620
2c8f981d 621 if (!midQ->resp_buf || midQ->midState != MID_RESPONSE_RECEIVED) {
d6e04ae6 622 rc = -EIO;
2c8f981d 623 cFYI(1, "Bad MID state?");
2b2bdfba
SF
624 goto out;
625 }
626
2c8f981d
JL
627 iov[0].iov_base = (char *)midQ->resp_buf;
628 iov[0].iov_len = be32_to_cpu(midQ->resp_buf->smb_buf_length) + 4;
629 if (midQ->largeBuf)
630 *pRespBufType = CIFS_LARGE_BUFFER;
631 else
632 *pRespBufType = CIFS_SMALL_BUFFER;
2b2bdfba 633
2c8f981d 634 rc = cifs_check_receive(midQ, ses->server, flags & CIFS_LOG_ERROR);
1da177e4 635
2c8f981d
JL
636 /* mark it so buf will not be freed by delete_mid */
637 if ((flags & CIFS_NO_RESP) == 0)
638 midQ->resp_buf = NULL;
7ee1af76 639out:
ddc8cf8f 640 delete_mid(midQ);
79a58d1f 641 atomic_dec(&ses->server->inFlight);
7ee1af76 642 wake_up(&ses->server->request_q);
1da177e4 643
d6e04ae6
SF
644 return rc;
645}
1da177e4
LT
646
647int
96daf2b0 648SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4
LT
649 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
650 int *pbytes_returned, const int long_op)
651{
652 int rc = 0;
1da177e4
LT
653 struct mid_q_entry *midQ;
654
655 if (ses == NULL) {
b6b38f70 656 cERROR(1, "Null smb session");
1da177e4
LT
657 return -EIO;
658 }
79a58d1f 659 if (ses->server == NULL) {
b6b38f70 660 cERROR(1, "Null tcp session");
1da177e4
LT
661 return -EIO;
662 }
663
79a58d1f 664 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
665 return -ENOENT;
666
79a58d1f 667 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
668 to the same server. We may make this configurable later or
669 use ses->maxReq */
1da177e4 670
be8e3b00
SF
671 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
672 MAX_CIFS_HDR_SIZE - 4) {
b6b38f70 673 cERROR(1, "Illegal length, greater than maximum frame, %d",
be8e3b00 674 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
675 return -EIO;
676 }
677
c5797a94 678 rc = wait_for_free_request(ses->server, long_op);
7ee1af76
JA
679 if (rc)
680 return rc;
681
79a58d1f 682 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
683 and avoid races inside tcp sendmsg code that could cause corruption
684 of smb data */
685
72ca545b 686 mutex_lock(&ses->server->srv_mutex);
1da177e4 687
7ee1af76
JA
688 rc = allocate_mid(ses, in_buf, &midQ);
689 if (rc) {
72ca545b 690 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 691 /* Update # of requests on wire to server */
79a58d1f 692 atomic_dec(&ses->server->inFlight);
7ee1af76
JA
693 wake_up(&ses->server->request_q);
694 return rc;
1da177e4
LT
695 }
696
ad009ac9 697 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
698 if (rc) {
699 mutex_unlock(&ses->server->srv_mutex);
700 goto out;
701 }
1da177e4
LT
702
703 midQ->midState = MID_REQUEST_SUBMITTED;
131afd0b
SF
704#ifdef CONFIG_CIFS_STATS2
705 atomic_inc(&ses->server->inSend);
706#endif
be8e3b00 707 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
131afd0b
SF
708#ifdef CONFIG_CIFS_STATS2
709 atomic_dec(&ses->server->inSend);
1047abc1 710 midQ->when_sent = jiffies;
131afd0b 711#endif
72ca545b 712 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 713
79a58d1f 714 if (rc < 0)
7ee1af76
JA
715 goto out;
716
0ade640e 717 if (long_op == CIFS_ASYNC_OP)
7ee1af76 718 goto out;
1da177e4 719
0ade640e 720 rc = wait_for_response(ses->server, midQ);
1be912dd 721 if (rc != 0) {
2db7c581 722 send_nt_cancel(ses->server, in_buf, midQ);
1be912dd
JL
723 spin_lock(&GlobalMid_Lock);
724 if (midQ->midState == MID_REQUEST_SUBMITTED) {
725 /* no longer considered to be "in-flight" */
726 midQ->callback = DeleteMidQEntry;
727 spin_unlock(&GlobalMid_Lock);
728 atomic_dec(&ses->server->inFlight);
729 wake_up(&ses->server->request_q);
730 return rc;
731 }
732 spin_unlock(&GlobalMid_Lock);
733 }
1da177e4 734
3c1105df 735 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 736 if (rc != 0) {
79a58d1f 737 atomic_dec(&ses->server->inFlight);
7ee1af76 738 wake_up(&ses->server->request_q);
1da177e4
LT
739 return rc;
740 }
50c2f753 741
2c8f981d
JL
742 if (!midQ->resp_buf || !out_buf ||
743 midQ->midState != MID_RESPONSE_RECEIVED) {
2b2bdfba 744 rc = -EIO;
b6b38f70 745 cERROR(1, "Bad MID state?");
2c8f981d 746 goto out;
1da177e4 747 }
7ee1af76 748
2c8f981d
JL
749 *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
750 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
751 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 752out:
ddc8cf8f 753 delete_mid(midQ);
79a58d1f 754 atomic_dec(&ses->server->inFlight);
7ee1af76 755 wake_up(&ses->server->request_q);
1da177e4 756
7ee1af76
JA
757 return rc;
758}
1da177e4 759
7ee1af76
JA
760/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
761 blocking lock to return. */
762
763static int
96daf2b0 764send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
765 struct smb_hdr *in_buf,
766 struct smb_hdr *out_buf)
767{
768 int bytes_returned;
96daf2b0 769 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
770 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
771
772 /* We just modify the current in_buf to change
773 the type of lock from LOCKING_ANDX_SHARED_LOCK
774 or LOCKING_ANDX_EXCLUSIVE_LOCK to
775 LOCKING_ANDX_CANCEL_LOCK. */
776
777 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
778 pSMB->Timeout = 0;
779 pSMB->hdr.Mid = GetNextMid(ses->server);
780
781 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 782 &bytes_returned, 0);
7ee1af76
JA
783}
784
785int
96daf2b0 786SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
787 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
788 int *pbytes_returned)
789{
790 int rc = 0;
791 int rstart = 0;
7ee1af76 792 struct mid_q_entry *midQ;
96daf2b0 793 struct cifs_ses *ses;
7ee1af76
JA
794
795 if (tcon == NULL || tcon->ses == NULL) {
b6b38f70 796 cERROR(1, "Null smb session");
7ee1af76
JA
797 return -EIO;
798 }
799 ses = tcon->ses;
800
79a58d1f 801 if (ses->server == NULL) {
b6b38f70 802 cERROR(1, "Null tcp session");
7ee1af76
JA
803 return -EIO;
804 }
805
79a58d1f 806 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
807 return -ENOENT;
808
79a58d1f 809 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
810 to the same server. We may make this configurable later or
811 use ses->maxReq */
812
be8e3b00
SF
813 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
814 MAX_CIFS_HDR_SIZE - 4) {
b6b38f70 815 cERROR(1, "Illegal length, greater than maximum frame, %d",
be8e3b00 816 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
817 return -EIO;
818 }
819
c5797a94 820 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP);
7ee1af76
JA
821 if (rc)
822 return rc;
823
79a58d1f 824 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
825 and avoid races inside tcp sendmsg code that could cause corruption
826 of smb data */
827
72ca545b 828 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
829
830 rc = allocate_mid(ses, in_buf, &midQ);
831 if (rc) {
72ca545b 832 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
833 return rc;
834 }
835
7ee1af76 836 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 837 if (rc) {
ddc8cf8f 838 delete_mid(midQ);
829049cb
VL
839 mutex_unlock(&ses->server->srv_mutex);
840 return rc;
841 }
1da177e4 842
7ee1af76
JA
843 midQ->midState = MID_REQUEST_SUBMITTED;
844#ifdef CONFIG_CIFS_STATS2
845 atomic_inc(&ses->server->inSend);
846#endif
be8e3b00 847 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
7ee1af76
JA
848#ifdef CONFIG_CIFS_STATS2
849 atomic_dec(&ses->server->inSend);
850 midQ->when_sent = jiffies;
851#endif
72ca545b 852 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 853
79a58d1f 854 if (rc < 0) {
ddc8cf8f 855 delete_mid(midQ);
7ee1af76
JA
856 return rc;
857 }
858
859 /* Wait for a reply - allow signals to interrupt. */
860 rc = wait_event_interruptible(ses->server->response_q,
79a58d1f 861 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
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. */
76dcc26f 874 rc = send_nt_cancel(ses->server, in_buf, midQ);
7ee1af76 875 if (rc) {
ddc8cf8f 876 delete_mid(midQ);
7ee1af76
JA
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) {
ddc8cf8f 888 delete_mid(midQ);
7ee1af76
JA
889 return rc;
890 }
891 }
892
1be912dd
JL
893 rc = wait_for_response(ses->server, midQ);
894 if (rc) {
2db7c581 895 send_nt_cancel(ses->server, in_buf, midQ);
1be912dd
JL
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);
7ee1af76 904 }
1be912dd
JL
905
906 /* We got the response - restart system call. */
907 rstart = 1;
7ee1af76
JA
908 }
909
3c1105df 910 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 911 if (rc != 0)
7ee1af76 912 return rc;
50c2f753 913
17c8bfed 914 /* rcvd frame is ok */
2c8f981d 915 if (out_buf == NULL || midQ->midState != MID_RESPONSE_RECEIVED) {
698e96a8 916 rc = -EIO;
b6b38f70 917 cERROR(1, "Bad MID state?");
698e96a8
VL
918 goto out;
919 }
1da177e4 920
2c8f981d
JL
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);
17c8bfed 924out:
ddc8cf8f 925 delete_mid(midQ);
7ee1af76
JA
926 if (rstart && rc == -EACCES)
927 return -ERESTARTSYS;
1da177e4
LT
928 return rc;
929}