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