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