cifs: push rfc1002 generation down the stack
[linux-2.6-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>
f06ac72e 29#include <linux/freezer.h>
b8eed283 30#include <linux/tcp.h>
2f8b5444 31#include <linux/bvec.h>
97bc00b3 32#include <linux/highmem.h>
7c0f6ba6 33#include <linux/uaccess.h>
1da177e4
LT
34#include <asm/processor.h>
35#include <linux/mempool.h>
36#include "cifspdu.h"
37#include "cifsglob.h"
38#include "cifsproto.h"
39#include "cifs_debug.h"
8bd68c6e 40#include "smb2proto.h"
9762c2d0 41#include "smbdirect.h"
50c2f753 42
3cecf486
RS
43/* Max number of iovectors we can use off the stack when sending requests. */
44#define CIFS_MAX_IOV_SIZE 8
45
2dc7e1c0
PS
46void
47cifs_wake_up_task(struct mid_q_entry *mid)
2b84a36c
JL
48{
49 wake_up_process(mid->callback_data);
50}
51
a6827c18 52struct mid_q_entry *
24b9b06b 53AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
1da177e4
LT
54{
55 struct mid_q_entry *temp;
56
24b9b06b 57 if (server == NULL) {
f96637be 58 cifs_dbg(VFS, "Null TCP session in AllocMidQEntry\n");
1da177e4
LT
59 return NULL;
60 }
50c2f753 61
232087cb 62 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
a6f74e80
N
63 memset(temp, 0, sizeof(struct mid_q_entry));
64 temp->mid = get_mid(smb_buffer);
65 temp->pid = current->pid;
66 temp->command = cpu_to_le16(smb_buffer->Command);
67 cifs_dbg(FYI, "For smb_command %d\n", smb_buffer->Command);
1047abc1 68 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
a6f74e80
N
69 /* when mid allocated can be before when sent */
70 temp->when_alloc = jiffies;
71 temp->server = server;
2b84a36c 72
a6f74e80
N
73 /*
74 * The default is for the mid to be synchronous, so the
75 * default callback just wakes up the current task.
76 */
77 temp->callback = cifs_wake_up_task;
78 temp->callback_data = current;
1da177e4 79
1da177e4 80 atomic_inc(&midCount);
7c9421e1 81 temp->mid_state = MID_REQUEST_ALLOCATED;
1da177e4
LT
82 return temp;
83}
84
766fdbb5 85void
1da177e4
LT
86DeleteMidQEntry(struct mid_q_entry *midEntry)
87{
1047abc1 88#ifdef CONFIG_CIFS_STATS2
2dc7e1c0 89 __le16 command = midEntry->server->vals->lock_cmd;
1047abc1
SF
90 unsigned long now;
91#endif
7c9421e1 92 midEntry->mid_state = MID_FREE;
8097531a 93 atomic_dec(&midCount);
7c9421e1 94 if (midEntry->large_buf)
b8643e1b
SF
95 cifs_buf_release(midEntry->resp_buf);
96 else
97 cifs_small_buf_release(midEntry->resp_buf);
1047abc1
SF
98#ifdef CONFIG_CIFS_STATS2
99 now = jiffies;
100 /* commands taking longer than one second are indications that
101 something is wrong, unless it is quite a slow link or server */
4328fea7 102 if (time_after(now, midEntry->when_alloc + HZ)) {
2dc7e1c0 103 if ((cifsFYI & CIFS_TIMER) && (midEntry->command != command)) {
0b456f04 104 pr_debug(" CIFS slow rsp: cmd %d mid %llu",
1047abc1 105 midEntry->command, midEntry->mid);
0b456f04 106 pr_info(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
1047abc1
SF
107 now - midEntry->when_alloc,
108 now - midEntry->when_sent,
109 now - midEntry->when_received);
110 }
111 }
112#endif
1da177e4
LT
113 mempool_free(midEntry, cifs_mid_poolp);
114}
115
3c1bf7e4
PS
116void
117cifs_delete_mid(struct mid_q_entry *mid)
ddc8cf8f
JL
118{
119 spin_lock(&GlobalMid_Lock);
120 list_del(&mid->qhead);
121 spin_unlock(&GlobalMid_Lock);
122
123 DeleteMidQEntry(mid);
124}
125
6f49f46b
JL
126/*
127 * smb_send_kvec - send an array of kvecs to the server
128 * @server: Server to send the data to
3ab3f2a1 129 * @smb_msg: Message to send
6f49f46b
JL
130 * @sent: amount of data sent on socket is stored here
131 *
132 * Our basic "send data to server" function. Should be called with srv_mutex
133 * held. The caller is responsible for handling the results.
134 */
d6e04ae6 135static int
3ab3f2a1
AV
136smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
137 size_t *sent)
1da177e4
LT
138{
139 int rc = 0;
3ab3f2a1 140 int retries = 0;
edf1ae40 141 struct socket *ssocket = server->ssocket;
50c2f753 142
6f49f46b
JL
143 *sent = 0;
144
3ab3f2a1
AV
145 smb_msg->msg_name = (struct sockaddr *) &server->dstaddr;
146 smb_msg->msg_namelen = sizeof(struct sockaddr);
147 smb_msg->msg_control = NULL;
148 smb_msg->msg_controllen = 0;
0496e02d 149 if (server->noblocksnd)
3ab3f2a1 150 smb_msg->msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
edf1ae40 151 else
3ab3f2a1 152 smb_msg->msg_flags = MSG_NOSIGNAL;
1da177e4 153
3ab3f2a1 154 while (msg_data_left(smb_msg)) {
6f49f46b
JL
155 /*
156 * If blocking send, we try 3 times, since each can block
157 * for 5 seconds. For nonblocking we have to try more
158 * but wait increasing amounts of time allowing time for
159 * socket to clear. The overall time we wait in either
160 * case to send on the socket is about 15 seconds.
161 * Similarly we wait for 15 seconds for a response from
162 * the server in SendReceive[2] for the server to send
163 * a response back for most types of requests (except
164 * SMB Write past end of file which can be slow, and
165 * blocking lock operations). NFS waits slightly longer
166 * than CIFS, but this can make it take longer for
167 * nonresponsive servers to be detected and 15 seconds
168 * is more than enough time for modern networks to
169 * send a packet. In most cases if we fail to send
170 * after the retries we will kill the socket and
171 * reconnect which may clear the network problem.
172 */
3ab3f2a1 173 rc = sock_sendmsg(ssocket, smb_msg);
ce6c44e4 174 if (rc == -EAGAIN) {
3ab3f2a1
AV
175 retries++;
176 if (retries >= 14 ||
177 (!server->noblocksnd && (retries > 2))) {
f96637be
JP
178 cifs_dbg(VFS, "sends on sock %p stuck for 15 seconds\n",
179 ssocket);
3ab3f2a1 180 return -EAGAIN;
1da177e4 181 }
3ab3f2a1 182 msleep(1 << retries);
1da177e4
LT
183 continue;
184 }
6f49f46b 185
79a58d1f 186 if (rc < 0)
3ab3f2a1 187 return rc;
6f49f46b 188
79a58d1f 189 if (rc == 0) {
3e84469d
SF
190 /* should never happen, letting socket clear before
191 retrying is our only obvious option here */
f96637be 192 cifs_dbg(VFS, "tcp sent no data\n");
3e84469d
SF
193 msleep(500);
194 continue;
d6e04ae6 195 }
6f49f46b 196
3ab3f2a1
AV
197 /* send was at least partially successful */
198 *sent += rc;
199 retries = 0; /* in case we get ENOSPC on the next send */
1da177e4 200 }
3ab3f2a1 201 return 0;
97bc00b3
JL
202}
203
a26054d1
JL
204static unsigned long
205rqst_len(struct smb_rqst *rqst)
206{
207 unsigned int i;
208 struct kvec *iov = rqst->rq_iov;
209 unsigned long buflen = 0;
210
211 /* total up iov array first */
212 for (i = 0; i < rqst->rq_nvec; i++)
213 buflen += iov[i].iov_len;
214
c06a0f2d
LL
215 /*
216 * Add in the page array if there is one. The caller needs to make
217 * sure rq_offset and rq_tailsz are set correctly. If a buffer of
218 * multiple pages ends at page boundary, rq_tailsz needs to be set to
219 * PAGE_SIZE.
220 */
a26054d1 221 if (rqst->rq_npages) {
c06a0f2d
LL
222 if (rqst->rq_npages == 1)
223 buflen += rqst->rq_tailsz;
224 else {
225 /*
226 * If there is more than one page, calculate the
227 * buffer length based on rq_offset and rq_tailsz
228 */
229 buflen += rqst->rq_pagesz * (rqst->rq_npages - 1) -
230 rqst->rq_offset;
231 buflen += rqst->rq_tailsz;
232 }
a26054d1
JL
233 }
234
235 return buflen;
236}
237
6f49f46b 238static int
7fb8986e 239__smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
6f49f46b
JL
240{
241 int rc;
242 struct kvec *iov = rqst->rq_iov;
243 int n_vec = rqst->rq_nvec;
c713c877 244 unsigned int send_length;
97bc00b3 245 unsigned int i;
3ab3f2a1 246 size_t total_len = 0, sent, size;
b8eed283 247 struct socket *ssocket = server->ssocket;
3ab3f2a1 248 struct msghdr smb_msg;
b8eed283 249 int val = 1;
c713c877
RS
250 __be32 rfc1002_marker;
251
9762c2d0
LL
252 if (cifs_rdma_enabled(server) && server->smbd_conn) {
253 rc = smbd_send(server->smbd_conn, rqst);
254 goto smbd_done;
255 }
ea702b80
JL
256 if (ssocket == NULL)
257 return -ENOTSOCK;
258
a26054d1 259 send_length = rqst_len(rqst);
c713c877 260 rfc1002_marker = cpu_to_be32(send_length);
6f49f46b 261
b8eed283
JL
262 /* cork the socket */
263 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
264 (char *)&val, sizeof(val));
265
3ab3f2a1 266 size = 0;
c713c877
RS
267 /* Generate a rfc1002 marker for SMB2+ */
268 if (server->vals->header_preamble_size == 0) {
269 struct kvec hiov = {
270 .iov_base = &rfc1002_marker,
271 .iov_len = 4
272 };
273 iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, &hiov,
274 1, 4);
275 rc = smb_send_kvec(server, &smb_msg, &sent);
276 if (rc < 0)
277 goto uncork;
278
279 total_len += sent;
280 send_length += 4;
281 }
282
283 cifs_dbg(FYI, "Sending smb: smb_len=%u\n", send_length);
284 dump_smb(iov[0].iov_base, iov[0].iov_len);
285 dump_smb(iov[1].iov_base, iov[1].iov_len);
286
3ab3f2a1
AV
287 for (i = 0; i < n_vec; i++)
288 size += iov[i].iov_len;
289
290 iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, iov, n_vec, size);
291
292 rc = smb_send_kvec(server, &smb_msg, &sent);
97bc00b3
JL
293 if (rc < 0)
294 goto uncork;
295
296 total_len += sent;
297
298 /* now walk the page array and send each page in it */
299 for (i = 0; i < rqst->rq_npages; i++) {
e8157b27
LL
300 struct bio_vec bvec;
301
302 bvec.bv_page = rqst->rq_pages[i];
303 rqst_page_get_length(rqst, i, &bvec.bv_len, &bvec.bv_offset);
304
3ab3f2a1 305 iov_iter_bvec(&smb_msg.msg_iter, WRITE | ITER_BVEC,
e8157b27 306 &bvec, 1, bvec.bv_len);
3ab3f2a1 307 rc = smb_send_kvec(server, &smb_msg, &sent);
97bc00b3
JL
308 if (rc < 0)
309 break;
310
311 total_len += sent;
312 }
1da177e4 313
97bc00b3 314uncork:
b8eed283
JL
315 /* uncork it */
316 val = 0;
317 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
318 (char *)&val, sizeof(val));
319
c713c877 320 if ((total_len > 0) && (total_len != send_length)) {
f96637be 321 cifs_dbg(FYI, "partial send (wanted=%u sent=%zu): terminating session\n",
c713c877 322 send_length, total_len);
6f49f46b
JL
323 /*
324 * If we have only sent part of an SMB then the next SMB could
325 * be taken as the remainder of this one. We need to kill the
326 * socket so the server throws away the partial SMB
327 */
edf1ae40
SF
328 server->tcpStatus = CifsNeedReconnect;
329 }
9762c2d0 330smbd_done:
d804d41d 331 if (rc < 0 && rc != -EINTR)
f96637be
JP
332 cifs_dbg(VFS, "Error %d sending data on socket to server\n",
333 rc);
d804d41d 334 else
1da177e4 335 rc = 0;
1da177e4
LT
336
337 return rc;
338}
339
6f49f46b 340static int
7fb8986e 341smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags)
6f49f46b 342{
7fb8986e
PS
343 struct smb_rqst cur_rqst;
344 int rc;
345
346 if (!(flags & CIFS_TRANSFORM_REQ))
347 return __smb_send_rqst(server, rqst);
348
349 if (!server->ops->init_transform_rq ||
350 !server->ops->free_transform_rq) {
351 cifs_dbg(VFS, "Encryption requested but transform callbacks are missed\n");
352 return -EIO;
353 }
6f49f46b 354
7fb8986e
PS
355 rc = server->ops->init_transform_rq(server, &cur_rqst, rqst);
356 if (rc)
357 return rc;
358
359 rc = __smb_send_rqst(server, &cur_rqst);
360 server->ops->free_transform_rq(&cur_rqst);
361 return rc;
6f49f46b
JL
362}
363
0496e02d
JL
364int
365smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
366 unsigned int smb_buf_length)
367{
738f9de5 368 struct kvec iov[2];
7fb8986e
PS
369 struct smb_rqst rqst = { .rq_iov = iov,
370 .rq_nvec = 2 };
0496e02d 371
738f9de5
PS
372 iov[0].iov_base = smb_buffer;
373 iov[0].iov_len = 4;
374 iov[1].iov_base = (char *)smb_buffer + 4;
375 iov[1].iov_len = smb_buf_length;
0496e02d 376
7fb8986e 377 return __smb_send_rqst(server, &rqst);
0496e02d
JL
378}
379
fc40f9cf 380static int
a891f0f8 381wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
bc205ed1 382 int *credits)
1da177e4 383{
5bc59498
PS
384 int rc;
385
fc40f9cf 386 spin_lock(&server->req_lock);
a891f0f8 387 if (timeout == CIFS_ASYNC_OP) {
1da177e4 388 /* oplock breaks must not be held up */
fc40f9cf 389 server->in_flight++;
bc205ed1 390 *credits -= 1;
fc40f9cf 391 spin_unlock(&server->req_lock);
27a97a61
VL
392 return 0;
393 }
394
27a97a61 395 while (1) {
bc205ed1 396 if (*credits <= 0) {
fc40f9cf 397 spin_unlock(&server->req_lock);
789e6661 398 cifs_num_waiters_inc(server);
5bc59498 399 rc = wait_event_killable(server->request_q,
bc205ed1 400 has_credits(server, credits));
789e6661 401 cifs_num_waiters_dec(server);
5bc59498
PS
402 if (rc)
403 return rc;
fc40f9cf 404 spin_lock(&server->req_lock);
27a97a61 405 } else {
c5797a94 406 if (server->tcpStatus == CifsExiting) {
fc40f9cf 407 spin_unlock(&server->req_lock);
27a97a61 408 return -ENOENT;
1da177e4 409 }
27a97a61 410
2d86dbc9
PS
411 /*
412 * Can not count locking commands against total
413 * as they are allowed to block on server.
414 */
27a97a61
VL
415
416 /* update # of requests on the wire to server */
a891f0f8 417 if (timeout != CIFS_BLOCKING_OP) {
bc205ed1 418 *credits -= 1;
fc40f9cf 419 server->in_flight++;
2d86dbc9 420 }
fc40f9cf 421 spin_unlock(&server->req_lock);
27a97a61 422 break;
1da177e4
LT
423 }
424 }
7ee1af76
JA
425 return 0;
426}
1da177e4 427
bc205ed1 428static int
a891f0f8
PS
429wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
430 const int optype)
bc205ed1 431{
eb4c7df6
SP
432 int *val;
433
434 val = server->ops->get_credits_field(server, optype);
435 /* Since an echo is already inflight, no need to wait to send another */
436 if (*val <= 0 && optype == CIFS_ECHO_OP)
437 return -EAGAIN;
438 return wait_for_free_credits(server, timeout, val);
bc205ed1
PS
439}
440
cb7e9eab
PS
441int
442cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
443 unsigned int *num, unsigned int *credits)
444{
445 *num = size;
446 *credits = 0;
447 return 0;
448}
449
96daf2b0 450static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
7ee1af76
JA
451 struct mid_q_entry **ppmidQ)
452{
1da177e4 453 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 454 return -ENOENT;
8fbbd365
VL
455 }
456
457 if (ses->server->tcpStatus == CifsNeedReconnect) {
f96637be 458 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
7ee1af76 459 return -EAGAIN;
8fbbd365
VL
460 }
461
7f48558e 462 if (ses->status == CifsNew) {
79a58d1f 463 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 464 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 465 return -EAGAIN;
ad7a2926 466 /* else ok - we are setting up session */
1da177e4 467 }
7f48558e
SP
468
469 if (ses->status == CifsExiting) {
470 /* check if SMB session is bad because we are setting it up */
471 if (in_buf->Command != SMB_COM_LOGOFF_ANDX)
472 return -EAGAIN;
473 /* else ok - we are shutting down session */
474 }
475
24b9b06b 476 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 477 if (*ppmidQ == NULL)
7ee1af76 478 return -ENOMEM;
ddc8cf8f
JL
479 spin_lock(&GlobalMid_Lock);
480 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
481 spin_unlock(&GlobalMid_Lock);
7ee1af76
JA
482 return 0;
483}
484
0ade640e
JL
485static int
486wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
7ee1af76 487{
0ade640e 488 int error;
7ee1af76 489
5853cc2a 490 error = wait_event_freezekillable_unsafe(server->response_q,
7c9421e1 491 midQ->mid_state != MID_REQUEST_SUBMITTED);
0ade640e
JL
492 if (error < 0)
493 return -ERESTARTSYS;
7ee1af76 494
0ade640e 495 return 0;
7ee1af76
JA
496}
497
fec344e3
JL
498struct mid_q_entry *
499cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
792af7b0
PS
500{
501 int rc;
fec344e3 502 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
503 struct mid_q_entry *mid;
504
738f9de5
PS
505 if (rqst->rq_iov[0].iov_len != 4 ||
506 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
507 return ERR_PTR(-EIO);
508
792af7b0 509 /* enable signing if server requires it */
38d77c50 510 if (server->sign)
792af7b0
PS
511 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
512
513 mid = AllocMidQEntry(hdr, server);
514 if (mid == NULL)
fec344e3 515 return ERR_PTR(-ENOMEM);
792af7b0 516
fec344e3 517 rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);
ffc61ccb
SP
518 if (rc) {
519 DeleteMidQEntry(mid);
fec344e3 520 return ERR_PTR(rc);
ffc61ccb
SP
521 }
522
fec344e3 523 return mid;
792af7b0 524}
133672ef 525
a6827c18
JL
526/*
527 * Send a SMB request and set the callback function in the mid to handle
528 * the result. Caller is responsible for dealing with timeouts.
529 */
530int
fec344e3 531cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
9b7c18a2
PS
532 mid_receive_t *receive, mid_callback_t *callback,
533 mid_handle_t *handle, void *cbdata, const int flags)
a6827c18 534{
a891f0f8 535 int rc, timeout, optype;
a6827c18 536 struct mid_q_entry *mid;
cb7e9eab 537 unsigned int credits = 0;
a6827c18 538
a891f0f8
PS
539 timeout = flags & CIFS_TIMEOUT_MASK;
540 optype = flags & CIFS_OP_MASK;
541
cb7e9eab
PS
542 if ((flags & CIFS_HAS_CREDITS) == 0) {
543 rc = wait_for_free_request(server, timeout, optype);
544 if (rc)
545 return rc;
546 credits = 1;
547 }
a6827c18
JL
548
549 mutex_lock(&server->srv_mutex);
fec344e3
JL
550 mid = server->ops->setup_async_request(server, rqst);
551 if (IS_ERR(mid)) {
a6827c18 552 mutex_unlock(&server->srv_mutex);
cb7e9eab 553 add_credits_and_wake_if(server, credits, optype);
fec344e3 554 return PTR_ERR(mid);
a6827c18
JL
555 }
556
44d22d84 557 mid->receive = receive;
a6827c18
JL
558 mid->callback = callback;
559 mid->callback_data = cbdata;
9b7c18a2 560 mid->handle = handle;
7c9421e1 561 mid->mid_state = MID_REQUEST_SUBMITTED;
789e6661 562
ffc61ccb
SP
563 /* put it on the pending_mid_q */
564 spin_lock(&GlobalMid_Lock);
565 list_add_tail(&mid->qhead, &server->pending_mid_q);
566 spin_unlock(&GlobalMid_Lock);
567
93d2cb6c
LL
568 /*
569 * Need to store the time in mid before calling I/O. For call_async,
570 * I/O response may come back and free the mid entry on another thread.
571 */
572 cifs_save_when_sent(mid);
789e6661 573 cifs_in_send_inc(server);
7fb8986e 574 rc = smb_send_rqst(server, rqst, flags);
789e6661 575 cifs_in_send_dec(server);
ad313cb8 576
820962dc 577 if (rc < 0) {
ad313cb8 578 server->sequence_number -= 2;
820962dc
RV
579 cifs_delete_mid(mid);
580 }
581
a6827c18 582 mutex_unlock(&server->srv_mutex);
789e6661 583
ffc61ccb
SP
584 if (rc == 0)
585 return 0;
a6827c18 586
cb7e9eab 587 add_credits_and_wake_if(server, credits, optype);
a6827c18
JL
588 return rc;
589}
590
133672ef
SF
591/*
592 *
593 * Send an SMB Request. No response info (other than return code)
594 * needs to be parsed.
595 *
596 * flags indicate the type of request buffer and how long to wait
597 * and whether to log NT STATUS code (error) before mapping it to POSIX error
598 *
599 */
600int
96daf2b0 601SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
792af7b0 602 char *in_buf, int flags)
133672ef
SF
603{
604 int rc;
605 struct kvec iov[1];
da502f7d 606 struct kvec rsp_iov;
133672ef
SF
607 int resp_buf_type;
608
792af7b0
PS
609 iov[0].iov_base = in_buf;
610 iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
133672ef 611 flags |= CIFS_NO_RESP;
da502f7d 612 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
f96637be 613 cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
90c81e0b 614
133672ef
SF
615 return rc;
616}
617
053d5034 618static int
3c1105df 619cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
053d5034
JL
620{
621 int rc = 0;
622
f96637be
JP
623 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
624 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
053d5034 625
74dd92a8 626 spin_lock(&GlobalMid_Lock);
7c9421e1 627 switch (mid->mid_state) {
74dd92a8 628 case MID_RESPONSE_RECEIVED:
053d5034
JL
629 spin_unlock(&GlobalMid_Lock);
630 return rc;
74dd92a8
JL
631 case MID_RETRY_NEEDED:
632 rc = -EAGAIN;
633 break;
71823baf
JL
634 case MID_RESPONSE_MALFORMED:
635 rc = -EIO;
636 break;
3c1105df
JL
637 case MID_SHUTDOWN:
638 rc = -EHOSTDOWN;
639 break;
74dd92a8 640 default:
3c1105df 641 list_del_init(&mid->qhead);
f96637be
JP
642 cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
643 __func__, mid->mid, mid->mid_state);
74dd92a8 644 rc = -EIO;
053d5034
JL
645 }
646 spin_unlock(&GlobalMid_Lock);
647
2b84a36c 648 DeleteMidQEntry(mid);
053d5034
JL
649 return rc;
650}
651
121b046a 652static inline int
fb2036d8
PS
653send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
654 struct mid_q_entry *mid)
76dcc26f 655{
121b046a 656 return server->ops->send_cancel ?
fb2036d8 657 server->ops->send_cancel(server, rqst, mid) : 0;
76dcc26f
JL
658}
659
2c8f981d
JL
660int
661cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
662 bool log_error)
663{
792af7b0 664 unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
826a95e4
JL
665
666 dump_smb(mid->resp_buf, min_t(u32, 92, len));
2c8f981d
JL
667
668 /* convert the length into a more usable form */
38d77c50 669 if (server->sign) {
738f9de5 670 struct kvec iov[2];
985e4ff0 671 int rc = 0;
738f9de5
PS
672 struct smb_rqst rqst = { .rq_iov = iov,
673 .rq_nvec = 2 };
826a95e4 674
738f9de5
PS
675 iov[0].iov_base = mid->resp_buf;
676 iov[0].iov_len = 4;
677 iov[1].iov_base = (char *)mid->resp_buf + 4;
678 iov[1].iov_len = len - 4;
2c8f981d 679 /* FIXME: add code to kill session */
bf5ea0e2 680 rc = cifs_verify_signature(&rqst, server,
0124cc45 681 mid->sequence_number);
985e4ff0 682 if (rc)
f96637be
JP
683 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
684 rc);
2c8f981d
JL
685 }
686
687 /* BB special case reconnect tid and uid here? */
688 return map_smb_to_linux_error(mid->resp_buf, log_error);
689}
690
fec344e3
JL
691struct mid_q_entry *
692cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
792af7b0
PS
693{
694 int rc;
fec344e3 695 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
696 struct mid_q_entry *mid;
697
738f9de5
PS
698 if (rqst->rq_iov[0].iov_len != 4 ||
699 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
700 return ERR_PTR(-EIO);
701
792af7b0
PS
702 rc = allocate_mid(ses, hdr, &mid);
703 if (rc)
fec344e3
JL
704 return ERR_PTR(rc);
705 rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
706 if (rc) {
3c1bf7e4 707 cifs_delete_mid(mid);
fec344e3
JL
708 return ERR_PTR(rc);
709 }
710 return mid;
792af7b0
PS
711}
712
b8f57ee8 713int
738f9de5
PS
714cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
715 struct smb_rqst *rqst, int *resp_buf_type, const int flags,
716 struct kvec *resp_iov)
7ee1af76
JA
717{
718 int rc = 0;
a891f0f8 719 int timeout, optype;
7ee1af76 720 struct mid_q_entry *midQ;
a891f0f8 721 unsigned int credits = 1;
738f9de5 722 char *buf;
50c2f753 723
a891f0f8
PS
724 timeout = flags & CIFS_TIMEOUT_MASK;
725 optype = flags & CIFS_OP_MASK;
133672ef 726
a891f0f8 727 *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */
7ee1af76
JA
728
729 if ((ses == NULL) || (ses->server == NULL)) {
f96637be 730 cifs_dbg(VFS, "Null session\n");
7ee1af76
JA
731 return -EIO;
732 }
733
da502f7d 734 if (ses->server->tcpStatus == CifsExiting)
7ee1af76 735 return -ENOENT;
7ee1af76 736
792af7b0
PS
737 /*
738 * Ensure that we do not send more than 50 overlapping requests
739 * to the same server. We may make this configurable later or
740 * use ses->maxReq.
741 */
a891f0f8 742 rc = wait_for_free_request(ses->server, timeout, optype);
da502f7d 743 if (rc)
7ee1af76 744 return rc;
7ee1af76 745
792af7b0
PS
746 /*
747 * Make sure that we sign in the same order that we send on this socket
748 * and avoid races inside tcp sendmsg code that could cause corruption
749 * of smb data.
750 */
7ee1af76 751
72ca545b 752 mutex_lock(&ses->server->srv_mutex);
7ee1af76 753
738f9de5 754 midQ = ses->server->ops->setup_request(ses, rqst);
fec344e3 755 if (IS_ERR(midQ)) {
72ca545b 756 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 757 /* Update # of requests on wire to server */
a891f0f8 758 add_credits(ses->server, 1, optype);
fec344e3 759 return PTR_ERR(midQ);
1da177e4 760 }
1da177e4 761
7c9421e1 762 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 763 cifs_in_send_inc(ses->server);
7fb8986e 764 rc = smb_send_rqst(ses->server, rqst, flags);
789e6661
SF
765 cifs_in_send_dec(ses->server);
766 cifs_save_when_sent(midQ);
7ee1af76 767
ad313cb8
JL
768 if (rc < 0)
769 ses->server->sequence_number -= 2;
72ca545b 770 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 771
da502f7d 772 if (rc < 0)
7ee1af76 773 goto out;
4b8f930f 774
8bd68c6e 775#ifdef CONFIG_CIFS_SMB311
0d5ec281 776 if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
c713c877
RS
777 smb311_update_preauth_hash(ses, rqst->rq_iov,
778 rqst->rq_nvec);
8bd68c6e
AA
779#endif
780
da502f7d 781 if (timeout == CIFS_ASYNC_OP)
133672ef 782 goto out;
d6e04ae6 783
0ade640e 784 rc = wait_for_response(ses->server, midQ);
1be912dd 785 if (rc != 0) {
38bd4906 786 cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid);
738f9de5 787 send_cancel(ses->server, rqst, midQ);
1be912dd 788 spin_lock(&GlobalMid_Lock);
7c9421e1 789 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
38bd4906 790 midQ->mid_flags |= MID_WAIT_CANCELLED;
1be912dd
JL
791 midQ->callback = DeleteMidQEntry;
792 spin_unlock(&GlobalMid_Lock);
a891f0f8 793 add_credits(ses->server, 1, optype);
1be912dd
JL
794 return rc;
795 }
796 spin_unlock(&GlobalMid_Lock);
797 }
d6e04ae6 798
3c1105df 799 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 800 if (rc != 0) {
a891f0f8 801 add_credits(ses->server, 1, optype);
d6e04ae6
SF
802 return rc;
803 }
50c2f753 804
7c9421e1 805 if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
d6e04ae6 806 rc = -EIO;
f96637be 807 cifs_dbg(FYI, "Bad MID state?\n");
2b2bdfba
SF
808 goto out;
809 }
810
792af7b0 811 buf = (char *)midQ->resp_buf;
da502f7d 812 resp_iov->iov_base = buf;
e19b2bc0 813 resp_iov->iov_len = midQ->resp_buf_size +
93012bf9 814 ses->server->vals->header_preamble_size;
7c9421e1 815 if (midQ->large_buf)
a891f0f8 816 *resp_buf_type = CIFS_LARGE_BUFFER;
2c8f981d 817 else
a891f0f8
PS
818 *resp_buf_type = CIFS_SMALL_BUFFER;
819
8bd68c6e 820#ifdef CONFIG_CIFS_SMB311
0d5ec281 821 if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
8bd68c6e 822 struct kvec iov = {
c713c877
RS
823 .iov_base = resp_iov->iov_base,
824 .iov_len = resp_iov->iov_len
8bd68c6e
AA
825 };
826 smb311_update_preauth_hash(ses, &iov, 1);
827 }
828#endif
829
a891f0f8 830 credits = ses->server->ops->get_credits(midQ);
2b2bdfba 831
082d0642
PS
832 rc = ses->server->ops->check_receive(midQ, ses->server,
833 flags & CIFS_LOG_ERROR);
1da177e4 834
3c1bf7e4 835 /* mark it so buf will not be freed by cifs_delete_mid */
2c8f981d
JL
836 if ((flags & CIFS_NO_RESP) == 0)
837 midQ->resp_buf = NULL;
7ee1af76 838out:
3c1bf7e4 839 cifs_delete_mid(midQ);
a891f0f8 840 add_credits(ses->server, credits, optype);
1da177e4 841
d6e04ae6
SF
842 return rc;
843}
1da177e4 844
738f9de5
PS
845int
846SendReceive2(const unsigned int xid, struct cifs_ses *ses,
847 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
848 const int flags, struct kvec *resp_iov)
849{
850 struct smb_rqst rqst;
3cecf486 851 struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov;
738f9de5
PS
852 int rc;
853
3cecf486 854 if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
6da2ec56
KC
855 new_iov = kmalloc_array(n_vec + 1, sizeof(struct kvec),
856 GFP_KERNEL);
117e3b7f
SF
857 if (!new_iov) {
858 /* otherwise cifs_send_recv below sets resp_buf_type */
859 *resp_buf_type = CIFS_NO_BUFFER;
3cecf486 860 return -ENOMEM;
117e3b7f 861 }
3cecf486
RS
862 } else
863 new_iov = s_iov;
738f9de5
PS
864
865 /* 1st iov is a RFC1001 length followed by the rest of the packet */
866 memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec));
867
868 new_iov[0].iov_base = new_iov[1].iov_base;
869 new_iov[0].iov_len = 4;
870 new_iov[1].iov_base += 4;
871 new_iov[1].iov_len -= 4;
872
873 memset(&rqst, 0, sizeof(struct smb_rqst));
874 rqst.rq_iov = new_iov;
875 rqst.rq_nvec = n_vec + 1;
876
877 rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
3cecf486
RS
878 if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
879 kfree(new_iov);
738f9de5
PS
880 return rc;
881}
882
83b77391
RS
883/* Like SendReceive2 but iov[0] does not contain an rfc1002 header */
884int
885smb2_send_recv(const unsigned int xid, struct cifs_ses *ses,
886 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
887 const int flags, struct kvec *resp_iov)
888{
889 struct smb_rqst rqst;
83b77391 890 int rc;
83b77391
RS
891
892 memset(&rqst, 0, sizeof(struct smb_rqst));
c713c877
RS
893 rqst.rq_iov = iov;
894 rqst.rq_nvec = n_vec;
83b77391
RS
895
896 rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
83b77391
RS
897 return rc;
898}
899
1da177e4 900int
96daf2b0 901SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4 902 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
a891f0f8 903 int *pbytes_returned, const int timeout)
1da177e4
LT
904{
905 int rc = 0;
1da177e4 906 struct mid_q_entry *midQ;
fb2036d8
PS
907 unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
908 struct kvec iov = { .iov_base = in_buf, .iov_len = len };
909 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
1da177e4
LT
910
911 if (ses == NULL) {
f96637be 912 cifs_dbg(VFS, "Null smb session\n");
1da177e4
LT
913 return -EIO;
914 }
79a58d1f 915 if (ses->server == NULL) {
f96637be 916 cifs_dbg(VFS, "Null tcp session\n");
1da177e4
LT
917 return -EIO;
918 }
919
79a58d1f 920 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
921 return -ENOENT;
922
79a58d1f 923 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
924 to the same server. We may make this configurable later or
925 use ses->maxReq */
1da177e4 926
fb2036d8 927 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
f96637be 928 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
fb2036d8 929 len);
6d9c6d54
VL
930 return -EIO;
931 }
932
a891f0f8 933 rc = wait_for_free_request(ses->server, timeout, 0);
7ee1af76
JA
934 if (rc)
935 return rc;
936
79a58d1f 937 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
938 and avoid races inside tcp sendmsg code that could cause corruption
939 of smb data */
940
72ca545b 941 mutex_lock(&ses->server->srv_mutex);
1da177e4 942
7ee1af76
JA
943 rc = allocate_mid(ses, in_buf, &midQ);
944 if (rc) {
72ca545b 945 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 946 /* Update # of requests on wire to server */
a891f0f8 947 add_credits(ses->server, 1, 0);
7ee1af76 948 return rc;
1da177e4
LT
949 }
950
ad009ac9 951 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
952 if (rc) {
953 mutex_unlock(&ses->server->srv_mutex);
954 goto out;
955 }
1da177e4 956
7c9421e1 957 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661
SF
958
959 cifs_in_send_inc(ses->server);
fb2036d8 960 rc = smb_send(ses->server, in_buf, len);
789e6661
SF
961 cifs_in_send_dec(ses->server);
962 cifs_save_when_sent(midQ);
ad313cb8
JL
963
964 if (rc < 0)
965 ses->server->sequence_number -= 2;
966
72ca545b 967 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 968
79a58d1f 969 if (rc < 0)
7ee1af76
JA
970 goto out;
971
a891f0f8 972 if (timeout == CIFS_ASYNC_OP)
7ee1af76 973 goto out;
1da177e4 974
0ade640e 975 rc = wait_for_response(ses->server, midQ);
1be912dd 976 if (rc != 0) {
fb2036d8 977 send_cancel(ses->server, &rqst, midQ);
1be912dd 978 spin_lock(&GlobalMid_Lock);
7c9421e1 979 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
980 /* no longer considered to be "in-flight" */
981 midQ->callback = DeleteMidQEntry;
982 spin_unlock(&GlobalMid_Lock);
a891f0f8 983 add_credits(ses->server, 1, 0);
1be912dd
JL
984 return rc;
985 }
986 spin_unlock(&GlobalMid_Lock);
987 }
1da177e4 988
3c1105df 989 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 990 if (rc != 0) {
a891f0f8 991 add_credits(ses->server, 1, 0);
1da177e4
LT
992 return rc;
993 }
50c2f753 994
2c8f981d 995 if (!midQ->resp_buf || !out_buf ||
7c9421e1 996 midQ->mid_state != MID_RESPONSE_RECEIVED) {
2b2bdfba 997 rc = -EIO;
f96637be 998 cifs_dbg(VFS, "Bad MID state?\n");
2c8f981d 999 goto out;
1da177e4 1000 }
7ee1af76 1001
d4e4854f 1002 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1003 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1004 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 1005out:
3c1bf7e4 1006 cifs_delete_mid(midQ);
a891f0f8 1007 add_credits(ses->server, 1, 0);
1da177e4 1008
7ee1af76
JA
1009 return rc;
1010}
1da177e4 1011
7ee1af76
JA
1012/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
1013 blocking lock to return. */
1014
1015static int
96daf2b0 1016send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
1017 struct smb_hdr *in_buf,
1018 struct smb_hdr *out_buf)
1019{
1020 int bytes_returned;
96daf2b0 1021 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
1022 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
1023
1024 /* We just modify the current in_buf to change
1025 the type of lock from LOCKING_ANDX_SHARED_LOCK
1026 or LOCKING_ANDX_EXCLUSIVE_LOCK to
1027 LOCKING_ANDX_CANCEL_LOCK. */
1028
1029 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
1030 pSMB->Timeout = 0;
88257360 1031 pSMB->hdr.Mid = get_next_mid(ses->server);
7ee1af76
JA
1032
1033 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 1034 &bytes_returned, 0);
7ee1af76
JA
1035}
1036
1037int
96daf2b0 1038SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
1039 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
1040 int *pbytes_returned)
1041{
1042 int rc = 0;
1043 int rstart = 0;
7ee1af76 1044 struct mid_q_entry *midQ;
96daf2b0 1045 struct cifs_ses *ses;
fb2036d8
PS
1046 unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
1047 struct kvec iov = { .iov_base = in_buf, .iov_len = len };
1048 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
7ee1af76
JA
1049
1050 if (tcon == NULL || tcon->ses == NULL) {
f96637be 1051 cifs_dbg(VFS, "Null smb session\n");
7ee1af76
JA
1052 return -EIO;
1053 }
1054 ses = tcon->ses;
1055
79a58d1f 1056 if (ses->server == NULL) {
f96637be 1057 cifs_dbg(VFS, "Null tcp session\n");
7ee1af76
JA
1058 return -EIO;
1059 }
1060
79a58d1f 1061 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
1062 return -ENOENT;
1063
79a58d1f 1064 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
1065 to the same server. We may make this configurable later or
1066 use ses->maxReq */
1067
fb2036d8 1068 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
f96637be 1069 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
fb2036d8 1070 len);
6d9c6d54
VL
1071 return -EIO;
1072 }
1073
a891f0f8 1074 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0);
7ee1af76
JA
1075 if (rc)
1076 return rc;
1077
79a58d1f 1078 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
1079 and avoid races inside tcp sendmsg code that could cause corruption
1080 of smb data */
1081
72ca545b 1082 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
1083
1084 rc = allocate_mid(ses, in_buf, &midQ);
1085 if (rc) {
72ca545b 1086 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
1087 return rc;
1088 }
1089
7ee1af76 1090 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 1091 if (rc) {
3c1bf7e4 1092 cifs_delete_mid(midQ);
829049cb
VL
1093 mutex_unlock(&ses->server->srv_mutex);
1094 return rc;
1095 }
1da177e4 1096
7c9421e1 1097 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 1098 cifs_in_send_inc(ses->server);
fb2036d8 1099 rc = smb_send(ses->server, in_buf, len);
789e6661
SF
1100 cifs_in_send_dec(ses->server);
1101 cifs_save_when_sent(midQ);
ad313cb8
JL
1102
1103 if (rc < 0)
1104 ses->server->sequence_number -= 2;
1105
72ca545b 1106 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 1107
79a58d1f 1108 if (rc < 0) {
3c1bf7e4 1109 cifs_delete_mid(midQ);
7ee1af76
JA
1110 return rc;
1111 }
1112
1113 /* Wait for a reply - allow signals to interrupt. */
1114 rc = wait_event_interruptible(ses->server->response_q,
7c9421e1 1115 (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
1116 ((ses->server->tcpStatus != CifsGood) &&
1117 (ses->server->tcpStatus != CifsNew)));
1118
1119 /* Were we interrupted by a signal ? */
1120 if ((rc == -ERESTARTSYS) &&
7c9421e1 1121 (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
7ee1af76
JA
1122 ((ses->server->tcpStatus == CifsGood) ||
1123 (ses->server->tcpStatus == CifsNew))) {
1124
1125 if (in_buf->Command == SMB_COM_TRANSACTION2) {
1126 /* POSIX lock. We send a NT_CANCEL SMB to cause the
1127 blocking lock to return. */
fb2036d8 1128 rc = send_cancel(ses->server, &rqst, midQ);
7ee1af76 1129 if (rc) {
3c1bf7e4 1130 cifs_delete_mid(midQ);
7ee1af76
JA
1131 return rc;
1132 }
1133 } else {
1134 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
1135 to cause the blocking lock to return. */
1136
1137 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
1138
1139 /* If we get -ENOLCK back the lock may have
1140 already been removed. Don't exit in this case. */
1141 if (rc && rc != -ENOLCK) {
3c1bf7e4 1142 cifs_delete_mid(midQ);
7ee1af76
JA
1143 return rc;
1144 }
1145 }
1146
1be912dd
JL
1147 rc = wait_for_response(ses->server, midQ);
1148 if (rc) {
fb2036d8 1149 send_cancel(ses->server, &rqst, midQ);
1be912dd 1150 spin_lock(&GlobalMid_Lock);
7c9421e1 1151 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
1152 /* no longer considered to be "in-flight" */
1153 midQ->callback = DeleteMidQEntry;
1154 spin_unlock(&GlobalMid_Lock);
1155 return rc;
1156 }
1157 spin_unlock(&GlobalMid_Lock);
7ee1af76 1158 }
1be912dd
JL
1159
1160 /* We got the response - restart system call. */
1161 rstart = 1;
7ee1af76
JA
1162 }
1163
3c1105df 1164 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 1165 if (rc != 0)
7ee1af76 1166 return rc;
50c2f753 1167
17c8bfed 1168 /* rcvd frame is ok */
7c9421e1 1169 if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
698e96a8 1170 rc = -EIO;
f96637be 1171 cifs_dbg(VFS, "Bad MID state?\n");
698e96a8
VL
1172 goto out;
1173 }
1da177e4 1174
d4e4854f 1175 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1176 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1177 rc = cifs_check_receive(midQ, ses->server, 0);
17c8bfed 1178out:
3c1bf7e4 1179 cifs_delete_mid(midQ);
7ee1af76
JA
1180 if (rstart && rc == -EACCES)
1181 return -ERESTARTSYS;
1da177e4
LT
1182 return rc;
1183}