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