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