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