]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - fs/cifs/transport.c
cifs: teach signing routines how to deal with arrays of pages in a smb_rqst
[mirror_ubuntu-bionic-kernel.git] / fs / cifs / transport.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/transport.c
3 *
ad7a2926 4 * Copyright (C) International Business Machines Corp., 2002,2008
1da177e4 5 * Author(s): Steve French (sfrench@us.ibm.com)
14a441a2 6 * Jeremy Allison (jra@samba.org) 2006.
79a58d1f 7 *
1da177e4
LT
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software
79a58d1f 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1da177e4
LT
21 */
22
23#include <linux/fs.h>
24#include <linux/list.h>
5a0e3ad6 25#include <linux/gfp.h>
1da177e4
LT
26#include <linux/wait.h>
27#include <linux/net.h>
28#include <linux/delay.h>
f06ac72e 29#include <linux/freezer.h>
b8eed283 30#include <linux/tcp.h>
97bc00b3 31#include <linux/highmem.h>
1da177e4
LT
32#include <asm/uaccess.h>
33#include <asm/processor.h>
34#include <linux/mempool.h>
35#include "cifspdu.h"
36#include "cifsglob.h"
37#include "cifsproto.h"
38#include "cifs_debug.h"
50c2f753 39
2dc7e1c0
PS
40void
41cifs_wake_up_task(struct mid_q_entry *mid)
2b84a36c
JL
42{
43 wake_up_process(mid->callback_data);
44}
45
a6827c18 46struct mid_q_entry *
24b9b06b 47AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
1da177e4
LT
48{
49 struct mid_q_entry *temp;
50
24b9b06b 51 if (server == NULL) {
b6b38f70 52 cERROR(1, "Null TCP session in AllocMidQEntry");
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));
1da177e4
LT
61 temp->mid = smb_buffer->Mid; /* always LE */
62 temp->pid = current->pid;
7c9421e1
PS
63 temp->command = cpu_to_le16(smb_buffer->Command);
64 cFYI(1, "For smb_command %d", 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)) {
7c9421e1 102 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %llu",
1047abc1
SF
103 midEntry->command, midEntry->mid);
104 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
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
79a58d1f 147 if (ssocket == NULL)
1da177e4 148 return -ENOTSOCK; /* BB eventually add reconnect code here */
3e84469d 149
a9f1b85e 150 smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
26f57364 151 smb_msg.msg_namelen = sizeof(struct sockaddr);
1da177e4
LT
152 smb_msg.msg_control = NULL;
153 smb_msg.msg_controllen = 0;
0496e02d 154 if (server->noblocksnd)
edf1ae40
SF
155 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
156 else
157 smb_msg.msg_flags = MSG_NOSIGNAL;
1da177e4 158
6f49f46b 159 remaining = 0;
3e84469d 160 for (i = 0; i < n_vec; i++)
6f49f46b 161 remaining += iov[i].iov_len;
1da177e4 162
17680356 163 i = 0;
6f49f46b
JL
164 while (remaining) {
165 /*
166 * If blocking send, we try 3 times, since each can block
167 * for 5 seconds. For nonblocking we have to try more
168 * but wait increasing amounts of time allowing time for
169 * socket to clear. The overall time we wait in either
170 * case to send on the socket is about 15 seconds.
171 * Similarly we wait for 15 seconds for a response from
172 * the server in SendReceive[2] for the server to send
173 * a response back for most types of requests (except
174 * SMB Write past end of file which can be slow, and
175 * blocking lock operations). NFS waits slightly longer
176 * than CIFS, but this can make it take longer for
177 * nonresponsive servers to be detected and 15 seconds
178 * is more than enough time for modern networks to
179 * send a packet. In most cases if we fail to send
180 * after the retries we will kill the socket and
181 * reconnect which may clear the network problem.
182 */
3e84469d 183 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
6f49f46b
JL
184 n_vec - first_vec, remaining);
185 if (rc == -ENOSPC || rc == -EAGAIN) {
1da177e4 186 i++;
6f49f46b
JL
187 if (i >= 14 || (!server->noblocksnd && (i > 2))) {
188 cERROR(1, "sends on sock %p stuck for 15 "
189 "seconds", ssocket);
1da177e4
LT
190 rc = -EAGAIN;
191 break;
192 }
68058e75 193 msleep(1 << i);
1da177e4
LT
194 continue;
195 }
6f49f46b 196
79a58d1f 197 if (rc < 0)
1da177e4 198 break;
3e84469d 199
6f49f46b
JL
200 /* send was at least partially successful */
201 *sent += rc;
202
203 if (rc == remaining) {
204 remaining = 0;
61de800d 205 break;
6f49f46b
JL
206 }
207
208 if (rc > remaining) {
209 cERROR(1, "sent %d requested %d", rc, remaining);
3e84469d
SF
210 break;
211 }
6f49f46b 212
79a58d1f 213 if (rc == 0) {
3e84469d
SF
214 /* should never happen, letting socket clear before
215 retrying is our only obvious option here */
b6b38f70 216 cERROR(1, "tcp sent no data");
3e84469d
SF
217 msleep(500);
218 continue;
d6e04ae6 219 }
6f49f46b
JL
220
221 remaining -= rc;
222
68058e75 223 /* the line below resets i */
3e84469d
SF
224 for (i = first_vec; i < n_vec; i++) {
225 if (iov[i].iov_len) {
226 if (rc > iov[i].iov_len) {
227 rc -= iov[i].iov_len;
228 iov[i].iov_len = 0;
229 } else {
230 iov[i].iov_base += rc;
231 iov[i].iov_len -= rc;
232 first_vec = i;
233 break;
234 }
235 }
d6e04ae6 236 }
6f49f46b 237
5e1253b5 238 i = 0; /* in case we get ENOSPC on the next send */
6f49f46b 239 rc = 0;
1da177e4 240 }
6f49f46b
JL
241 return rc;
242}
243
97bc00b3
JL
244/**
245 * rqst_page_to_kvec - Turn a slot in the smb_rqst page array into a kvec
246 * @rqst: pointer to smb_rqst
247 * @idx: index into the array of the page
248 * @iov: pointer to struct kvec that will hold the result
249 *
250 * Helper function to convert a slot in the rqst->rq_pages array into a kvec.
251 * The page will be kmapped and the address placed into iov_base. The length
252 * will then be adjusted according to the ptailoff.
253 */
fb308a6f 254void
97bc00b3
JL
255cifs_rqst_page_to_kvec(struct smb_rqst *rqst, unsigned int idx,
256 struct kvec *iov)
257{
258 /*
259 * FIXME: We could avoid this kmap altogether if we used
260 * kernel_sendpage instead of kernel_sendmsg. That will only
261 * work if signing is disabled though as sendpage inlines the
262 * page directly into the fraglist. If userspace modifies the
263 * page after we calculate the signature, then the server will
264 * reject it and may break the connection. kernel_sendmsg does
265 * an extra copy of the data and avoids that issue.
266 */
267 iov->iov_base = kmap(rqst->rq_pages[idx]);
268
269 /* if last page, don't send beyond this offset into page */
270 if (idx == (rqst->rq_npages - 1))
271 iov->iov_len = rqst->rq_tailsz;
272 else
273 iov->iov_len = rqst->rq_pagesz;
274}
275
6f49f46b
JL
276static int
277smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
278{
279 int rc;
280 struct kvec *iov = rqst->rq_iov;
281 int n_vec = rqst->rq_nvec;
282 unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
97bc00b3
JL
283 unsigned int i;
284 size_t total_len = 0, sent;
b8eed283
JL
285 struct socket *ssocket = server->ssocket;
286 int val = 1;
6f49f46b
JL
287
288 cFYI(1, "Sending smb: smb_len=%u", smb_buf_length);
289 dump_smb(iov[0].iov_base, iov[0].iov_len);
290
b8eed283
JL
291 /* cork the socket */
292 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
293 (char *)&val, sizeof(val));
294
97bc00b3
JL
295 rc = smb_send_kvec(server, iov, n_vec, &sent);
296 if (rc < 0)
297 goto uncork;
298
299 total_len += sent;
300
301 /* now walk the page array and send each page in it */
302 for (i = 0; i < rqst->rq_npages; i++) {
303 struct kvec p_iov;
304
305 cifs_rqst_page_to_kvec(rqst, i, &p_iov);
306 rc = smb_send_kvec(server, &p_iov, 1, &sent);
307 kunmap(rqst->rq_pages[i]);
308 if (rc < 0)
309 break;
310
311 total_len += sent;
312 }
1da177e4 313
97bc00b3 314uncork:
b8eed283
JL
315 /* uncork it */
316 val = 0;
317 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
318 (char *)&val, sizeof(val));
319
edf1ae40 320 if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
6f49f46b
JL
321 cFYI(1, "partial send (wanted=%u sent=%zu): terminating "
322 "session", smb_buf_length + 4, total_len);
323 /*
324 * If we have only sent part of an SMB then the next SMB could
325 * be taken as the remainder of this one. We need to kill the
326 * socket so the server throws away the partial SMB
327 */
edf1ae40
SF
328 server->tcpStatus = CifsNeedReconnect;
329 }
330
d804d41d 331 if (rc < 0 && rc != -EINTR)
b6b38f70 332 cERROR(1, "Error %d sending data on socket to server", rc);
d804d41d 333 else
1da177e4 334 rc = 0;
1da177e4
LT
335
336 return rc;
337}
338
6f49f46b
JL
339static int
340smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
341{
342 struct smb_rqst rqst = { .rq_iov = iov,
343 .rq_nvec = n_vec };
344
345 return smb_send_rqst(server, &rqst);
346}
347
0496e02d
JL
348int
349smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
350 unsigned int smb_buf_length)
351{
352 struct kvec iov;
353
354 iov.iov_base = smb_buffer;
355 iov.iov_len = smb_buf_length + 4;
356
357 return smb_sendv(server, &iov, 1);
358}
359
fc40f9cf 360static int
a891f0f8 361wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
bc205ed1 362 int *credits)
1da177e4 363{
5bc59498
PS
364 int rc;
365
fc40f9cf 366 spin_lock(&server->req_lock);
a891f0f8 367 if (timeout == CIFS_ASYNC_OP) {
1da177e4 368 /* oplock breaks must not be held up */
fc40f9cf 369 server->in_flight++;
bc205ed1 370 *credits -= 1;
fc40f9cf 371 spin_unlock(&server->req_lock);
27a97a61
VL
372 return 0;
373 }
374
27a97a61 375 while (1) {
bc205ed1 376 if (*credits <= 0) {
fc40f9cf 377 spin_unlock(&server->req_lock);
789e6661 378 cifs_num_waiters_inc(server);
5bc59498 379 rc = wait_event_killable(server->request_q,
bc205ed1 380 has_credits(server, credits));
789e6661 381 cifs_num_waiters_dec(server);
5bc59498
PS
382 if (rc)
383 return rc;
fc40f9cf 384 spin_lock(&server->req_lock);
27a97a61 385 } else {
c5797a94 386 if (server->tcpStatus == CifsExiting) {
fc40f9cf 387 spin_unlock(&server->req_lock);
27a97a61 388 return -ENOENT;
1da177e4 389 }
27a97a61 390
2d86dbc9
PS
391 /*
392 * Can not count locking commands against total
393 * as they are allowed to block on server.
394 */
27a97a61
VL
395
396 /* update # of requests on the wire to server */
a891f0f8 397 if (timeout != CIFS_BLOCKING_OP) {
bc205ed1 398 *credits -= 1;
fc40f9cf 399 server->in_flight++;
2d86dbc9 400 }
fc40f9cf 401 spin_unlock(&server->req_lock);
27a97a61 402 break;
1da177e4
LT
403 }
404 }
7ee1af76
JA
405 return 0;
406}
1da177e4 407
bc205ed1 408static int
a891f0f8
PS
409wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
410 const int optype)
bc205ed1 411{
a891f0f8
PS
412 return wait_for_free_credits(server, timeout,
413 server->ops->get_credits_field(server, optype));
bc205ed1
PS
414}
415
96daf2b0 416static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
7ee1af76
JA
417 struct mid_q_entry **ppmidQ)
418{
1da177e4 419 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 420 return -ENOENT;
8fbbd365
VL
421 }
422
423 if (ses->server->tcpStatus == CifsNeedReconnect) {
b6b38f70 424 cFYI(1, "tcp session dead - return to caller to retry");
7ee1af76 425 return -EAGAIN;
8fbbd365
VL
426 }
427
428 if (ses->status != CifsGood) {
1da177e4 429 /* check if SMB session is bad because we are setting it up */
79a58d1f 430 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 431 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 432 return -EAGAIN;
ad7a2926 433 /* else ok - we are setting up session */
1da177e4 434 }
24b9b06b 435 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 436 if (*ppmidQ == NULL)
7ee1af76 437 return -ENOMEM;
ddc8cf8f
JL
438 spin_lock(&GlobalMid_Lock);
439 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
440 spin_unlock(&GlobalMid_Lock);
7ee1af76
JA
441 return 0;
442}
443
0ade640e
JL
444static int
445wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
7ee1af76 446{
0ade640e 447 int error;
7ee1af76 448
f06ac72e 449 error = wait_event_freezekillable(server->response_q,
7c9421e1 450 midQ->mid_state != MID_REQUEST_SUBMITTED);
0ade640e
JL
451 if (error < 0)
452 return -ERESTARTSYS;
7ee1af76 453
0ade640e 454 return 0;
7ee1af76
JA
455}
456
45740847 457int
792af7b0
PS
458cifs_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov,
459 unsigned int nvec, struct mid_q_entry **ret_mid)
460{
461 int rc;
462 struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
463 struct mid_q_entry *mid;
464
465 /* enable signing if server requires it */
466 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
467 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
468
469 mid = AllocMidQEntry(hdr, server);
470 if (mid == NULL)
471 return -ENOMEM;
472
762a4206 473 rc = cifs_sign_smbv(iov, nvec, server, &mid->sequence_number);
ffc61ccb
SP
474 if (rc) {
475 DeleteMidQEntry(mid);
476 return rc;
477 }
478
792af7b0 479 *ret_mid = mid;
ffc61ccb 480 return 0;
792af7b0 481}
133672ef 482
a6827c18
JL
483/*
484 * Send a SMB request and set the callback function in the mid to handle
485 * the result. Caller is responsible for dealing with timeouts.
486 */
487int
fcc31cb6 488cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
44d22d84 489 unsigned int nvec, mid_receive_t *receive,
a891f0f8 490 mid_callback_t *callback, void *cbdata, const int flags)
a6827c18 491{
a891f0f8 492 int rc, timeout, optype;
a6827c18
JL
493 struct mid_q_entry *mid;
494
a891f0f8
PS
495 timeout = flags & CIFS_TIMEOUT_MASK;
496 optype = flags & CIFS_OP_MASK;
497
498 rc = wait_for_free_request(server, timeout, optype);
a6827c18
JL
499 if (rc)
500 return rc;
501
502 mutex_lock(&server->srv_mutex);
45740847 503 rc = server->ops->setup_async_request(server, iov, nvec, &mid);
792af7b0 504 if (rc) {
a6827c18 505 mutex_unlock(&server->srv_mutex);
a891f0f8 506 add_credits(server, 1, optype);
0193e072 507 wake_up(&server->request_q);
792af7b0 508 return rc;
a6827c18
JL
509 }
510
44d22d84 511 mid->receive = receive;
a6827c18
JL
512 mid->callback = callback;
513 mid->callback_data = cbdata;
7c9421e1 514 mid->mid_state = MID_REQUEST_SUBMITTED;
789e6661 515
ffc61ccb
SP
516 /* put it on the pending_mid_q */
517 spin_lock(&GlobalMid_Lock);
518 list_add_tail(&mid->qhead, &server->pending_mid_q);
519 spin_unlock(&GlobalMid_Lock);
520
521
789e6661 522 cifs_in_send_inc(server);
fcc31cb6 523 rc = smb_sendv(server, iov, nvec);
789e6661
SF
524 cifs_in_send_dec(server);
525 cifs_save_when_sent(mid);
a6827c18 526 mutex_unlock(&server->srv_mutex);
789e6661 527
ffc61ccb
SP
528 if (rc == 0)
529 return 0;
a6827c18 530
3c1bf7e4 531 cifs_delete_mid(mid);
a891f0f8 532 add_credits(server, 1, optype);
a6827c18
JL
533 wake_up(&server->request_q);
534 return rc;
535}
536
133672ef
SF
537/*
538 *
539 * Send an SMB Request. No response info (other than return code)
540 * needs to be parsed.
541 *
542 * flags indicate the type of request buffer and how long to wait
543 * and whether to log NT STATUS code (error) before mapping it to POSIX error
544 *
545 */
546int
96daf2b0 547SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
792af7b0 548 char *in_buf, int flags)
133672ef
SF
549{
550 int rc;
551 struct kvec iov[1];
552 int resp_buf_type;
553
792af7b0
PS
554 iov[0].iov_base = in_buf;
555 iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
133672ef
SF
556 flags |= CIFS_NO_RESP;
557 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
b6b38f70 558 cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
90c81e0b 559
133672ef
SF
560 return rc;
561}
562
053d5034 563static int
3c1105df 564cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
053d5034
JL
565{
566 int rc = 0;
567
7c9421e1
PS
568 cFYI(1, "%s: cmd=%d mid=%llu state=%d", __func__,
569 le16_to_cpu(mid->command), mid->mid, mid->mid_state);
053d5034 570
74dd92a8 571 spin_lock(&GlobalMid_Lock);
7c9421e1 572 switch (mid->mid_state) {
74dd92a8 573 case MID_RESPONSE_RECEIVED:
053d5034
JL
574 spin_unlock(&GlobalMid_Lock);
575 return rc;
74dd92a8
JL
576 case MID_RETRY_NEEDED:
577 rc = -EAGAIN;
578 break;
71823baf
JL
579 case MID_RESPONSE_MALFORMED:
580 rc = -EIO;
581 break;
3c1105df
JL
582 case MID_SHUTDOWN:
583 rc = -EHOSTDOWN;
584 break;
74dd92a8 585 default:
3c1105df 586 list_del_init(&mid->qhead);
7c9421e1
PS
587 cERROR(1, "%s: invalid mid state mid=%llu state=%d", __func__,
588 mid->mid, mid->mid_state);
74dd92a8 589 rc = -EIO;
053d5034
JL
590 }
591 spin_unlock(&GlobalMid_Lock);
592
2b84a36c 593 DeleteMidQEntry(mid);
053d5034
JL
594 return rc;
595}
596
121b046a
JL
597static inline int
598send_cancel(struct TCP_Server_Info *server, void *buf, struct mid_q_entry *mid)
76dcc26f 599{
121b046a
JL
600 return server->ops->send_cancel ?
601 server->ops->send_cancel(server, buf, mid) : 0;
76dcc26f
JL
602}
603
2c8f981d
JL
604int
605cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
606 bool log_error)
607{
792af7b0 608 unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
826a95e4
JL
609
610 dump_smb(mid->resp_buf, min_t(u32, 92, len));
2c8f981d
JL
611
612 /* convert the length into a more usable form */
96daf2b0 613 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
826a95e4 614 struct kvec iov;
985e4ff0 615 int rc = 0;
bf5ea0e2
JL
616 struct smb_rqst rqst = { .rq_iov = &iov,
617 .rq_nvec = 1 };
826a95e4
JL
618
619 iov.iov_base = mid->resp_buf;
620 iov.iov_len = len;
2c8f981d 621 /* FIXME: add code to kill session */
bf5ea0e2 622 rc = cifs_verify_signature(&rqst, server,
985e4ff0
SF
623 mid->sequence_number + 1);
624 if (rc)
625 cERROR(1, "SMB signature verification returned error = "
626 "%d", rc);
2c8f981d
JL
627 }
628
629 /* BB special case reconnect tid and uid here? */
630 return map_smb_to_linux_error(mid->resp_buf, log_error);
631}
632
082d0642 633int
792af7b0
PS
634cifs_setup_request(struct cifs_ses *ses, struct kvec *iov,
635 unsigned int nvec, struct mid_q_entry **ret_mid)
636{
637 int rc;
638 struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
639 struct mid_q_entry *mid;
640
641 rc = allocate_mid(ses, hdr, &mid);
642 if (rc)
643 return rc;
762a4206 644 rc = cifs_sign_smbv(iov, nvec, ses->server, &mid->sequence_number);
792af7b0 645 if (rc)
3c1bf7e4 646 cifs_delete_mid(mid);
792af7b0
PS
647 *ret_mid = mid;
648 return rc;
649}
650
7ee1af76 651int
96daf2b0 652SendReceive2(const unsigned int xid, struct cifs_ses *ses,
a891f0f8 653 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
133672ef 654 const int flags)
7ee1af76
JA
655{
656 int rc = 0;
a891f0f8 657 int timeout, optype;
7ee1af76 658 struct mid_q_entry *midQ;
792af7b0 659 char *buf = iov[0].iov_base;
a891f0f8 660 unsigned int credits = 1;
50c2f753 661
a891f0f8
PS
662 timeout = flags & CIFS_TIMEOUT_MASK;
663 optype = flags & CIFS_OP_MASK;
133672ef 664
a891f0f8 665 *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */
7ee1af76
JA
666
667 if ((ses == NULL) || (ses->server == NULL)) {
792af7b0 668 cifs_small_buf_release(buf);
b6b38f70 669 cERROR(1, "Null session");
7ee1af76
JA
670 return -EIO;
671 }
672
79a58d1f 673 if (ses->server->tcpStatus == CifsExiting) {
792af7b0 674 cifs_small_buf_release(buf);
7ee1af76
JA
675 return -ENOENT;
676 }
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);
7ee1af76 685 if (rc) {
792af7b0 686 cifs_small_buf_release(buf);
7ee1af76
JA
687 return rc;
688 }
689
792af7b0
PS
690 /*
691 * Make sure that we sign in the same order that we send on this socket
692 * and avoid races inside tcp sendmsg code that could cause corruption
693 * of smb data.
694 */
7ee1af76 695
72ca545b 696 mutex_lock(&ses->server->srv_mutex);
7ee1af76 697
082d0642 698 rc = ses->server->ops->setup_request(ses, iov, n_vec, &midQ);
7ee1af76 699 if (rc) {
72ca545b 700 mutex_unlock(&ses->server->srv_mutex);
792af7b0 701 cifs_small_buf_release(buf);
7ee1af76 702 /* Update # of requests on wire to server */
a891f0f8 703 add_credits(ses->server, 1, optype);
7ee1af76 704 return rc;
1da177e4 705 }
1da177e4 706
7c9421e1 707 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 708 cifs_in_send_inc(ses->server);
0496e02d 709 rc = smb_sendv(ses->server, iov, n_vec);
789e6661
SF
710 cifs_in_send_dec(ses->server);
711 cifs_save_when_sent(midQ);
7ee1af76 712
72ca545b 713 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 714
2db7c581 715 if (rc < 0) {
792af7b0 716 cifs_small_buf_release(buf);
7ee1af76 717 goto out;
2db7c581 718 }
4b8f930f 719
a891f0f8 720 if (timeout == CIFS_ASYNC_OP) {
792af7b0 721 cifs_small_buf_release(buf);
133672ef 722 goto out;
2db7c581 723 }
d6e04ae6 724
0ade640e 725 rc = wait_for_response(ses->server, midQ);
1be912dd 726 if (rc != 0) {
121b046a 727 send_cancel(ses->server, buf, midQ);
1be912dd 728 spin_lock(&GlobalMid_Lock);
7c9421e1 729 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
730 midQ->callback = DeleteMidQEntry;
731 spin_unlock(&GlobalMid_Lock);
792af7b0 732 cifs_small_buf_release(buf);
a891f0f8 733 add_credits(ses->server, 1, optype);
1be912dd
JL
734 return rc;
735 }
736 spin_unlock(&GlobalMid_Lock);
737 }
d6e04ae6 738
792af7b0 739 cifs_small_buf_release(buf);
2db7c581 740
3c1105df 741 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 742 if (rc != 0) {
a891f0f8 743 add_credits(ses->server, 1, optype);
d6e04ae6
SF
744 return rc;
745 }
50c2f753 746
7c9421e1 747 if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
d6e04ae6 748 rc = -EIO;
2c8f981d 749 cFYI(1, "Bad MID state?");
2b2bdfba
SF
750 goto out;
751 }
752
792af7b0
PS
753 buf = (char *)midQ->resp_buf;
754 iov[0].iov_base = buf;
755 iov[0].iov_len = get_rfc1002_length(buf) + 4;
7c9421e1 756 if (midQ->large_buf)
a891f0f8 757 *resp_buf_type = CIFS_LARGE_BUFFER;
2c8f981d 758 else
a891f0f8
PS
759 *resp_buf_type = CIFS_SMALL_BUFFER;
760
761 credits = ses->server->ops->get_credits(midQ);
2b2bdfba 762
082d0642
PS
763 rc = ses->server->ops->check_receive(midQ, ses->server,
764 flags & CIFS_LOG_ERROR);
1da177e4 765
3c1bf7e4 766 /* mark it so buf will not be freed by cifs_delete_mid */
2c8f981d
JL
767 if ((flags & CIFS_NO_RESP) == 0)
768 midQ->resp_buf = NULL;
7ee1af76 769out:
3c1bf7e4 770 cifs_delete_mid(midQ);
a891f0f8 771 add_credits(ses->server, credits, optype);
1da177e4 772
d6e04ae6
SF
773 return rc;
774}
1da177e4
LT
775
776int
96daf2b0 777SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4 778 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
a891f0f8 779 int *pbytes_returned, const int timeout)
1da177e4
LT
780{
781 int rc = 0;
1da177e4
LT
782 struct mid_q_entry *midQ;
783
784 if (ses == NULL) {
b6b38f70 785 cERROR(1, "Null smb session");
1da177e4
LT
786 return -EIO;
787 }
79a58d1f 788 if (ses->server == NULL) {
b6b38f70 789 cERROR(1, "Null tcp session");
1da177e4
LT
790 return -EIO;
791 }
792
79a58d1f 793 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
794 return -ENOENT;
795
79a58d1f 796 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
797 to the same server. We may make this configurable later or
798 use ses->maxReq */
1da177e4 799
be8e3b00
SF
800 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
801 MAX_CIFS_HDR_SIZE - 4) {
b6b38f70 802 cERROR(1, "Illegal length, greater than maximum frame, %d",
be8e3b00 803 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
804 return -EIO;
805 }
806
a891f0f8 807 rc = wait_for_free_request(ses->server, timeout, 0);
7ee1af76
JA
808 if (rc)
809 return rc;
810
79a58d1f 811 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
812 and avoid races inside tcp sendmsg code that could cause corruption
813 of smb data */
814
72ca545b 815 mutex_lock(&ses->server->srv_mutex);
1da177e4 816
7ee1af76
JA
817 rc = allocate_mid(ses, in_buf, &midQ);
818 if (rc) {
72ca545b 819 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 820 /* Update # of requests on wire to server */
a891f0f8 821 add_credits(ses->server, 1, 0);
7ee1af76 822 return rc;
1da177e4
LT
823 }
824
ad009ac9 825 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
826 if (rc) {
827 mutex_unlock(&ses->server->srv_mutex);
828 goto out;
829 }
1da177e4 830
7c9421e1 831 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661
SF
832
833 cifs_in_send_inc(ses->server);
be8e3b00 834 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
835 cifs_in_send_dec(ses->server);
836 cifs_save_when_sent(midQ);
72ca545b 837 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 838
79a58d1f 839 if (rc < 0)
7ee1af76
JA
840 goto out;
841
a891f0f8 842 if (timeout == CIFS_ASYNC_OP)
7ee1af76 843 goto out;
1da177e4 844
0ade640e 845 rc = wait_for_response(ses->server, midQ);
1be912dd 846 if (rc != 0) {
121b046a 847 send_cancel(ses->server, in_buf, midQ);
1be912dd 848 spin_lock(&GlobalMid_Lock);
7c9421e1 849 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
850 /* no longer considered to be "in-flight" */
851 midQ->callback = DeleteMidQEntry;
852 spin_unlock(&GlobalMid_Lock);
a891f0f8 853 add_credits(ses->server, 1, 0);
1be912dd
JL
854 return rc;
855 }
856 spin_unlock(&GlobalMid_Lock);
857 }
1da177e4 858
3c1105df 859 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 860 if (rc != 0) {
a891f0f8 861 add_credits(ses->server, 1, 0);
1da177e4
LT
862 return rc;
863 }
50c2f753 864
2c8f981d 865 if (!midQ->resp_buf || !out_buf ||
7c9421e1 866 midQ->mid_state != MID_RESPONSE_RECEIVED) {
2b2bdfba 867 rc = -EIO;
b6b38f70 868 cERROR(1, "Bad MID state?");
2c8f981d 869 goto out;
1da177e4 870 }
7ee1af76 871
d4e4854f 872 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
873 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
874 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 875out:
3c1bf7e4 876 cifs_delete_mid(midQ);
a891f0f8 877 add_credits(ses->server, 1, 0);
1da177e4 878
7ee1af76
JA
879 return rc;
880}
1da177e4 881
7ee1af76
JA
882/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
883 blocking lock to return. */
884
885static int
96daf2b0 886send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
887 struct smb_hdr *in_buf,
888 struct smb_hdr *out_buf)
889{
890 int bytes_returned;
96daf2b0 891 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
892 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
893
894 /* We just modify the current in_buf to change
895 the type of lock from LOCKING_ANDX_SHARED_LOCK
896 or LOCKING_ANDX_EXCLUSIVE_LOCK to
897 LOCKING_ANDX_CANCEL_LOCK. */
898
899 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
900 pSMB->Timeout = 0;
88257360 901 pSMB->hdr.Mid = get_next_mid(ses->server);
7ee1af76
JA
902
903 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 904 &bytes_returned, 0);
7ee1af76
JA
905}
906
907int
96daf2b0 908SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
909 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
910 int *pbytes_returned)
911{
912 int rc = 0;
913 int rstart = 0;
7ee1af76 914 struct mid_q_entry *midQ;
96daf2b0 915 struct cifs_ses *ses;
7ee1af76
JA
916
917 if (tcon == NULL || tcon->ses == NULL) {
b6b38f70 918 cERROR(1, "Null smb session");
7ee1af76
JA
919 return -EIO;
920 }
921 ses = tcon->ses;
922
79a58d1f 923 if (ses->server == NULL) {
b6b38f70 924 cERROR(1, "Null tcp session");
7ee1af76
JA
925 return -EIO;
926 }
927
79a58d1f 928 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
929 return -ENOENT;
930
79a58d1f 931 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
932 to the same server. We may make this configurable later or
933 use ses->maxReq */
934
be8e3b00
SF
935 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
936 MAX_CIFS_HDR_SIZE - 4) {
b6b38f70 937 cERROR(1, "Illegal length, greater than maximum frame, %d",
be8e3b00 938 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
939 return -EIO;
940 }
941
a891f0f8 942 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0);
7ee1af76
JA
943 if (rc)
944 return rc;
945
79a58d1f 946 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
947 and avoid races inside tcp sendmsg code that could cause corruption
948 of smb data */
949
72ca545b 950 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
951
952 rc = allocate_mid(ses, in_buf, &midQ);
953 if (rc) {
72ca545b 954 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
955 return rc;
956 }
957
7ee1af76 958 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 959 if (rc) {
3c1bf7e4 960 cifs_delete_mid(midQ);
829049cb
VL
961 mutex_unlock(&ses->server->srv_mutex);
962 return rc;
963 }
1da177e4 964
7c9421e1 965 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 966 cifs_in_send_inc(ses->server);
be8e3b00 967 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
968 cifs_in_send_dec(ses->server);
969 cifs_save_when_sent(midQ);
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;
b6b38f70 1035 cERROR(1, "Bad MID state?");
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}