cifs: clean up checkSMB
[linux-block.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{
499 dump_smb(mid->resp_buf,
500 min_t(u32, 92, be32_to_cpu(mid->resp_buf->smb_buf_length)));
501
502 /* convert the length into a more usable form */
96daf2b0 503 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
2c8f981d
JL
504 /* FIXME: add code to kill session */
505 if (cifs_verify_signature(mid->resp_buf, server,
506 mid->sequence_number + 1) != 0)
507 cERROR(1, "Unexpected SMB signature");
508 }
509
510 /* BB special case reconnect tid and uid here? */
511 return map_smb_to_linux_error(mid->resp_buf, log_error);
512}
513
7ee1af76 514int
96daf2b0 515SendReceive2(const unsigned int xid, struct cifs_ses *ses,
79a58d1f 516 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
133672ef 517 const int flags)
7ee1af76
JA
518{
519 int rc = 0;
133672ef 520 int long_op;
7ee1af76
JA
521 struct mid_q_entry *midQ;
522 struct smb_hdr *in_buf = iov[0].iov_base;
50c2f753 523
133672ef
SF
524 long_op = flags & CIFS_TIMEOUT_MASK;
525
7ee1af76
JA
526 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
527
528 if ((ses == NULL) || (ses->server == NULL)) {
529 cifs_small_buf_release(in_buf);
b6b38f70 530 cERROR(1, "Null session");
7ee1af76
JA
531 return -EIO;
532 }
533
79a58d1f 534 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76
JA
535 cifs_small_buf_release(in_buf);
536 return -ENOENT;
537 }
538
79a58d1f 539 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
540 to the same server. We may make this configurable later or
541 use ses->maxReq */
542
c5797a94 543 rc = wait_for_free_request(ses->server, long_op);
7ee1af76
JA
544 if (rc) {
545 cifs_small_buf_release(in_buf);
546 return rc;
547 }
548
79a58d1f 549 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
550 and avoid races inside tcp sendmsg code that could cause corruption
551 of smb data */
552
72ca545b 553 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
554
555 rc = allocate_mid(ses, in_buf, &midQ);
556 if (rc) {
72ca545b 557 mutex_unlock(&ses->server->srv_mutex);
4b8f930f 558 cifs_small_buf_release(in_buf);
7ee1af76 559 /* Update # of requests on wire to server */
79a58d1f 560 atomic_dec(&ses->server->inFlight);
7ee1af76
JA
561 wake_up(&ses->server->request_q);
562 return rc;
1da177e4 563 }
79a58d1f 564 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
829049cb
VL
565 if (rc) {
566 mutex_unlock(&ses->server->srv_mutex);
567 cifs_small_buf_release(in_buf);
568 goto out;
569 }
1da177e4
LT
570
571 midQ->midState = MID_REQUEST_SUBMITTED;
789e6661 572 cifs_in_send_inc(ses->server);
0496e02d 573 rc = smb_sendv(ses->server, iov, n_vec);
789e6661
SF
574 cifs_in_send_dec(ses->server);
575 cifs_save_when_sent(midQ);
7ee1af76 576
72ca545b 577 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 578
2db7c581
JL
579 if (rc < 0) {
580 cifs_small_buf_release(in_buf);
7ee1af76 581 goto out;
2db7c581 582 }
4b8f930f 583
2db7c581
JL
584 if (long_op == CIFS_ASYNC_OP) {
585 cifs_small_buf_release(in_buf);
133672ef 586 goto out;
2db7c581 587 }
d6e04ae6 588
0ade640e 589 rc = wait_for_response(ses->server, midQ);
1be912dd 590 if (rc != 0) {
2db7c581 591 send_nt_cancel(ses->server, in_buf, midQ);
1be912dd
JL
592 spin_lock(&GlobalMid_Lock);
593 if (midQ->midState == MID_REQUEST_SUBMITTED) {
594 midQ->callback = DeleteMidQEntry;
595 spin_unlock(&GlobalMid_Lock);
2db7c581 596 cifs_small_buf_release(in_buf);
1be912dd
JL
597 atomic_dec(&ses->server->inFlight);
598 wake_up(&ses->server->request_q);
599 return rc;
600 }
601 spin_unlock(&GlobalMid_Lock);
602 }
d6e04ae6 603
2db7c581
JL
604 cifs_small_buf_release(in_buf);
605
3c1105df 606 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 607 if (rc != 0) {
79a58d1f 608 atomic_dec(&ses->server->inFlight);
7ee1af76 609 wake_up(&ses->server->request_q);
d6e04ae6
SF
610 return rc;
611 }
50c2f753 612
2c8f981d 613 if (!midQ->resp_buf || midQ->midState != MID_RESPONSE_RECEIVED) {
d6e04ae6 614 rc = -EIO;
2c8f981d 615 cFYI(1, "Bad MID state?");
2b2bdfba
SF
616 goto out;
617 }
618
2c8f981d
JL
619 iov[0].iov_base = (char *)midQ->resp_buf;
620 iov[0].iov_len = be32_to_cpu(midQ->resp_buf->smb_buf_length) + 4;
621 if (midQ->largeBuf)
622 *pRespBufType = CIFS_LARGE_BUFFER;
623 else
624 *pRespBufType = CIFS_SMALL_BUFFER;
2b2bdfba 625
2c8f981d 626 rc = cifs_check_receive(midQ, ses->server, flags & CIFS_LOG_ERROR);
1da177e4 627
2c8f981d
JL
628 /* mark it so buf will not be freed by delete_mid */
629 if ((flags & CIFS_NO_RESP) == 0)
630 midQ->resp_buf = NULL;
7ee1af76 631out:
ddc8cf8f 632 delete_mid(midQ);
79a58d1f 633 atomic_dec(&ses->server->inFlight);
7ee1af76 634 wake_up(&ses->server->request_q);
1da177e4 635
d6e04ae6
SF
636 return rc;
637}
1da177e4
LT
638
639int
96daf2b0 640SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4
LT
641 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
642 int *pbytes_returned, const int long_op)
643{
644 int rc = 0;
1da177e4
LT
645 struct mid_q_entry *midQ;
646
647 if (ses == NULL) {
b6b38f70 648 cERROR(1, "Null smb session");
1da177e4
LT
649 return -EIO;
650 }
79a58d1f 651 if (ses->server == NULL) {
b6b38f70 652 cERROR(1, "Null tcp session");
1da177e4
LT
653 return -EIO;
654 }
655
79a58d1f 656 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
657 return -ENOENT;
658
79a58d1f 659 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
660 to the same server. We may make this configurable later or
661 use ses->maxReq */
1da177e4 662
be8e3b00
SF
663 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
664 MAX_CIFS_HDR_SIZE - 4) {
b6b38f70 665 cERROR(1, "Illegal length, greater than maximum frame, %d",
be8e3b00 666 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
667 return -EIO;
668 }
669
c5797a94 670 rc = wait_for_free_request(ses->server, long_op);
7ee1af76
JA
671 if (rc)
672 return rc;
673
79a58d1f 674 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
675 and avoid races inside tcp sendmsg code that could cause corruption
676 of smb data */
677
72ca545b 678 mutex_lock(&ses->server->srv_mutex);
1da177e4 679
7ee1af76
JA
680 rc = allocate_mid(ses, in_buf, &midQ);
681 if (rc) {
72ca545b 682 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 683 /* Update # of requests on wire to server */
79a58d1f 684 atomic_dec(&ses->server->inFlight);
7ee1af76
JA
685 wake_up(&ses->server->request_q);
686 return rc;
1da177e4
LT
687 }
688
ad009ac9 689 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
690 if (rc) {
691 mutex_unlock(&ses->server->srv_mutex);
692 goto out;
693 }
1da177e4
LT
694
695 midQ->midState = MID_REQUEST_SUBMITTED;
789e6661
SF
696
697 cifs_in_send_inc(ses->server);
be8e3b00 698 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
699 cifs_in_send_dec(ses->server);
700 cifs_save_when_sent(midQ);
72ca545b 701 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 702
79a58d1f 703 if (rc < 0)
7ee1af76
JA
704 goto out;
705
0ade640e 706 if (long_op == CIFS_ASYNC_OP)
7ee1af76 707 goto out;
1da177e4 708
0ade640e 709 rc = wait_for_response(ses->server, midQ);
1be912dd 710 if (rc != 0) {
2db7c581 711 send_nt_cancel(ses->server, in_buf, midQ);
1be912dd
JL
712 spin_lock(&GlobalMid_Lock);
713 if (midQ->midState == MID_REQUEST_SUBMITTED) {
714 /* no longer considered to be "in-flight" */
715 midQ->callback = DeleteMidQEntry;
716 spin_unlock(&GlobalMid_Lock);
717 atomic_dec(&ses->server->inFlight);
718 wake_up(&ses->server->request_q);
719 return rc;
720 }
721 spin_unlock(&GlobalMid_Lock);
722 }
1da177e4 723
3c1105df 724 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 725 if (rc != 0) {
79a58d1f 726 atomic_dec(&ses->server->inFlight);
7ee1af76 727 wake_up(&ses->server->request_q);
1da177e4
LT
728 return rc;
729 }
50c2f753 730
2c8f981d
JL
731 if (!midQ->resp_buf || !out_buf ||
732 midQ->midState != MID_RESPONSE_RECEIVED) {
2b2bdfba 733 rc = -EIO;
b6b38f70 734 cERROR(1, "Bad MID state?");
2c8f981d 735 goto out;
1da177e4 736 }
7ee1af76 737
2c8f981d
JL
738 *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
739 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
740 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 741out:
ddc8cf8f 742 delete_mid(midQ);
79a58d1f 743 atomic_dec(&ses->server->inFlight);
7ee1af76 744 wake_up(&ses->server->request_q);
1da177e4 745
7ee1af76
JA
746 return rc;
747}
1da177e4 748
7ee1af76
JA
749/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
750 blocking lock to return. */
751
752static int
96daf2b0 753send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
754 struct smb_hdr *in_buf,
755 struct smb_hdr *out_buf)
756{
757 int bytes_returned;
96daf2b0 758 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
759 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
760
761 /* We just modify the current in_buf to change
762 the type of lock from LOCKING_ANDX_SHARED_LOCK
763 or LOCKING_ANDX_EXCLUSIVE_LOCK to
764 LOCKING_ANDX_CANCEL_LOCK. */
765
766 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
767 pSMB->Timeout = 0;
768 pSMB->hdr.Mid = GetNextMid(ses->server);
769
770 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 771 &bytes_returned, 0);
7ee1af76
JA
772}
773
774int
96daf2b0 775SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
776 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
777 int *pbytes_returned)
778{
779 int rc = 0;
780 int rstart = 0;
7ee1af76 781 struct mid_q_entry *midQ;
96daf2b0 782 struct cifs_ses *ses;
7ee1af76
JA
783
784 if (tcon == NULL || tcon->ses == NULL) {
b6b38f70 785 cERROR(1, "Null smb session");
7ee1af76
JA
786 return -EIO;
787 }
788 ses = tcon->ses;
789
79a58d1f 790 if (ses->server == NULL) {
b6b38f70 791 cERROR(1, "Null tcp session");
7ee1af76
JA
792 return -EIO;
793 }
794
79a58d1f 795 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
796 return -ENOENT;
797
79a58d1f 798 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
799 to the same server. We may make this configurable later or
800 use ses->maxReq */
801
be8e3b00
SF
802 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
803 MAX_CIFS_HDR_SIZE - 4) {
b6b38f70 804 cERROR(1, "Illegal length, greater than maximum frame, %d",
be8e3b00 805 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
806 return -EIO;
807 }
808
c5797a94 809 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP);
7ee1af76
JA
810 if (rc)
811 return rc;
812
79a58d1f 813 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
814 and avoid races inside tcp sendmsg code that could cause corruption
815 of smb data */
816
72ca545b 817 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
818
819 rc = allocate_mid(ses, in_buf, &midQ);
820 if (rc) {
72ca545b 821 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
822 return rc;
823 }
824
7ee1af76 825 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 826 if (rc) {
ddc8cf8f 827 delete_mid(midQ);
829049cb
VL
828 mutex_unlock(&ses->server->srv_mutex);
829 return rc;
830 }
1da177e4 831
7ee1af76 832 midQ->midState = MID_REQUEST_SUBMITTED;
789e6661 833 cifs_in_send_inc(ses->server);
be8e3b00 834 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
835 cifs_in_send_dec(ses->server);
836 cifs_save_when_sent(midQ);
72ca545b 837 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 838
79a58d1f 839 if (rc < 0) {
ddc8cf8f 840 delete_mid(midQ);
7ee1af76
JA
841 return rc;
842 }
843
844 /* Wait for a reply - allow signals to interrupt. */
845 rc = wait_event_interruptible(ses->server->response_q,
79a58d1f 846 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
847 ((ses->server->tcpStatus != CifsGood) &&
848 (ses->server->tcpStatus != CifsNew)));
849
850 /* Were we interrupted by a signal ? */
851 if ((rc == -ERESTARTSYS) &&
852 (midQ->midState == MID_REQUEST_SUBMITTED) &&
853 ((ses->server->tcpStatus == CifsGood) ||
854 (ses->server->tcpStatus == CifsNew))) {
855
856 if (in_buf->Command == SMB_COM_TRANSACTION2) {
857 /* POSIX lock. We send a NT_CANCEL SMB to cause the
858 blocking lock to return. */
76dcc26f 859 rc = send_nt_cancel(ses->server, in_buf, midQ);
7ee1af76 860 if (rc) {
ddc8cf8f 861 delete_mid(midQ);
7ee1af76
JA
862 return rc;
863 }
864 } else {
865 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
866 to cause the blocking lock to return. */
867
868 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
869
870 /* If we get -ENOLCK back the lock may have
871 already been removed. Don't exit in this case. */
872 if (rc && rc != -ENOLCK) {
ddc8cf8f 873 delete_mid(midQ);
7ee1af76
JA
874 return rc;
875 }
876 }
877
1be912dd
JL
878 rc = wait_for_response(ses->server, midQ);
879 if (rc) {
2db7c581 880 send_nt_cancel(ses->server, in_buf, midQ);
1be912dd
JL
881 spin_lock(&GlobalMid_Lock);
882 if (midQ->midState == MID_REQUEST_SUBMITTED) {
883 /* no longer considered to be "in-flight" */
884 midQ->callback = DeleteMidQEntry;
885 spin_unlock(&GlobalMid_Lock);
886 return rc;
887 }
888 spin_unlock(&GlobalMid_Lock);
7ee1af76 889 }
1be912dd
JL
890
891 /* We got the response - restart system call. */
892 rstart = 1;
7ee1af76
JA
893 }
894
3c1105df 895 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 896 if (rc != 0)
7ee1af76 897 return rc;
50c2f753 898
17c8bfed 899 /* rcvd frame is ok */
2c8f981d 900 if (out_buf == NULL || midQ->midState != MID_RESPONSE_RECEIVED) {
698e96a8 901 rc = -EIO;
b6b38f70 902 cERROR(1, "Bad MID state?");
698e96a8
VL
903 goto out;
904 }
1da177e4 905
2c8f981d
JL
906 *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
907 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
908 rc = cifs_check_receive(midQ, ses->server, 0);
17c8bfed 909out:
ddc8cf8f 910 delete_mid(midQ);
7ee1af76
JA
911 if (rstart && rc == -EACCES)
912 return -ERESTARTSYS;
1da177e4
LT
913 return rc;
914}