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