]> git.ipfire.org Git - people/ms/linux.git/blame - fs/cifs/transport.c
mm: Introduce kvcalloc()
[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>
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;
244 unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
a26054d1 245 unsigned long send_length;
97bc00b3 246 unsigned int i;
3ab3f2a1 247 size_t total_len = 0, sent, size;
b8eed283 248 struct socket *ssocket = server->ssocket;
3ab3f2a1 249 struct msghdr smb_msg;
b8eed283 250 int val = 1;
9762c2d0
LL
251 if (cifs_rdma_enabled(server) && server->smbd_conn) {
252 rc = smbd_send(server->smbd_conn, rqst);
253 goto smbd_done;
254 }
ea702b80
JL
255 if (ssocket == NULL)
256 return -ENOTSOCK;
257
a26054d1
JL
258 /* sanity check send length */
259 send_length = rqst_len(rqst);
260 if (send_length != smb_buf_length + 4) {
261 WARN(1, "Send length mismatch(send_length=%lu smb_buf_length=%u)\n",
262 send_length, smb_buf_length);
263 return -EIO;
264 }
265
738f9de5
PS
266 if (n_vec < 2)
267 return -EIO;
268
f96637be 269 cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length);
6f49f46b 270 dump_smb(iov[0].iov_base, iov[0].iov_len);
738f9de5 271 dump_smb(iov[1].iov_base, iov[1].iov_len);
6f49f46b 272
b8eed283
JL
273 /* cork the socket */
274 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
275 (char *)&val, sizeof(val));
276
3ab3f2a1
AV
277 size = 0;
278 for (i = 0; i < n_vec; i++)
279 size += iov[i].iov_len;
280
281 iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, iov, n_vec, size);
282
283 rc = smb_send_kvec(server, &smb_msg, &sent);
97bc00b3
JL
284 if (rc < 0)
285 goto uncork;
286
287 total_len += sent;
288
289 /* now walk the page array and send each page in it */
290 for (i = 0; i < rqst->rq_npages; i++) {
e8157b27
LL
291 struct bio_vec bvec;
292
293 bvec.bv_page = rqst->rq_pages[i];
294 rqst_page_get_length(rqst, i, &bvec.bv_len, &bvec.bv_offset);
295
3ab3f2a1 296 iov_iter_bvec(&smb_msg.msg_iter, WRITE | ITER_BVEC,
e8157b27 297 &bvec, 1, bvec.bv_len);
3ab3f2a1 298 rc = smb_send_kvec(server, &smb_msg, &sent);
97bc00b3
JL
299 if (rc < 0)
300 break;
301
302 total_len += sent;
303 }
1da177e4 304
97bc00b3 305uncork:
b8eed283
JL
306 /* uncork it */
307 val = 0;
308 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
309 (char *)&val, sizeof(val));
310
edf1ae40 311 if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
f96637be
JP
312 cifs_dbg(FYI, "partial send (wanted=%u sent=%zu): terminating session\n",
313 smb_buf_length + 4, total_len);
6f49f46b
JL
314 /*
315 * If we have only sent part of an SMB then the next SMB could
316 * be taken as the remainder of this one. We need to kill the
317 * socket so the server throws away the partial SMB
318 */
edf1ae40
SF
319 server->tcpStatus = CifsNeedReconnect;
320 }
9762c2d0 321smbd_done:
d804d41d 322 if (rc < 0 && rc != -EINTR)
f96637be
JP
323 cifs_dbg(VFS, "Error %d sending data on socket to server\n",
324 rc);
d804d41d 325 else
1da177e4 326 rc = 0;
1da177e4
LT
327
328 return rc;
329}
330
6f49f46b 331static int
7fb8986e 332smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags)
6f49f46b 333{
7fb8986e
PS
334 struct smb_rqst cur_rqst;
335 int rc;
336
337 if (!(flags & CIFS_TRANSFORM_REQ))
338 return __smb_send_rqst(server, rqst);
339
340 if (!server->ops->init_transform_rq ||
341 !server->ops->free_transform_rq) {
342 cifs_dbg(VFS, "Encryption requested but transform callbacks are missed\n");
343 return -EIO;
344 }
6f49f46b 345
7fb8986e
PS
346 rc = server->ops->init_transform_rq(server, &cur_rqst, rqst);
347 if (rc)
348 return rc;
349
350 rc = __smb_send_rqst(server, &cur_rqst);
351 server->ops->free_transform_rq(&cur_rqst);
352 return rc;
6f49f46b
JL
353}
354
0496e02d
JL
355int
356smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
357 unsigned int smb_buf_length)
358{
738f9de5 359 struct kvec iov[2];
7fb8986e
PS
360 struct smb_rqst rqst = { .rq_iov = iov,
361 .rq_nvec = 2 };
0496e02d 362
738f9de5
PS
363 iov[0].iov_base = smb_buffer;
364 iov[0].iov_len = 4;
365 iov[1].iov_base = (char *)smb_buffer + 4;
366 iov[1].iov_len = smb_buf_length;
0496e02d 367
7fb8986e 368 return __smb_send_rqst(server, &rqst);
0496e02d
JL
369}
370
fc40f9cf 371static int
a891f0f8 372wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
bc205ed1 373 int *credits)
1da177e4 374{
5bc59498
PS
375 int rc;
376
fc40f9cf 377 spin_lock(&server->req_lock);
a891f0f8 378 if (timeout == CIFS_ASYNC_OP) {
1da177e4 379 /* oplock breaks must not be held up */
fc40f9cf 380 server->in_flight++;
bc205ed1 381 *credits -= 1;
fc40f9cf 382 spin_unlock(&server->req_lock);
27a97a61
VL
383 return 0;
384 }
385
27a97a61 386 while (1) {
bc205ed1 387 if (*credits <= 0) {
fc40f9cf 388 spin_unlock(&server->req_lock);
789e6661 389 cifs_num_waiters_inc(server);
5bc59498 390 rc = wait_event_killable(server->request_q,
bc205ed1 391 has_credits(server, credits));
789e6661 392 cifs_num_waiters_dec(server);
5bc59498
PS
393 if (rc)
394 return rc;
fc40f9cf 395 spin_lock(&server->req_lock);
27a97a61 396 } else {
c5797a94 397 if (server->tcpStatus == CifsExiting) {
fc40f9cf 398 spin_unlock(&server->req_lock);
27a97a61 399 return -ENOENT;
1da177e4 400 }
27a97a61 401
2d86dbc9
PS
402 /*
403 * Can not count locking commands against total
404 * as they are allowed to block on server.
405 */
27a97a61
VL
406
407 /* update # of requests on the wire to server */
a891f0f8 408 if (timeout != CIFS_BLOCKING_OP) {
bc205ed1 409 *credits -= 1;
fc40f9cf 410 server->in_flight++;
2d86dbc9 411 }
fc40f9cf 412 spin_unlock(&server->req_lock);
27a97a61 413 break;
1da177e4
LT
414 }
415 }
7ee1af76
JA
416 return 0;
417}
1da177e4 418
bc205ed1 419static int
a891f0f8
PS
420wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
421 const int optype)
bc205ed1 422{
eb4c7df6
SP
423 int *val;
424
425 val = server->ops->get_credits_field(server, optype);
426 /* Since an echo is already inflight, no need to wait to send another */
427 if (*val <= 0 && optype == CIFS_ECHO_OP)
428 return -EAGAIN;
429 return wait_for_free_credits(server, timeout, val);
bc205ed1
PS
430}
431
cb7e9eab
PS
432int
433cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
434 unsigned int *num, unsigned int *credits)
435{
436 *num = size;
437 *credits = 0;
438 return 0;
439}
440
96daf2b0 441static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
7ee1af76
JA
442 struct mid_q_entry **ppmidQ)
443{
1da177e4 444 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 445 return -ENOENT;
8fbbd365
VL
446 }
447
448 if (ses->server->tcpStatus == CifsNeedReconnect) {
f96637be 449 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
7ee1af76 450 return -EAGAIN;
8fbbd365
VL
451 }
452
7f48558e 453 if (ses->status == CifsNew) {
79a58d1f 454 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 455 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 456 return -EAGAIN;
ad7a2926 457 /* else ok - we are setting up session */
1da177e4 458 }
7f48558e
SP
459
460 if (ses->status == CifsExiting) {
461 /* check if SMB session is bad because we are setting it up */
462 if (in_buf->Command != SMB_COM_LOGOFF_ANDX)
463 return -EAGAIN;
464 /* else ok - we are shutting down session */
465 }
466
24b9b06b 467 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 468 if (*ppmidQ == NULL)
7ee1af76 469 return -ENOMEM;
ddc8cf8f
JL
470 spin_lock(&GlobalMid_Lock);
471 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
472 spin_unlock(&GlobalMid_Lock);
7ee1af76
JA
473 return 0;
474}
475
0ade640e
JL
476static int
477wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
7ee1af76 478{
0ade640e 479 int error;
7ee1af76 480
5853cc2a 481 error = wait_event_freezekillable_unsafe(server->response_q,
7c9421e1 482 midQ->mid_state != MID_REQUEST_SUBMITTED);
0ade640e
JL
483 if (error < 0)
484 return -ERESTARTSYS;
7ee1af76 485
0ade640e 486 return 0;
7ee1af76
JA
487}
488
fec344e3
JL
489struct mid_q_entry *
490cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
792af7b0
PS
491{
492 int rc;
fec344e3 493 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
494 struct mid_q_entry *mid;
495
738f9de5
PS
496 if (rqst->rq_iov[0].iov_len != 4 ||
497 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
498 return ERR_PTR(-EIO);
499
792af7b0 500 /* enable signing if server requires it */
38d77c50 501 if (server->sign)
792af7b0
PS
502 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
503
504 mid = AllocMidQEntry(hdr, server);
505 if (mid == NULL)
fec344e3 506 return ERR_PTR(-ENOMEM);
792af7b0 507
fec344e3 508 rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);
ffc61ccb
SP
509 if (rc) {
510 DeleteMidQEntry(mid);
fec344e3 511 return ERR_PTR(rc);
ffc61ccb
SP
512 }
513
fec344e3 514 return mid;
792af7b0 515}
133672ef 516
a6827c18
JL
517/*
518 * Send a SMB request and set the callback function in the mid to handle
519 * the result. Caller is responsible for dealing with timeouts.
520 */
521int
fec344e3 522cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
9b7c18a2
PS
523 mid_receive_t *receive, mid_callback_t *callback,
524 mid_handle_t *handle, void *cbdata, const int flags)
a6827c18 525{
a891f0f8 526 int rc, timeout, optype;
a6827c18 527 struct mid_q_entry *mid;
cb7e9eab 528 unsigned int credits = 0;
a6827c18 529
a891f0f8
PS
530 timeout = flags & CIFS_TIMEOUT_MASK;
531 optype = flags & CIFS_OP_MASK;
532
cb7e9eab
PS
533 if ((flags & CIFS_HAS_CREDITS) == 0) {
534 rc = wait_for_free_request(server, timeout, optype);
535 if (rc)
536 return rc;
537 credits = 1;
538 }
a6827c18
JL
539
540 mutex_lock(&server->srv_mutex);
fec344e3
JL
541 mid = server->ops->setup_async_request(server, rqst);
542 if (IS_ERR(mid)) {
a6827c18 543 mutex_unlock(&server->srv_mutex);
cb7e9eab 544 add_credits_and_wake_if(server, credits, optype);
fec344e3 545 return PTR_ERR(mid);
a6827c18
JL
546 }
547
44d22d84 548 mid->receive = receive;
a6827c18
JL
549 mid->callback = callback;
550 mid->callback_data = cbdata;
9b7c18a2 551 mid->handle = handle;
7c9421e1 552 mid->mid_state = MID_REQUEST_SUBMITTED;
789e6661 553
ffc61ccb
SP
554 /* put it on the pending_mid_q */
555 spin_lock(&GlobalMid_Lock);
556 list_add_tail(&mid->qhead, &server->pending_mid_q);
557 spin_unlock(&GlobalMid_Lock);
558
93d2cb6c
LL
559 /*
560 * Need to store the time in mid before calling I/O. For call_async,
561 * I/O response may come back and free the mid entry on another thread.
562 */
563 cifs_save_when_sent(mid);
789e6661 564 cifs_in_send_inc(server);
7fb8986e 565 rc = smb_send_rqst(server, rqst, flags);
789e6661 566 cifs_in_send_dec(server);
ad313cb8 567
820962dc 568 if (rc < 0) {
ad313cb8 569 server->sequence_number -= 2;
820962dc
RV
570 cifs_delete_mid(mid);
571 }
572
a6827c18 573 mutex_unlock(&server->srv_mutex);
789e6661 574
ffc61ccb
SP
575 if (rc == 0)
576 return 0;
a6827c18 577
cb7e9eab 578 add_credits_and_wake_if(server, credits, optype);
a6827c18
JL
579 return rc;
580}
581
133672ef
SF
582/*
583 *
584 * Send an SMB Request. No response info (other than return code)
585 * needs to be parsed.
586 *
587 * flags indicate the type of request buffer and how long to wait
588 * and whether to log NT STATUS code (error) before mapping it to POSIX error
589 *
590 */
591int
96daf2b0 592SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
792af7b0 593 char *in_buf, int flags)
133672ef
SF
594{
595 int rc;
596 struct kvec iov[1];
da502f7d 597 struct kvec rsp_iov;
133672ef
SF
598 int resp_buf_type;
599
792af7b0
PS
600 iov[0].iov_base = in_buf;
601 iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
133672ef 602 flags |= CIFS_NO_RESP;
da502f7d 603 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
f96637be 604 cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
90c81e0b 605
133672ef
SF
606 return rc;
607}
608
053d5034 609static int
3c1105df 610cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
053d5034
JL
611{
612 int rc = 0;
613
f96637be
JP
614 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
615 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
053d5034 616
74dd92a8 617 spin_lock(&GlobalMid_Lock);
7c9421e1 618 switch (mid->mid_state) {
74dd92a8 619 case MID_RESPONSE_RECEIVED:
053d5034
JL
620 spin_unlock(&GlobalMid_Lock);
621 return rc;
74dd92a8
JL
622 case MID_RETRY_NEEDED:
623 rc = -EAGAIN;
624 break;
71823baf
JL
625 case MID_RESPONSE_MALFORMED:
626 rc = -EIO;
627 break;
3c1105df
JL
628 case MID_SHUTDOWN:
629 rc = -EHOSTDOWN;
630 break;
74dd92a8 631 default:
3c1105df 632 list_del_init(&mid->qhead);
f96637be
JP
633 cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
634 __func__, mid->mid, mid->mid_state);
74dd92a8 635 rc = -EIO;
053d5034
JL
636 }
637 spin_unlock(&GlobalMid_Lock);
638
2b84a36c 639 DeleteMidQEntry(mid);
053d5034
JL
640 return rc;
641}
642
121b046a 643static inline int
fb2036d8
PS
644send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
645 struct mid_q_entry *mid)
76dcc26f 646{
121b046a 647 return server->ops->send_cancel ?
fb2036d8 648 server->ops->send_cancel(server, rqst, mid) : 0;
76dcc26f
JL
649}
650
2c8f981d
JL
651int
652cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
653 bool log_error)
654{
792af7b0 655 unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
826a95e4
JL
656
657 dump_smb(mid->resp_buf, min_t(u32, 92, len));
2c8f981d
JL
658
659 /* convert the length into a more usable form */
38d77c50 660 if (server->sign) {
738f9de5 661 struct kvec iov[2];
985e4ff0 662 int rc = 0;
738f9de5
PS
663 struct smb_rqst rqst = { .rq_iov = iov,
664 .rq_nvec = 2 };
826a95e4 665
738f9de5
PS
666 iov[0].iov_base = mid->resp_buf;
667 iov[0].iov_len = 4;
668 iov[1].iov_base = (char *)mid->resp_buf + 4;
669 iov[1].iov_len = len - 4;
2c8f981d 670 /* FIXME: add code to kill session */
bf5ea0e2 671 rc = cifs_verify_signature(&rqst, server,
0124cc45 672 mid->sequence_number);
985e4ff0 673 if (rc)
f96637be
JP
674 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
675 rc);
2c8f981d
JL
676 }
677
678 /* BB special case reconnect tid and uid here? */
679 return map_smb_to_linux_error(mid->resp_buf, log_error);
680}
681
fec344e3
JL
682struct mid_q_entry *
683cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
792af7b0
PS
684{
685 int rc;
fec344e3 686 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
687 struct mid_q_entry *mid;
688
738f9de5
PS
689 if (rqst->rq_iov[0].iov_len != 4 ||
690 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
691 return ERR_PTR(-EIO);
692
792af7b0
PS
693 rc = allocate_mid(ses, hdr, &mid);
694 if (rc)
fec344e3
JL
695 return ERR_PTR(rc);
696 rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
697 if (rc) {
3c1bf7e4 698 cifs_delete_mid(mid);
fec344e3
JL
699 return ERR_PTR(rc);
700 }
701 return mid;
792af7b0
PS
702}
703
b8f57ee8 704int
738f9de5
PS
705cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
706 struct smb_rqst *rqst, int *resp_buf_type, const int flags,
707 struct kvec *resp_iov)
7ee1af76
JA
708{
709 int rc = 0;
a891f0f8 710 int timeout, optype;
7ee1af76 711 struct mid_q_entry *midQ;
a891f0f8 712 unsigned int credits = 1;
738f9de5 713 char *buf;
50c2f753 714
a891f0f8
PS
715 timeout = flags & CIFS_TIMEOUT_MASK;
716 optype = flags & CIFS_OP_MASK;
133672ef 717
a891f0f8 718 *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */
7ee1af76
JA
719
720 if ((ses == NULL) || (ses->server == NULL)) {
f96637be 721 cifs_dbg(VFS, "Null session\n");
7ee1af76
JA
722 return -EIO;
723 }
724
da502f7d 725 if (ses->server->tcpStatus == CifsExiting)
7ee1af76 726 return -ENOENT;
7ee1af76 727
792af7b0
PS
728 /*
729 * Ensure that we do not send more than 50 overlapping requests
730 * to the same server. We may make this configurable later or
731 * use ses->maxReq.
732 */
7ee1af76 733
a891f0f8 734 rc = wait_for_free_request(ses->server, timeout, optype);
da502f7d 735 if (rc)
7ee1af76 736 return rc;
7ee1af76 737
792af7b0
PS
738 /*
739 * Make sure that we sign in the same order that we send on this socket
740 * and avoid races inside tcp sendmsg code that could cause corruption
741 * of smb data.
742 */
7ee1af76 743
72ca545b 744 mutex_lock(&ses->server->srv_mutex);
7ee1af76 745
738f9de5 746 midQ = ses->server->ops->setup_request(ses, rqst);
fec344e3 747 if (IS_ERR(midQ)) {
72ca545b 748 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 749 /* Update # of requests on wire to server */
a891f0f8 750 add_credits(ses->server, 1, optype);
fec344e3 751 return PTR_ERR(midQ);
1da177e4 752 }
1da177e4 753
7c9421e1 754 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 755 cifs_in_send_inc(ses->server);
7fb8986e 756 rc = smb_send_rqst(ses->server, rqst, flags);
789e6661
SF
757 cifs_in_send_dec(ses->server);
758 cifs_save_when_sent(midQ);
7ee1af76 759
ad313cb8
JL
760 if (rc < 0)
761 ses->server->sequence_number -= 2;
72ca545b 762 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 763
da502f7d 764 if (rc < 0)
7ee1af76 765 goto out;
4b8f930f 766
8bd68c6e 767#ifdef CONFIG_CIFS_SMB311
0d5ec281 768 if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
8bd68c6e
AA
769 smb311_update_preauth_hash(ses, rqst->rq_iov+1,
770 rqst->rq_nvec-1);
771#endif
772
da502f7d 773 if (timeout == CIFS_ASYNC_OP)
133672ef 774 goto out;
d6e04ae6 775
0ade640e 776 rc = wait_for_response(ses->server, midQ);
1be912dd 777 if (rc != 0) {
38bd4906 778 cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid);
738f9de5 779 send_cancel(ses->server, rqst, midQ);
1be912dd 780 spin_lock(&GlobalMid_Lock);
7c9421e1 781 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
38bd4906 782 midQ->mid_flags |= MID_WAIT_CANCELLED;
1be912dd
JL
783 midQ->callback = DeleteMidQEntry;
784 spin_unlock(&GlobalMid_Lock);
a891f0f8 785 add_credits(ses->server, 1, optype);
1be912dd
JL
786 return rc;
787 }
788 spin_unlock(&GlobalMid_Lock);
789 }
d6e04ae6 790
3c1105df 791 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 792 if (rc != 0) {
a891f0f8 793 add_credits(ses->server, 1, optype);
d6e04ae6
SF
794 return rc;
795 }
50c2f753 796
7c9421e1 797 if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
d6e04ae6 798 rc = -EIO;
f96637be 799 cifs_dbg(FYI, "Bad MID state?\n");
2b2bdfba
SF
800 goto out;
801 }
802
792af7b0 803 buf = (char *)midQ->resp_buf;
da502f7d 804 resp_iov->iov_base = buf;
e19b2bc0 805 resp_iov->iov_len = midQ->resp_buf_size +
93012bf9 806 ses->server->vals->header_preamble_size;
7c9421e1 807 if (midQ->large_buf)
a891f0f8 808 *resp_buf_type = CIFS_LARGE_BUFFER;
2c8f981d 809 else
a891f0f8
PS
810 *resp_buf_type = CIFS_SMALL_BUFFER;
811
8bd68c6e 812#ifdef CONFIG_CIFS_SMB311
0d5ec281 813 if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
8bd68c6e 814 struct kvec iov = {
977b6170
RS
815 .iov_base = buf,
816 .iov_len = midQ->resp_buf_size
8bd68c6e
AA
817 };
818 smb311_update_preauth_hash(ses, &iov, 1);
819 }
820#endif
821
a891f0f8 822 credits = ses->server->ops->get_credits(midQ);
2b2bdfba 823
082d0642
PS
824 rc = ses->server->ops->check_receive(midQ, ses->server,
825 flags & CIFS_LOG_ERROR);
1da177e4 826
3c1bf7e4 827 /* mark it so buf will not be freed by cifs_delete_mid */
2c8f981d
JL
828 if ((flags & CIFS_NO_RESP) == 0)
829 midQ->resp_buf = NULL;
7ee1af76 830out:
3c1bf7e4 831 cifs_delete_mid(midQ);
a891f0f8 832 add_credits(ses->server, credits, optype);
1da177e4 833
d6e04ae6
SF
834 return rc;
835}
1da177e4 836
738f9de5
PS
837int
838SendReceive2(const unsigned int xid, struct cifs_ses *ses,
839 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
840 const int flags, struct kvec *resp_iov)
841{
842 struct smb_rqst rqst;
3cecf486 843 struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov;
738f9de5
PS
844 int rc;
845
3cecf486
RS
846 if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
847 new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1),
848 GFP_KERNEL);
117e3b7f
SF
849 if (!new_iov) {
850 /* otherwise cifs_send_recv below sets resp_buf_type */
851 *resp_buf_type = CIFS_NO_BUFFER;
3cecf486 852 return -ENOMEM;
117e3b7f 853 }
3cecf486
RS
854 } else
855 new_iov = s_iov;
738f9de5
PS
856
857 /* 1st iov is a RFC1001 length followed by the rest of the packet */
858 memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec));
859
860 new_iov[0].iov_base = new_iov[1].iov_base;
861 new_iov[0].iov_len = 4;
862 new_iov[1].iov_base += 4;
863 new_iov[1].iov_len -= 4;
864
865 memset(&rqst, 0, sizeof(struct smb_rqst));
866 rqst.rq_iov = new_iov;
867 rqst.rq_nvec = n_vec + 1;
868
869 rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
3cecf486
RS
870 if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
871 kfree(new_iov);
738f9de5
PS
872 return rc;
873}
874
83b77391
RS
875/* Like SendReceive2 but iov[0] does not contain an rfc1002 header */
876int
877smb2_send_recv(const unsigned int xid, struct cifs_ses *ses,
878 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
879 const int flags, struct kvec *resp_iov)
880{
881 struct smb_rqst rqst;
3cecf486 882 struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov;
83b77391
RS
883 int rc;
884 int i;
885 __u32 count;
886 __be32 rfc1002_marker;
887
3cecf486
RS
888 if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
889 new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1),
890 GFP_KERNEL);
891 if (!new_iov)
892 return -ENOMEM;
893 } else
894 new_iov = s_iov;
83b77391
RS
895
896 /* 1st iov is an RFC1002 Session Message length */
897 memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec));
898
899 count = 0;
900 for (i = 1; i < n_vec + 1; i++)
901 count += new_iov[i].iov_len;
902
903 rfc1002_marker = cpu_to_be32(count);
904
905 new_iov[0].iov_base = &rfc1002_marker;
906 new_iov[0].iov_len = 4;
907
908 memset(&rqst, 0, sizeof(struct smb_rqst));
909 rqst.rq_iov = new_iov;
910 rqst.rq_nvec = n_vec + 1;
911
912 rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
3cecf486
RS
913 if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
914 kfree(new_iov);
83b77391
RS
915 return rc;
916}
917
1da177e4 918int
96daf2b0 919SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4 920 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
a891f0f8 921 int *pbytes_returned, const int timeout)
1da177e4
LT
922{
923 int rc = 0;
1da177e4 924 struct mid_q_entry *midQ;
fb2036d8
PS
925 unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
926 struct kvec iov = { .iov_base = in_buf, .iov_len = len };
927 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
1da177e4
LT
928
929 if (ses == NULL) {
f96637be 930 cifs_dbg(VFS, "Null smb session\n");
1da177e4
LT
931 return -EIO;
932 }
79a58d1f 933 if (ses->server == NULL) {
f96637be 934 cifs_dbg(VFS, "Null tcp session\n");
1da177e4
LT
935 return -EIO;
936 }
937
79a58d1f 938 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
939 return -ENOENT;
940
79a58d1f 941 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
942 to the same server. We may make this configurable later or
943 use ses->maxReq */
1da177e4 944
fb2036d8 945 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
f96637be 946 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
fb2036d8 947 len);
6d9c6d54
VL
948 return -EIO;
949 }
950
a891f0f8 951 rc = wait_for_free_request(ses->server, timeout, 0);
7ee1af76
JA
952 if (rc)
953 return rc;
954
79a58d1f 955 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
956 and avoid races inside tcp sendmsg code that could cause corruption
957 of smb data */
958
72ca545b 959 mutex_lock(&ses->server->srv_mutex);
1da177e4 960
7ee1af76
JA
961 rc = allocate_mid(ses, in_buf, &midQ);
962 if (rc) {
72ca545b 963 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 964 /* Update # of requests on wire to server */
a891f0f8 965 add_credits(ses->server, 1, 0);
7ee1af76 966 return rc;
1da177e4
LT
967 }
968
ad009ac9 969 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
970 if (rc) {
971 mutex_unlock(&ses->server->srv_mutex);
972 goto out;
973 }
1da177e4 974
7c9421e1 975 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661
SF
976
977 cifs_in_send_inc(ses->server);
fb2036d8 978 rc = smb_send(ses->server, in_buf, len);
789e6661
SF
979 cifs_in_send_dec(ses->server);
980 cifs_save_when_sent(midQ);
ad313cb8
JL
981
982 if (rc < 0)
983 ses->server->sequence_number -= 2;
984
72ca545b 985 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 986
79a58d1f 987 if (rc < 0)
7ee1af76
JA
988 goto out;
989
a891f0f8 990 if (timeout == CIFS_ASYNC_OP)
7ee1af76 991 goto out;
1da177e4 992
0ade640e 993 rc = wait_for_response(ses->server, midQ);
1be912dd 994 if (rc != 0) {
fb2036d8 995 send_cancel(ses->server, &rqst, midQ);
1be912dd 996 spin_lock(&GlobalMid_Lock);
7c9421e1 997 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
998 /* no longer considered to be "in-flight" */
999 midQ->callback = DeleteMidQEntry;
1000 spin_unlock(&GlobalMid_Lock);
a891f0f8 1001 add_credits(ses->server, 1, 0);
1be912dd
JL
1002 return rc;
1003 }
1004 spin_unlock(&GlobalMid_Lock);
1005 }
1da177e4 1006
3c1105df 1007 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 1008 if (rc != 0) {
a891f0f8 1009 add_credits(ses->server, 1, 0);
1da177e4
LT
1010 return rc;
1011 }
50c2f753 1012
2c8f981d 1013 if (!midQ->resp_buf || !out_buf ||
7c9421e1 1014 midQ->mid_state != MID_RESPONSE_RECEIVED) {
2b2bdfba 1015 rc = -EIO;
f96637be 1016 cifs_dbg(VFS, "Bad MID state?\n");
2c8f981d 1017 goto out;
1da177e4 1018 }
7ee1af76 1019
d4e4854f 1020 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1021 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1022 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 1023out:
3c1bf7e4 1024 cifs_delete_mid(midQ);
a891f0f8 1025 add_credits(ses->server, 1, 0);
1da177e4 1026
7ee1af76
JA
1027 return rc;
1028}
1da177e4 1029
7ee1af76
JA
1030/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
1031 blocking lock to return. */
1032
1033static int
96daf2b0 1034send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
1035 struct smb_hdr *in_buf,
1036 struct smb_hdr *out_buf)
1037{
1038 int bytes_returned;
96daf2b0 1039 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
1040 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
1041
1042 /* We just modify the current in_buf to change
1043 the type of lock from LOCKING_ANDX_SHARED_LOCK
1044 or LOCKING_ANDX_EXCLUSIVE_LOCK to
1045 LOCKING_ANDX_CANCEL_LOCK. */
1046
1047 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
1048 pSMB->Timeout = 0;
88257360 1049 pSMB->hdr.Mid = get_next_mid(ses->server);
7ee1af76
JA
1050
1051 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 1052 &bytes_returned, 0);
7ee1af76
JA
1053}
1054
1055int
96daf2b0 1056SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
1057 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
1058 int *pbytes_returned)
1059{
1060 int rc = 0;
1061 int rstart = 0;
7ee1af76 1062 struct mid_q_entry *midQ;
96daf2b0 1063 struct cifs_ses *ses;
fb2036d8
PS
1064 unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
1065 struct kvec iov = { .iov_base = in_buf, .iov_len = len };
1066 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
7ee1af76
JA
1067
1068 if (tcon == NULL || tcon->ses == NULL) {
f96637be 1069 cifs_dbg(VFS, "Null smb session\n");
7ee1af76
JA
1070 return -EIO;
1071 }
1072 ses = tcon->ses;
1073
79a58d1f 1074 if (ses->server == NULL) {
f96637be 1075 cifs_dbg(VFS, "Null tcp session\n");
7ee1af76
JA
1076 return -EIO;
1077 }
1078
79a58d1f 1079 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
1080 return -ENOENT;
1081
79a58d1f 1082 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
1083 to the same server. We may make this configurable later or
1084 use ses->maxReq */
1085
fb2036d8 1086 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
f96637be 1087 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
fb2036d8 1088 len);
6d9c6d54
VL
1089 return -EIO;
1090 }
1091
a891f0f8 1092 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0);
7ee1af76
JA
1093 if (rc)
1094 return rc;
1095
79a58d1f 1096 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
1097 and avoid races inside tcp sendmsg code that could cause corruption
1098 of smb data */
1099
72ca545b 1100 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
1101
1102 rc = allocate_mid(ses, in_buf, &midQ);
1103 if (rc) {
72ca545b 1104 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
1105 return rc;
1106 }
1107
7ee1af76 1108 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 1109 if (rc) {
3c1bf7e4 1110 cifs_delete_mid(midQ);
829049cb
VL
1111 mutex_unlock(&ses->server->srv_mutex);
1112 return rc;
1113 }
1da177e4 1114
7c9421e1 1115 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 1116 cifs_in_send_inc(ses->server);
fb2036d8 1117 rc = smb_send(ses->server, in_buf, len);
789e6661
SF
1118 cifs_in_send_dec(ses->server);
1119 cifs_save_when_sent(midQ);
ad313cb8
JL
1120
1121 if (rc < 0)
1122 ses->server->sequence_number -= 2;
1123
72ca545b 1124 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 1125
79a58d1f 1126 if (rc < 0) {
3c1bf7e4 1127 cifs_delete_mid(midQ);
7ee1af76
JA
1128 return rc;
1129 }
1130
1131 /* Wait for a reply - allow signals to interrupt. */
1132 rc = wait_event_interruptible(ses->server->response_q,
7c9421e1 1133 (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
1134 ((ses->server->tcpStatus != CifsGood) &&
1135 (ses->server->tcpStatus != CifsNew)));
1136
1137 /* Were we interrupted by a signal ? */
1138 if ((rc == -ERESTARTSYS) &&
7c9421e1 1139 (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
7ee1af76
JA
1140 ((ses->server->tcpStatus == CifsGood) ||
1141 (ses->server->tcpStatus == CifsNew))) {
1142
1143 if (in_buf->Command == SMB_COM_TRANSACTION2) {
1144 /* POSIX lock. We send a NT_CANCEL SMB to cause the
1145 blocking lock to return. */
fb2036d8 1146 rc = send_cancel(ses->server, &rqst, midQ);
7ee1af76 1147 if (rc) {
3c1bf7e4 1148 cifs_delete_mid(midQ);
7ee1af76
JA
1149 return rc;
1150 }
1151 } else {
1152 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
1153 to cause the blocking lock to return. */
1154
1155 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
1156
1157 /* If we get -ENOLCK back the lock may have
1158 already been removed. Don't exit in this case. */
1159 if (rc && rc != -ENOLCK) {
3c1bf7e4 1160 cifs_delete_mid(midQ);
7ee1af76
JA
1161 return rc;
1162 }
1163 }
1164
1be912dd
JL
1165 rc = wait_for_response(ses->server, midQ);
1166 if (rc) {
fb2036d8 1167 send_cancel(ses->server, &rqst, midQ);
1be912dd 1168 spin_lock(&GlobalMid_Lock);
7c9421e1 1169 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
1170 /* no longer considered to be "in-flight" */
1171 midQ->callback = DeleteMidQEntry;
1172 spin_unlock(&GlobalMid_Lock);
1173 return rc;
1174 }
1175 spin_unlock(&GlobalMid_Lock);
7ee1af76 1176 }
1be912dd
JL
1177
1178 /* We got the response - restart system call. */
1179 rstart = 1;
7ee1af76
JA
1180 }
1181
3c1105df 1182 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 1183 if (rc != 0)
7ee1af76 1184 return rc;
50c2f753 1185
17c8bfed 1186 /* rcvd frame is ok */
7c9421e1 1187 if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
698e96a8 1188 rc = -EIO;
f96637be 1189 cifs_dbg(VFS, "Bad MID state?\n");
698e96a8
VL
1190 goto out;
1191 }
1da177e4 1192
d4e4854f 1193 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1194 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1195 rc = cifs_check_receive(midQ, ses->server, 0);
17c8bfed 1196out:
3c1bf7e4 1197 cifs_delete_mid(midQ);
7ee1af76
JA
1198 if (rstart && rc == -EACCES)
1199 return -ERESTARTSYS;
1da177e4
LT
1200 return rc;
1201}