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