]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - fs/cifs/transport.c
CIFS: Make SendReceive2() takes resp iov
[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
f96637be 248 cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length);
6f49f46b
JL
249 dump_smb(iov[0].iov_base, iov[0].iov_len);
250
b8eed283
JL
251 /* cork the socket */
252 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
253 (char *)&val, sizeof(val));
254
3ab3f2a1
AV
255 size = 0;
256 for (i = 0; i < n_vec; i++)
257 size += iov[i].iov_len;
258
259 iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, iov, n_vec, size);
260
261 rc = smb_send_kvec(server, &smb_msg, &sent);
97bc00b3
JL
262 if (rc < 0)
263 goto uncork;
264
265 total_len += sent;
266
267 /* now walk the page array and send each page in it */
268 for (i = 0; i < rqst->rq_npages; i++) {
3ab3f2a1
AV
269 size_t len = i == rqst->rq_npages - 1
270 ? rqst->rq_tailsz
271 : rqst->rq_pagesz;
272 struct bio_vec bvec = {
273 .bv_page = rqst->rq_pages[i],
274 .bv_len = len
275 };
276 iov_iter_bvec(&smb_msg.msg_iter, WRITE | ITER_BVEC,
277 &bvec, 1, len);
278 rc = smb_send_kvec(server, &smb_msg, &sent);
97bc00b3
JL
279 if (rc < 0)
280 break;
281
282 total_len += sent;
283 }
1da177e4 284
97bc00b3 285uncork:
b8eed283
JL
286 /* uncork it */
287 val = 0;
288 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
289 (char *)&val, sizeof(val));
290
edf1ae40 291 if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
f96637be
JP
292 cifs_dbg(FYI, "partial send (wanted=%u sent=%zu): terminating session\n",
293 smb_buf_length + 4, total_len);
6f49f46b
JL
294 /*
295 * If we have only sent part of an SMB then the next SMB could
296 * be taken as the remainder of this one. We need to kill the
297 * socket so the server throws away the partial SMB
298 */
edf1ae40
SF
299 server->tcpStatus = CifsNeedReconnect;
300 }
301
d804d41d 302 if (rc < 0 && rc != -EINTR)
f96637be
JP
303 cifs_dbg(VFS, "Error %d sending data on socket to server\n",
304 rc);
d804d41d 305 else
1da177e4 306 rc = 0;
1da177e4
LT
307
308 return rc;
309}
310
6f49f46b
JL
311static int
312smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
313{
314 struct smb_rqst rqst = { .rq_iov = iov,
315 .rq_nvec = n_vec };
316
317 return smb_send_rqst(server, &rqst);
318}
319
0496e02d
JL
320int
321smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
322 unsigned int smb_buf_length)
323{
324 struct kvec iov;
325
326 iov.iov_base = smb_buffer;
327 iov.iov_len = smb_buf_length + 4;
328
329 return smb_sendv(server, &iov, 1);
330}
331
fc40f9cf 332static int
a891f0f8 333wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
bc205ed1 334 int *credits)
1da177e4 335{
5bc59498
PS
336 int rc;
337
fc40f9cf 338 spin_lock(&server->req_lock);
a891f0f8 339 if (timeout == CIFS_ASYNC_OP) {
1da177e4 340 /* oplock breaks must not be held up */
fc40f9cf 341 server->in_flight++;
bc205ed1 342 *credits -= 1;
fc40f9cf 343 spin_unlock(&server->req_lock);
27a97a61
VL
344 return 0;
345 }
346
27a97a61 347 while (1) {
bc205ed1 348 if (*credits <= 0) {
fc40f9cf 349 spin_unlock(&server->req_lock);
789e6661 350 cifs_num_waiters_inc(server);
5bc59498 351 rc = wait_event_killable(server->request_q,
bc205ed1 352 has_credits(server, credits));
789e6661 353 cifs_num_waiters_dec(server);
5bc59498
PS
354 if (rc)
355 return rc;
fc40f9cf 356 spin_lock(&server->req_lock);
27a97a61 357 } else {
c5797a94 358 if (server->tcpStatus == CifsExiting) {
fc40f9cf 359 spin_unlock(&server->req_lock);
27a97a61 360 return -ENOENT;
1da177e4 361 }
27a97a61 362
2d86dbc9
PS
363 /*
364 * Can not count locking commands against total
365 * as they are allowed to block on server.
366 */
27a97a61
VL
367
368 /* update # of requests on the wire to server */
a891f0f8 369 if (timeout != CIFS_BLOCKING_OP) {
bc205ed1 370 *credits -= 1;
fc40f9cf 371 server->in_flight++;
2d86dbc9 372 }
fc40f9cf 373 spin_unlock(&server->req_lock);
27a97a61 374 break;
1da177e4
LT
375 }
376 }
7ee1af76
JA
377 return 0;
378}
1da177e4 379
bc205ed1 380static int
a891f0f8
PS
381wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
382 const int optype)
bc205ed1 383{
eb4c7df6
SP
384 int *val;
385
386 val = server->ops->get_credits_field(server, optype);
387 /* Since an echo is already inflight, no need to wait to send another */
388 if (*val <= 0 && optype == CIFS_ECHO_OP)
389 return -EAGAIN;
390 return wait_for_free_credits(server, timeout, val);
bc205ed1
PS
391}
392
cb7e9eab
PS
393int
394cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
395 unsigned int *num, unsigned int *credits)
396{
397 *num = size;
398 *credits = 0;
399 return 0;
400}
401
96daf2b0 402static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
7ee1af76
JA
403 struct mid_q_entry **ppmidQ)
404{
1da177e4 405 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 406 return -ENOENT;
8fbbd365
VL
407 }
408
409 if (ses->server->tcpStatus == CifsNeedReconnect) {
f96637be 410 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
7ee1af76 411 return -EAGAIN;
8fbbd365
VL
412 }
413
7f48558e 414 if (ses->status == CifsNew) {
79a58d1f 415 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 416 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 417 return -EAGAIN;
ad7a2926 418 /* else ok - we are setting up session */
1da177e4 419 }
7f48558e
SP
420
421 if (ses->status == CifsExiting) {
422 /* check if SMB session is bad because we are setting it up */
423 if (in_buf->Command != SMB_COM_LOGOFF_ANDX)
424 return -EAGAIN;
425 /* else ok - we are shutting down session */
426 }
427
24b9b06b 428 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 429 if (*ppmidQ == NULL)
7ee1af76 430 return -ENOMEM;
ddc8cf8f
JL
431 spin_lock(&GlobalMid_Lock);
432 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
433 spin_unlock(&GlobalMid_Lock);
7ee1af76
JA
434 return 0;
435}
436
0ade640e
JL
437static int
438wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
7ee1af76 439{
0ade640e 440 int error;
7ee1af76 441
5853cc2a 442 error = wait_event_freezekillable_unsafe(server->response_q,
7c9421e1 443 midQ->mid_state != MID_REQUEST_SUBMITTED);
0ade640e
JL
444 if (error < 0)
445 return -ERESTARTSYS;
7ee1af76 446
0ade640e 447 return 0;
7ee1af76
JA
448}
449
fec344e3
JL
450struct mid_q_entry *
451cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
792af7b0
PS
452{
453 int rc;
fec344e3 454 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
455 struct mid_q_entry *mid;
456
457 /* enable signing if server requires it */
38d77c50 458 if (server->sign)
792af7b0
PS
459 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
460
461 mid = AllocMidQEntry(hdr, server);
462 if (mid == NULL)
fec344e3 463 return ERR_PTR(-ENOMEM);
792af7b0 464
fec344e3 465 rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);
ffc61ccb
SP
466 if (rc) {
467 DeleteMidQEntry(mid);
fec344e3 468 return ERR_PTR(rc);
ffc61ccb
SP
469 }
470
fec344e3 471 return mid;
792af7b0 472}
133672ef 473
a6827c18
JL
474/*
475 * Send a SMB request and set the callback function in the mid to handle
476 * the result. Caller is responsible for dealing with timeouts.
477 */
478int
fec344e3
JL
479cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
480 mid_receive_t *receive, mid_callback_t *callback,
481 void *cbdata, const int flags)
a6827c18 482{
a891f0f8 483 int rc, timeout, optype;
a6827c18 484 struct mid_q_entry *mid;
cb7e9eab 485 unsigned int credits = 0;
a6827c18 486
a891f0f8
PS
487 timeout = flags & CIFS_TIMEOUT_MASK;
488 optype = flags & CIFS_OP_MASK;
489
cb7e9eab
PS
490 if ((flags & CIFS_HAS_CREDITS) == 0) {
491 rc = wait_for_free_request(server, timeout, optype);
492 if (rc)
493 return rc;
494 credits = 1;
495 }
a6827c18
JL
496
497 mutex_lock(&server->srv_mutex);
fec344e3
JL
498 mid = server->ops->setup_async_request(server, rqst);
499 if (IS_ERR(mid)) {
a6827c18 500 mutex_unlock(&server->srv_mutex);
cb7e9eab 501 add_credits_and_wake_if(server, credits, optype);
fec344e3 502 return PTR_ERR(mid);
a6827c18
JL
503 }
504
44d22d84 505 mid->receive = receive;
a6827c18
JL
506 mid->callback = callback;
507 mid->callback_data = cbdata;
7c9421e1 508 mid->mid_state = MID_REQUEST_SUBMITTED;
789e6661 509
ffc61ccb
SP
510 /* put it on the pending_mid_q */
511 spin_lock(&GlobalMid_Lock);
512 list_add_tail(&mid->qhead, &server->pending_mid_q);
513 spin_unlock(&GlobalMid_Lock);
514
515
789e6661 516 cifs_in_send_inc(server);
fec344e3 517 rc = smb_send_rqst(server, rqst);
789e6661
SF
518 cifs_in_send_dec(server);
519 cifs_save_when_sent(mid);
ad313cb8 520
820962dc 521 if (rc < 0) {
ad313cb8 522 server->sequence_number -= 2;
820962dc
RV
523 cifs_delete_mid(mid);
524 }
525
a6827c18 526 mutex_unlock(&server->srv_mutex);
789e6661 527
ffc61ccb
SP
528 if (rc == 0)
529 return 0;
a6827c18 530
cb7e9eab 531 add_credits_and_wake_if(server, credits, optype);
a6827c18
JL
532 return rc;
533}
534
133672ef
SF
535/*
536 *
537 * Send an SMB Request. No response info (other than return code)
538 * needs to be parsed.
539 *
540 * flags indicate the type of request buffer and how long to wait
541 * and whether to log NT STATUS code (error) before mapping it to POSIX error
542 *
543 */
544int
96daf2b0 545SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
792af7b0 546 char *in_buf, int flags)
133672ef
SF
547{
548 int rc;
549 struct kvec iov[1];
da502f7d 550 struct kvec rsp_iov;
133672ef
SF
551 int resp_buf_type;
552
792af7b0
PS
553 iov[0].iov_base = in_buf;
554 iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
133672ef 555 flags |= CIFS_NO_RESP;
da502f7d 556 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
f96637be 557 cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
90c81e0b 558
133672ef
SF
559 return rc;
560}
561
053d5034 562static int
3c1105df 563cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
053d5034
JL
564{
565 int rc = 0;
566
f96637be
JP
567 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
568 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
053d5034 569
74dd92a8 570 spin_lock(&GlobalMid_Lock);
7c9421e1 571 switch (mid->mid_state) {
74dd92a8 572 case MID_RESPONSE_RECEIVED:
053d5034
JL
573 spin_unlock(&GlobalMid_Lock);
574 return rc;
74dd92a8
JL
575 case MID_RETRY_NEEDED:
576 rc = -EAGAIN;
577 break;
71823baf
JL
578 case MID_RESPONSE_MALFORMED:
579 rc = -EIO;
580 break;
3c1105df
JL
581 case MID_SHUTDOWN:
582 rc = -EHOSTDOWN;
583 break;
74dd92a8 584 default:
3c1105df 585 list_del_init(&mid->qhead);
f96637be
JP
586 cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
587 __func__, mid->mid, mid->mid_state);
74dd92a8 588 rc = -EIO;
053d5034
JL
589 }
590 spin_unlock(&GlobalMid_Lock);
591
5fb4e288 592 mutex_lock(&server->srv_mutex);
2b84a36c 593 DeleteMidQEntry(mid);
5fb4e288 594 mutex_unlock(&server->srv_mutex);
053d5034
JL
595 return rc;
596}
597
121b046a
JL
598static inline int
599send_cancel(struct TCP_Server_Info *server, void *buf, struct mid_q_entry *mid)
76dcc26f 600{
121b046a
JL
601 return server->ops->send_cancel ?
602 server->ops->send_cancel(server, buf, mid) : 0;
76dcc26f
JL
603}
604
2c8f981d
JL
605int
606cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
607 bool log_error)
608{
792af7b0 609 unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
826a95e4
JL
610
611 dump_smb(mid->resp_buf, min_t(u32, 92, len));
2c8f981d
JL
612
613 /* convert the length into a more usable form */
38d77c50 614 if (server->sign) {
826a95e4 615 struct kvec iov;
985e4ff0 616 int rc = 0;
bf5ea0e2
JL
617 struct smb_rqst rqst = { .rq_iov = &iov,
618 .rq_nvec = 1 };
826a95e4
JL
619
620 iov.iov_base = mid->resp_buf;
621 iov.iov_len = len;
2c8f981d 622 /* FIXME: add code to kill session */
bf5ea0e2 623 rc = cifs_verify_signature(&rqst, server,
0124cc45 624 mid->sequence_number);
985e4ff0 625 if (rc)
f96637be
JP
626 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
627 rc);
2c8f981d
JL
628 }
629
630 /* BB special case reconnect tid and uid here? */
631 return map_smb_to_linux_error(mid->resp_buf, log_error);
632}
633
fec344e3
JL
634struct mid_q_entry *
635cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
792af7b0
PS
636{
637 int rc;
fec344e3 638 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
639 struct mid_q_entry *mid;
640
641 rc = allocate_mid(ses, hdr, &mid);
642 if (rc)
fec344e3
JL
643 return ERR_PTR(rc);
644 rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
645 if (rc) {
3c1bf7e4 646 cifs_delete_mid(mid);
fec344e3
JL
647 return ERR_PTR(rc);
648 }
649 return mid;
792af7b0
PS
650}
651
7ee1af76 652int
96daf2b0 653SendReceive2(const unsigned int xid, struct cifs_ses *ses,
a891f0f8 654 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
da502f7d 655 const int flags, struct kvec *resp_iov)
7ee1af76
JA
656{
657 int rc = 0;
a891f0f8 658 int timeout, optype;
7ee1af76 659 struct mid_q_entry *midQ;
792af7b0 660 char *buf = iov[0].iov_base;
a891f0f8 661 unsigned int credits = 1;
fec344e3
JL
662 struct smb_rqst rqst = { .rq_iov = iov,
663 .rq_nvec = n_vec };
50c2f753 664
a891f0f8
PS
665 timeout = flags & CIFS_TIMEOUT_MASK;
666 optype = flags & CIFS_OP_MASK;
133672ef 667
a891f0f8 668 *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */
7ee1af76
JA
669
670 if ((ses == NULL) || (ses->server == NULL)) {
f96637be 671 cifs_dbg(VFS, "Null session\n");
7ee1af76
JA
672 return -EIO;
673 }
674
da502f7d 675 if (ses->server->tcpStatus == CifsExiting)
7ee1af76 676 return -ENOENT;
7ee1af76 677
792af7b0
PS
678 /*
679 * Ensure that we do not send more than 50 overlapping requests
680 * to the same server. We may make this configurable later or
681 * use ses->maxReq.
682 */
7ee1af76 683
a891f0f8 684 rc = wait_for_free_request(ses->server, timeout, optype);
da502f7d 685 if (rc)
7ee1af76 686 return rc;
7ee1af76 687
792af7b0
PS
688 /*
689 * Make sure that we sign in the same order that we send on this socket
690 * and avoid races inside tcp sendmsg code that could cause corruption
691 * of smb data.
692 */
7ee1af76 693
72ca545b 694 mutex_lock(&ses->server->srv_mutex);
7ee1af76 695
fec344e3
JL
696 midQ = ses->server->ops->setup_request(ses, &rqst);
697 if (IS_ERR(midQ)) {
72ca545b 698 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 699 /* Update # of requests on wire to server */
a891f0f8 700 add_credits(ses->server, 1, optype);
fec344e3 701 return PTR_ERR(midQ);
1da177e4 702 }
1da177e4 703
7c9421e1 704 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 705 cifs_in_send_inc(ses->server);
0496e02d 706 rc = smb_sendv(ses->server, iov, n_vec);
789e6661
SF
707 cifs_in_send_dec(ses->server);
708 cifs_save_when_sent(midQ);
7ee1af76 709
ad313cb8
JL
710 if (rc < 0)
711 ses->server->sequence_number -= 2;
72ca545b 712 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 713
da502f7d 714 if (rc < 0)
7ee1af76 715 goto out;
4b8f930f 716
da502f7d 717 if (timeout == CIFS_ASYNC_OP)
133672ef 718 goto out;
d6e04ae6 719
0ade640e 720 rc = wait_for_response(ses->server, midQ);
1be912dd 721 if (rc != 0) {
121b046a 722 send_cancel(ses->server, buf, midQ);
1be912dd 723 spin_lock(&GlobalMid_Lock);
7c9421e1 724 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
725 midQ->callback = DeleteMidQEntry;
726 spin_unlock(&GlobalMid_Lock);
a891f0f8 727 add_credits(ses->server, 1, optype);
1be912dd
JL
728 return rc;
729 }
730 spin_unlock(&GlobalMid_Lock);
731 }
d6e04ae6 732
3c1105df 733 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 734 if (rc != 0) {
a891f0f8 735 add_credits(ses->server, 1, optype);
d6e04ae6
SF
736 return rc;
737 }
50c2f753 738
7c9421e1 739 if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
d6e04ae6 740 rc = -EIO;
f96637be 741 cifs_dbg(FYI, "Bad MID state?\n");
2b2bdfba
SF
742 goto out;
743 }
744
792af7b0 745 buf = (char *)midQ->resp_buf;
da502f7d
PS
746 resp_iov->iov_base = buf;
747 resp_iov->iov_len = get_rfc1002_length(buf) + 4;
7c9421e1 748 if (midQ->large_buf)
a891f0f8 749 *resp_buf_type = CIFS_LARGE_BUFFER;
2c8f981d 750 else
a891f0f8
PS
751 *resp_buf_type = CIFS_SMALL_BUFFER;
752
753 credits = ses->server->ops->get_credits(midQ);
2b2bdfba 754
082d0642
PS
755 rc = ses->server->ops->check_receive(midQ, ses->server,
756 flags & CIFS_LOG_ERROR);
1da177e4 757
3c1bf7e4 758 /* mark it so buf will not be freed by cifs_delete_mid */
2c8f981d
JL
759 if ((flags & CIFS_NO_RESP) == 0)
760 midQ->resp_buf = NULL;
7ee1af76 761out:
3c1bf7e4 762 cifs_delete_mid(midQ);
a891f0f8 763 add_credits(ses->server, credits, optype);
1da177e4 764
d6e04ae6
SF
765 return rc;
766}
1da177e4
LT
767
768int
96daf2b0 769SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4 770 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
a891f0f8 771 int *pbytes_returned, const int timeout)
1da177e4
LT
772{
773 int rc = 0;
1da177e4
LT
774 struct mid_q_entry *midQ;
775
776 if (ses == NULL) {
f96637be 777 cifs_dbg(VFS, "Null smb session\n");
1da177e4
LT
778 return -EIO;
779 }
79a58d1f 780 if (ses->server == NULL) {
f96637be 781 cifs_dbg(VFS, "Null tcp session\n");
1da177e4
LT
782 return -EIO;
783 }
784
79a58d1f 785 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
786 return -ENOENT;
787
79a58d1f 788 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
789 to the same server. We may make this configurable later or
790 use ses->maxReq */
1da177e4 791
be8e3b00
SF
792 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
793 MAX_CIFS_HDR_SIZE - 4) {
f96637be
JP
794 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
795 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
796 return -EIO;
797 }
798
a891f0f8 799 rc = wait_for_free_request(ses->server, timeout, 0);
7ee1af76
JA
800 if (rc)
801 return rc;
802
79a58d1f 803 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
804 and avoid races inside tcp sendmsg code that could cause corruption
805 of smb data */
806
72ca545b 807 mutex_lock(&ses->server->srv_mutex);
1da177e4 808
7ee1af76
JA
809 rc = allocate_mid(ses, in_buf, &midQ);
810 if (rc) {
72ca545b 811 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 812 /* Update # of requests on wire to server */
a891f0f8 813 add_credits(ses->server, 1, 0);
7ee1af76 814 return rc;
1da177e4
LT
815 }
816
ad009ac9 817 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
818 if (rc) {
819 mutex_unlock(&ses->server->srv_mutex);
820 goto out;
821 }
1da177e4 822
7c9421e1 823 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661
SF
824
825 cifs_in_send_inc(ses->server);
be8e3b00 826 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
827 cifs_in_send_dec(ses->server);
828 cifs_save_when_sent(midQ);
ad313cb8
JL
829
830 if (rc < 0)
831 ses->server->sequence_number -= 2;
832
72ca545b 833 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 834
79a58d1f 835 if (rc < 0)
7ee1af76
JA
836 goto out;
837
a891f0f8 838 if (timeout == CIFS_ASYNC_OP)
7ee1af76 839 goto out;
1da177e4 840
0ade640e 841 rc = wait_for_response(ses->server, midQ);
1be912dd 842 if (rc != 0) {
121b046a 843 send_cancel(ses->server, in_buf, midQ);
1be912dd 844 spin_lock(&GlobalMid_Lock);
7c9421e1 845 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
846 /* no longer considered to be "in-flight" */
847 midQ->callback = DeleteMidQEntry;
848 spin_unlock(&GlobalMid_Lock);
a891f0f8 849 add_credits(ses->server, 1, 0);
1be912dd
JL
850 return rc;
851 }
852 spin_unlock(&GlobalMid_Lock);
853 }
1da177e4 854
3c1105df 855 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 856 if (rc != 0) {
a891f0f8 857 add_credits(ses->server, 1, 0);
1da177e4
LT
858 return rc;
859 }
50c2f753 860
2c8f981d 861 if (!midQ->resp_buf || !out_buf ||
7c9421e1 862 midQ->mid_state != MID_RESPONSE_RECEIVED) {
2b2bdfba 863 rc = -EIO;
f96637be 864 cifs_dbg(VFS, "Bad MID state?\n");
2c8f981d 865 goto out;
1da177e4 866 }
7ee1af76 867
d4e4854f 868 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
869 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
870 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 871out:
3c1bf7e4 872 cifs_delete_mid(midQ);
a891f0f8 873 add_credits(ses->server, 1, 0);
1da177e4 874
7ee1af76
JA
875 return rc;
876}
1da177e4 877
7ee1af76
JA
878/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
879 blocking lock to return. */
880
881static int
96daf2b0 882send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
883 struct smb_hdr *in_buf,
884 struct smb_hdr *out_buf)
885{
886 int bytes_returned;
96daf2b0 887 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
888 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
889
890 /* We just modify the current in_buf to change
891 the type of lock from LOCKING_ANDX_SHARED_LOCK
892 or LOCKING_ANDX_EXCLUSIVE_LOCK to
893 LOCKING_ANDX_CANCEL_LOCK. */
894
895 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
896 pSMB->Timeout = 0;
88257360 897 pSMB->hdr.Mid = get_next_mid(ses->server);
7ee1af76
JA
898
899 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 900 &bytes_returned, 0);
7ee1af76
JA
901}
902
903int
96daf2b0 904SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
905 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
906 int *pbytes_returned)
907{
908 int rc = 0;
909 int rstart = 0;
7ee1af76 910 struct mid_q_entry *midQ;
96daf2b0 911 struct cifs_ses *ses;
7ee1af76
JA
912
913 if (tcon == NULL || tcon->ses == NULL) {
f96637be 914 cifs_dbg(VFS, "Null smb session\n");
7ee1af76
JA
915 return -EIO;
916 }
917 ses = tcon->ses;
918
79a58d1f 919 if (ses->server == NULL) {
f96637be 920 cifs_dbg(VFS, "Null tcp session\n");
7ee1af76
JA
921 return -EIO;
922 }
923
79a58d1f 924 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
925 return -ENOENT;
926
79a58d1f 927 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
928 to the same server. We may make this configurable later or
929 use ses->maxReq */
930
be8e3b00
SF
931 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
932 MAX_CIFS_HDR_SIZE - 4) {
f96637be
JP
933 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
934 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
935 return -EIO;
936 }
937
a891f0f8 938 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0);
7ee1af76
JA
939 if (rc)
940 return rc;
941
79a58d1f 942 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
943 and avoid races inside tcp sendmsg code that could cause corruption
944 of smb data */
945
72ca545b 946 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
947
948 rc = allocate_mid(ses, in_buf, &midQ);
949 if (rc) {
72ca545b 950 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
951 return rc;
952 }
953
7ee1af76 954 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 955 if (rc) {
3c1bf7e4 956 cifs_delete_mid(midQ);
829049cb
VL
957 mutex_unlock(&ses->server->srv_mutex);
958 return rc;
959 }
1da177e4 960
7c9421e1 961 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 962 cifs_in_send_inc(ses->server);
be8e3b00 963 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
964 cifs_in_send_dec(ses->server);
965 cifs_save_when_sent(midQ);
ad313cb8
JL
966
967 if (rc < 0)
968 ses->server->sequence_number -= 2;
969
72ca545b 970 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 971
79a58d1f 972 if (rc < 0) {
3c1bf7e4 973 cifs_delete_mid(midQ);
7ee1af76
JA
974 return rc;
975 }
976
977 /* Wait for a reply - allow signals to interrupt. */
978 rc = wait_event_interruptible(ses->server->response_q,
7c9421e1 979 (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
980 ((ses->server->tcpStatus != CifsGood) &&
981 (ses->server->tcpStatus != CifsNew)));
982
983 /* Were we interrupted by a signal ? */
984 if ((rc == -ERESTARTSYS) &&
7c9421e1 985 (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
7ee1af76
JA
986 ((ses->server->tcpStatus == CifsGood) ||
987 (ses->server->tcpStatus == CifsNew))) {
988
989 if (in_buf->Command == SMB_COM_TRANSACTION2) {
990 /* POSIX lock. We send a NT_CANCEL SMB to cause the
991 blocking lock to return. */
121b046a 992 rc = send_cancel(ses->server, in_buf, midQ);
7ee1af76 993 if (rc) {
3c1bf7e4 994 cifs_delete_mid(midQ);
7ee1af76
JA
995 return rc;
996 }
997 } else {
998 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
999 to cause the blocking lock to return. */
1000
1001 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
1002
1003 /* If we get -ENOLCK back the lock may have
1004 already been removed. Don't exit in this case. */
1005 if (rc && rc != -ENOLCK) {
3c1bf7e4 1006 cifs_delete_mid(midQ);
7ee1af76
JA
1007 return rc;
1008 }
1009 }
1010
1be912dd
JL
1011 rc = wait_for_response(ses->server, midQ);
1012 if (rc) {
121b046a 1013 send_cancel(ses->server, in_buf, midQ);
1be912dd 1014 spin_lock(&GlobalMid_Lock);
7c9421e1 1015 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
1016 /* no longer considered to be "in-flight" */
1017 midQ->callback = DeleteMidQEntry;
1018 spin_unlock(&GlobalMid_Lock);
1019 return rc;
1020 }
1021 spin_unlock(&GlobalMid_Lock);
7ee1af76 1022 }
1be912dd
JL
1023
1024 /* We got the response - restart system call. */
1025 rstart = 1;
7ee1af76
JA
1026 }
1027
3c1105df 1028 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 1029 if (rc != 0)
7ee1af76 1030 return rc;
50c2f753 1031
17c8bfed 1032 /* rcvd frame is ok */
7c9421e1 1033 if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
698e96a8 1034 rc = -EIO;
f96637be 1035 cifs_dbg(VFS, "Bad MID state?\n");
698e96a8
VL
1036 goto out;
1037 }
1da177e4 1038
d4e4854f 1039 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1040 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1041 rc = cifs_check_receive(midQ, ses->server, 0);
17c8bfed 1042out:
3c1bf7e4 1043 cifs_delete_mid(midQ);
7ee1af76
JA
1044 if (rstart && rc == -EACCES)
1045 return -ERESTARTSYS;
1da177e4
LT
1046 return rc;
1047}