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