Merge tag 'sound-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
[linux-2.6-block.git] / fs / cifs / transport.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/transport.c
3 *
ad7a2926 4 * Copyright (C) International Business Machines Corp., 2002,2008
1da177e4 5 * Author(s): Steve French (sfrench@us.ibm.com)
14a441a2 6 * Jeremy Allison (jra@samba.org) 2006.
79a58d1f 7 *
1da177e4
LT
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software
79a58d1f 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1da177e4
LT
21 */
22
23#include <linux/fs.h>
24#include <linux/list.h>
5a0e3ad6 25#include <linux/gfp.h>
1da177e4
LT
26#include <linux/wait.h>
27#include <linux/net.h>
28#include <linux/delay.h>
f06ac72e 29#include <linux/freezer.h>
b8eed283 30#include <linux/tcp.h>
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 578
820962dc 579 if (rc < 0) {
ad313cb8 580 server->sequence_number -= 2;
820962dc
RV
581 cifs_delete_mid(mid);
582 }
583
a6827c18 584 mutex_unlock(&server->srv_mutex);
789e6661 585
ffc61ccb
SP
586 if (rc == 0)
587 return 0;
a6827c18 588
cb7e9eab 589 add_credits_and_wake_if(server, credits, optype);
a6827c18
JL
590 return rc;
591}
592
133672ef
SF
593/*
594 *
595 * Send an SMB Request. No response info (other than return code)
596 * needs to be parsed.
597 *
598 * flags indicate the type of request buffer and how long to wait
599 * and whether to log NT STATUS code (error) before mapping it to POSIX error
600 *
601 */
602int
96daf2b0 603SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
792af7b0 604 char *in_buf, int flags)
133672ef
SF
605{
606 int rc;
607 struct kvec iov[1];
608 int resp_buf_type;
609
792af7b0
PS
610 iov[0].iov_base = in_buf;
611 iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
133672ef
SF
612 flags |= CIFS_NO_RESP;
613 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
f96637be 614 cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
90c81e0b 615
133672ef
SF
616 return rc;
617}
618
053d5034 619static int
3c1105df 620cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
053d5034
JL
621{
622 int rc = 0;
623
f96637be
JP
624 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
625 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
053d5034 626
74dd92a8 627 spin_lock(&GlobalMid_Lock);
7c9421e1 628 switch (mid->mid_state) {
74dd92a8 629 case MID_RESPONSE_RECEIVED:
053d5034
JL
630 spin_unlock(&GlobalMid_Lock);
631 return rc;
74dd92a8
JL
632 case MID_RETRY_NEEDED:
633 rc = -EAGAIN;
634 break;
71823baf
JL
635 case MID_RESPONSE_MALFORMED:
636 rc = -EIO;
637 break;
3c1105df
JL
638 case MID_SHUTDOWN:
639 rc = -EHOSTDOWN;
640 break;
74dd92a8 641 default:
3c1105df 642 list_del_init(&mid->qhead);
f96637be
JP
643 cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
644 __func__, mid->mid, mid->mid_state);
74dd92a8 645 rc = -EIO;
053d5034
JL
646 }
647 spin_unlock(&GlobalMid_Lock);
648
5fb4e288 649 mutex_lock(&server->srv_mutex);
2b84a36c 650 DeleteMidQEntry(mid);
5fb4e288 651 mutex_unlock(&server->srv_mutex);
053d5034
JL
652 return rc;
653}
654
121b046a
JL
655static inline int
656send_cancel(struct TCP_Server_Info *server, void *buf, struct mid_q_entry *mid)
76dcc26f 657{
121b046a
JL
658 return server->ops->send_cancel ?
659 server->ops->send_cancel(server, buf, mid) : 0;
76dcc26f
JL
660}
661
2c8f981d
JL
662int
663cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
664 bool log_error)
665{
792af7b0 666 unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
826a95e4
JL
667
668 dump_smb(mid->resp_buf, min_t(u32, 92, len));
2c8f981d
JL
669
670 /* convert the length into a more usable form */
38d77c50 671 if (server->sign) {
826a95e4 672 struct kvec iov;
985e4ff0 673 int rc = 0;
bf5ea0e2
JL
674 struct smb_rqst rqst = { .rq_iov = &iov,
675 .rq_nvec = 1 };
826a95e4
JL
676
677 iov.iov_base = mid->resp_buf;
678 iov.iov_len = len;
2c8f981d 679 /* FIXME: add code to kill session */
bf5ea0e2 680 rc = cifs_verify_signature(&rqst, server,
0124cc45 681 mid->sequence_number);
985e4ff0 682 if (rc)
f96637be
JP
683 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
684 rc);
2c8f981d
JL
685 }
686
687 /* BB special case reconnect tid and uid here? */
688 return map_smb_to_linux_error(mid->resp_buf, log_error);
689}
690
fec344e3
JL
691struct mid_q_entry *
692cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
792af7b0
PS
693{
694 int rc;
fec344e3 695 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
696 struct mid_q_entry *mid;
697
698 rc = allocate_mid(ses, hdr, &mid);
699 if (rc)
fec344e3
JL
700 return ERR_PTR(rc);
701 rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
702 if (rc) {
3c1bf7e4 703 cifs_delete_mid(mid);
fec344e3
JL
704 return ERR_PTR(rc);
705 }
706 return mid;
792af7b0
PS
707}
708
7ee1af76 709int
96daf2b0 710SendReceive2(const unsigned int xid, struct cifs_ses *ses,
a891f0f8 711 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
133672ef 712 const int flags)
7ee1af76
JA
713{
714 int rc = 0;
a891f0f8 715 int timeout, optype;
7ee1af76 716 struct mid_q_entry *midQ;
792af7b0 717 char *buf = iov[0].iov_base;
a891f0f8 718 unsigned int credits = 1;
fec344e3
JL
719 struct smb_rqst rqst = { .rq_iov = iov,
720 .rq_nvec = n_vec };
50c2f753 721
a891f0f8
PS
722 timeout = flags & CIFS_TIMEOUT_MASK;
723 optype = flags & CIFS_OP_MASK;
133672ef 724
a891f0f8 725 *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */
7ee1af76
JA
726
727 if ((ses == NULL) || (ses->server == NULL)) {
792af7b0 728 cifs_small_buf_release(buf);
f96637be 729 cifs_dbg(VFS, "Null session\n");
7ee1af76
JA
730 return -EIO;
731 }
732
79a58d1f 733 if (ses->server->tcpStatus == CifsExiting) {
792af7b0 734 cifs_small_buf_release(buf);
7ee1af76
JA
735 return -ENOENT;
736 }
737
792af7b0
PS
738 /*
739 * Ensure that we do not send more than 50 overlapping requests
740 * to the same server. We may make this configurable later or
741 * use ses->maxReq.
742 */
7ee1af76 743
a891f0f8 744 rc = wait_for_free_request(ses->server, timeout, optype);
7ee1af76 745 if (rc) {
792af7b0 746 cifs_small_buf_release(buf);
7ee1af76
JA
747 return rc;
748 }
749
792af7b0
PS
750 /*
751 * Make sure that we sign in the same order that we send on this socket
752 * and avoid races inside tcp sendmsg code that could cause corruption
753 * of smb data.
754 */
7ee1af76 755
72ca545b 756 mutex_lock(&ses->server->srv_mutex);
7ee1af76 757
fec344e3
JL
758 midQ = ses->server->ops->setup_request(ses, &rqst);
759 if (IS_ERR(midQ)) {
72ca545b 760 mutex_unlock(&ses->server->srv_mutex);
792af7b0 761 cifs_small_buf_release(buf);
7ee1af76 762 /* Update # of requests on wire to server */
a891f0f8 763 add_credits(ses->server, 1, optype);
fec344e3 764 return PTR_ERR(midQ);
1da177e4 765 }
1da177e4 766
7c9421e1 767 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 768 cifs_in_send_inc(ses->server);
0496e02d 769 rc = smb_sendv(ses->server, iov, n_vec);
789e6661
SF
770 cifs_in_send_dec(ses->server);
771 cifs_save_when_sent(midQ);
7ee1af76 772
ad313cb8
JL
773 if (rc < 0)
774 ses->server->sequence_number -= 2;
72ca545b 775 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 776
2db7c581 777 if (rc < 0) {
792af7b0 778 cifs_small_buf_release(buf);
7ee1af76 779 goto out;
2db7c581 780 }
4b8f930f 781
a891f0f8 782 if (timeout == CIFS_ASYNC_OP) {
792af7b0 783 cifs_small_buf_release(buf);
133672ef 784 goto out;
2db7c581 785 }
d6e04ae6 786
0ade640e 787 rc = wait_for_response(ses->server, midQ);
1be912dd 788 if (rc != 0) {
121b046a 789 send_cancel(ses->server, buf, midQ);
1be912dd 790 spin_lock(&GlobalMid_Lock);
7c9421e1 791 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
792 midQ->callback = DeleteMidQEntry;
793 spin_unlock(&GlobalMid_Lock);
792af7b0 794 cifs_small_buf_release(buf);
a891f0f8 795 add_credits(ses->server, 1, optype);
1be912dd
JL
796 return rc;
797 }
798 spin_unlock(&GlobalMid_Lock);
799 }
d6e04ae6 800
792af7b0 801 cifs_small_buf_release(buf);
2db7c581 802
3c1105df 803 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 804 if (rc != 0) {
a891f0f8 805 add_credits(ses->server, 1, optype);
d6e04ae6
SF
806 return rc;
807 }
50c2f753 808
7c9421e1 809 if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
d6e04ae6 810 rc = -EIO;
f96637be 811 cifs_dbg(FYI, "Bad MID state?\n");
2b2bdfba
SF
812 goto out;
813 }
814
792af7b0
PS
815 buf = (char *)midQ->resp_buf;
816 iov[0].iov_base = buf;
817 iov[0].iov_len = get_rfc1002_length(buf) + 4;
7c9421e1 818 if (midQ->large_buf)
a891f0f8 819 *resp_buf_type = CIFS_LARGE_BUFFER;
2c8f981d 820 else
a891f0f8
PS
821 *resp_buf_type = CIFS_SMALL_BUFFER;
822
823 credits = ses->server->ops->get_credits(midQ);
2b2bdfba 824
082d0642
PS
825 rc = ses->server->ops->check_receive(midQ, ses->server,
826 flags & CIFS_LOG_ERROR);
1da177e4 827
3c1bf7e4 828 /* mark it so buf will not be freed by cifs_delete_mid */
2c8f981d
JL
829 if ((flags & CIFS_NO_RESP) == 0)
830 midQ->resp_buf = NULL;
7ee1af76 831out:
3c1bf7e4 832 cifs_delete_mid(midQ);
a891f0f8 833 add_credits(ses->server, credits, optype);
1da177e4 834
d6e04ae6
SF
835 return rc;
836}
1da177e4
LT
837
838int
96daf2b0 839SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4 840 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
a891f0f8 841 int *pbytes_returned, const int timeout)
1da177e4
LT
842{
843 int rc = 0;
1da177e4
LT
844 struct mid_q_entry *midQ;
845
846 if (ses == NULL) {
f96637be 847 cifs_dbg(VFS, "Null smb session\n");
1da177e4
LT
848 return -EIO;
849 }
79a58d1f 850 if (ses->server == NULL) {
f96637be 851 cifs_dbg(VFS, "Null tcp session\n");
1da177e4
LT
852 return -EIO;
853 }
854
79a58d1f 855 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
856 return -ENOENT;
857
79a58d1f 858 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
859 to the same server. We may make this configurable later or
860 use ses->maxReq */
1da177e4 861
be8e3b00
SF
862 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
863 MAX_CIFS_HDR_SIZE - 4) {
f96637be
JP
864 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
865 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
866 return -EIO;
867 }
868
a891f0f8 869 rc = wait_for_free_request(ses->server, timeout, 0);
7ee1af76
JA
870 if (rc)
871 return rc;
872
79a58d1f 873 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
874 and avoid races inside tcp sendmsg code that could cause corruption
875 of smb data */
876
72ca545b 877 mutex_lock(&ses->server->srv_mutex);
1da177e4 878
7ee1af76
JA
879 rc = allocate_mid(ses, in_buf, &midQ);
880 if (rc) {
72ca545b 881 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 882 /* Update # of requests on wire to server */
a891f0f8 883 add_credits(ses->server, 1, 0);
7ee1af76 884 return rc;
1da177e4
LT
885 }
886
ad009ac9 887 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
888 if (rc) {
889 mutex_unlock(&ses->server->srv_mutex);
890 goto out;
891 }
1da177e4 892
7c9421e1 893 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661
SF
894
895 cifs_in_send_inc(ses->server);
be8e3b00 896 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
897 cifs_in_send_dec(ses->server);
898 cifs_save_when_sent(midQ);
ad313cb8
JL
899
900 if (rc < 0)
901 ses->server->sequence_number -= 2;
902
72ca545b 903 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 904
79a58d1f 905 if (rc < 0)
7ee1af76
JA
906 goto out;
907
a891f0f8 908 if (timeout == CIFS_ASYNC_OP)
7ee1af76 909 goto out;
1da177e4 910
0ade640e 911 rc = wait_for_response(ses->server, midQ);
1be912dd 912 if (rc != 0) {
121b046a 913 send_cancel(ses->server, in_buf, midQ);
1be912dd 914 spin_lock(&GlobalMid_Lock);
7c9421e1 915 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
916 /* no longer considered to be "in-flight" */
917 midQ->callback = DeleteMidQEntry;
918 spin_unlock(&GlobalMid_Lock);
a891f0f8 919 add_credits(ses->server, 1, 0);
1be912dd
JL
920 return rc;
921 }
922 spin_unlock(&GlobalMid_Lock);
923 }
1da177e4 924
3c1105df 925 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 926 if (rc != 0) {
a891f0f8 927 add_credits(ses->server, 1, 0);
1da177e4
LT
928 return rc;
929 }
50c2f753 930
2c8f981d 931 if (!midQ->resp_buf || !out_buf ||
7c9421e1 932 midQ->mid_state != MID_RESPONSE_RECEIVED) {
2b2bdfba 933 rc = -EIO;
f96637be 934 cifs_dbg(VFS, "Bad MID state?\n");
2c8f981d 935 goto out;
1da177e4 936 }
7ee1af76 937
d4e4854f 938 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
939 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
940 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 941out:
3c1bf7e4 942 cifs_delete_mid(midQ);
a891f0f8 943 add_credits(ses->server, 1, 0);
1da177e4 944
7ee1af76
JA
945 return rc;
946}
1da177e4 947
7ee1af76
JA
948/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
949 blocking lock to return. */
950
951static int
96daf2b0 952send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
953 struct smb_hdr *in_buf,
954 struct smb_hdr *out_buf)
955{
956 int bytes_returned;
96daf2b0 957 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
958 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
959
960 /* We just modify the current in_buf to change
961 the type of lock from LOCKING_ANDX_SHARED_LOCK
962 or LOCKING_ANDX_EXCLUSIVE_LOCK to
963 LOCKING_ANDX_CANCEL_LOCK. */
964
965 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
966 pSMB->Timeout = 0;
88257360 967 pSMB->hdr.Mid = get_next_mid(ses->server);
7ee1af76
JA
968
969 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 970 &bytes_returned, 0);
7ee1af76
JA
971}
972
973int
96daf2b0 974SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
975 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
976 int *pbytes_returned)
977{
978 int rc = 0;
979 int rstart = 0;
7ee1af76 980 struct mid_q_entry *midQ;
96daf2b0 981 struct cifs_ses *ses;
7ee1af76
JA
982
983 if (tcon == NULL || tcon->ses == NULL) {
f96637be 984 cifs_dbg(VFS, "Null smb session\n");
7ee1af76
JA
985 return -EIO;
986 }
987 ses = tcon->ses;
988
79a58d1f 989 if (ses->server == NULL) {
f96637be 990 cifs_dbg(VFS, "Null tcp session\n");
7ee1af76
JA
991 return -EIO;
992 }
993
79a58d1f 994 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
995 return -ENOENT;
996
79a58d1f 997 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
998 to the same server. We may make this configurable later or
999 use ses->maxReq */
1000
be8e3b00
SF
1001 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
1002 MAX_CIFS_HDR_SIZE - 4) {
f96637be
JP
1003 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
1004 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
1005 return -EIO;
1006 }
1007
a891f0f8 1008 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0);
7ee1af76
JA
1009 if (rc)
1010 return rc;
1011
79a58d1f 1012 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
1013 and avoid races inside tcp sendmsg code that could cause corruption
1014 of smb data */
1015
72ca545b 1016 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
1017
1018 rc = allocate_mid(ses, in_buf, &midQ);
1019 if (rc) {
72ca545b 1020 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
1021 return rc;
1022 }
1023
7ee1af76 1024 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 1025 if (rc) {
3c1bf7e4 1026 cifs_delete_mid(midQ);
829049cb
VL
1027 mutex_unlock(&ses->server->srv_mutex);
1028 return rc;
1029 }
1da177e4 1030
7c9421e1 1031 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 1032 cifs_in_send_inc(ses->server);
be8e3b00 1033 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
1034 cifs_in_send_dec(ses->server);
1035 cifs_save_when_sent(midQ);
ad313cb8
JL
1036
1037 if (rc < 0)
1038 ses->server->sequence_number -= 2;
1039
72ca545b 1040 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 1041
79a58d1f 1042 if (rc < 0) {
3c1bf7e4 1043 cifs_delete_mid(midQ);
7ee1af76
JA
1044 return rc;
1045 }
1046
1047 /* Wait for a reply - allow signals to interrupt. */
1048 rc = wait_event_interruptible(ses->server->response_q,
7c9421e1 1049 (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
1050 ((ses->server->tcpStatus != CifsGood) &&
1051 (ses->server->tcpStatus != CifsNew)));
1052
1053 /* Were we interrupted by a signal ? */
1054 if ((rc == -ERESTARTSYS) &&
7c9421e1 1055 (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
7ee1af76
JA
1056 ((ses->server->tcpStatus == CifsGood) ||
1057 (ses->server->tcpStatus == CifsNew))) {
1058
1059 if (in_buf->Command == SMB_COM_TRANSACTION2) {
1060 /* POSIX lock. We send a NT_CANCEL SMB to cause the
1061 blocking lock to return. */
121b046a 1062 rc = send_cancel(ses->server, in_buf, midQ);
7ee1af76 1063 if (rc) {
3c1bf7e4 1064 cifs_delete_mid(midQ);
7ee1af76
JA
1065 return rc;
1066 }
1067 } else {
1068 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
1069 to cause the blocking lock to return. */
1070
1071 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
1072
1073 /* If we get -ENOLCK back the lock may have
1074 already been removed. Don't exit in this case. */
1075 if (rc && rc != -ENOLCK) {
3c1bf7e4 1076 cifs_delete_mid(midQ);
7ee1af76
JA
1077 return rc;
1078 }
1079 }
1080
1be912dd
JL
1081 rc = wait_for_response(ses->server, midQ);
1082 if (rc) {
121b046a 1083 send_cancel(ses->server, in_buf, midQ);
1be912dd 1084 spin_lock(&GlobalMid_Lock);
7c9421e1 1085 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
1086 /* no longer considered to be "in-flight" */
1087 midQ->callback = DeleteMidQEntry;
1088 spin_unlock(&GlobalMid_Lock);
1089 return rc;
1090 }
1091 spin_unlock(&GlobalMid_Lock);
7ee1af76 1092 }
1be912dd
JL
1093
1094 /* We got the response - restart system call. */
1095 rstart = 1;
7ee1af76
JA
1096 }
1097
3c1105df 1098 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 1099 if (rc != 0)
7ee1af76 1100 return rc;
50c2f753 1101
17c8bfed 1102 /* rcvd frame is ok */
7c9421e1 1103 if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
698e96a8 1104 rc = -EIO;
f96637be 1105 cifs_dbg(VFS, "Bad MID state?\n");
698e96a8
VL
1106 goto out;
1107 }
1da177e4 1108
d4e4854f 1109 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1110 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1111 rc = cifs_check_receive(midQ, ses->server, 0);
17c8bfed 1112out:
3c1bf7e4 1113 cifs_delete_mid(midQ);
7ee1af76
JA
1114 if (rstart && rc == -EACCES)
1115 return -ERESTARTSYS;
1da177e4
LT
1116 return rc;
1117}