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