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