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