cifs: For SMB2 security informaion query, check for minimum sized security descriptor...
[linux-block.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>
2f8b5444 31#include <linux/bvec.h>
97bc00b3 32#include <linux/highmem.h>
7c0f6ba6 33#include <linux/uaccess.h>
1da177e4
LT
34#include <asm/processor.h>
35#include <linux/mempool.h>
36#include "cifspdu.h"
37#include "cifsglob.h"
38#include "cifsproto.h"
39#include "cifs_debug.h"
8bd68c6e 40#include "smb2proto.h"
9762c2d0 41#include "smbdirect.h"
50c2f753 42
3cecf486
RS
43/* Max number of iovectors we can use off the stack when sending requests. */
44#define CIFS_MAX_IOV_SIZE 8
45
2dc7e1c0
PS
46void
47cifs_wake_up_task(struct mid_q_entry *mid)
2b84a36c
JL
48{
49 wake_up_process(mid->callback_data);
50}
51
a6827c18 52struct mid_q_entry *
24b9b06b 53AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
1da177e4
LT
54{
55 struct mid_q_entry *temp;
56
24b9b06b 57 if (server == NULL) {
f96637be 58 cifs_dbg(VFS, "Null TCP session in AllocMidQEntry\n");
1da177e4
LT
59 return NULL;
60 }
50c2f753 61
232087cb 62 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
a6f74e80
N
63 memset(temp, 0, sizeof(struct mid_q_entry));
64 temp->mid = get_mid(smb_buffer);
65 temp->pid = current->pid;
66 temp->command = cpu_to_le16(smb_buffer->Command);
67 cifs_dbg(FYI, "For smb_command %d\n", smb_buffer->Command);
1047abc1 68 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
a6f74e80
N
69 /* when mid allocated can be before when sent */
70 temp->when_alloc = jiffies;
71 temp->server = server;
2b84a36c 72
a6f74e80
N
73 /*
74 * The default is for the mid to be synchronous, so the
75 * default callback just wakes up the current task.
76 */
77 temp->callback = cifs_wake_up_task;
78 temp->callback_data = current;
1da177e4 79
1da177e4 80 atomic_inc(&midCount);
7c9421e1 81 temp->mid_state = MID_REQUEST_ALLOCATED;
1da177e4
LT
82 return temp;
83}
84
766fdbb5 85void
1da177e4
LT
86DeleteMidQEntry(struct mid_q_entry *midEntry)
87{
1047abc1 88#ifdef CONFIG_CIFS_STATS2
2dc7e1c0 89 __le16 command = midEntry->server->vals->lock_cmd;
1047abc1
SF
90 unsigned long now;
91#endif
7c9421e1 92 midEntry->mid_state = MID_FREE;
8097531a 93 atomic_dec(&midCount);
7c9421e1 94 if (midEntry->large_buf)
b8643e1b
SF
95 cifs_buf_release(midEntry->resp_buf);
96 else
97 cifs_small_buf_release(midEntry->resp_buf);
1047abc1
SF
98#ifdef CONFIG_CIFS_STATS2
99 now = jiffies;
100 /* commands taking longer than one second are indications that
101 something is wrong, unless it is quite a slow link or server */
4328fea7 102 if (time_after(now, midEntry->when_alloc + HZ)) {
2dc7e1c0 103 if ((cifsFYI & CIFS_TIMER) && (midEntry->command != command)) {
0b456f04 104 pr_debug(" CIFS slow rsp: cmd %d mid %llu",
1047abc1 105 midEntry->command, midEntry->mid);
0b456f04 106 pr_info(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
1047abc1
SF
107 now - midEntry->when_alloc,
108 now - midEntry->when_sent,
109 now - midEntry->when_received);
110 }
111 }
112#endif
1da177e4
LT
113 mempool_free(midEntry, cifs_mid_poolp);
114}
115
3c1bf7e4
PS
116void
117cifs_delete_mid(struct mid_q_entry *mid)
ddc8cf8f
JL
118{
119 spin_lock(&GlobalMid_Lock);
120 list_del(&mid->qhead);
121 spin_unlock(&GlobalMid_Lock);
122
123 DeleteMidQEntry(mid);
124}
125
6f49f46b
JL
126/*
127 * smb_send_kvec - send an array of kvecs to the server
128 * @server: Server to send the data to
3ab3f2a1 129 * @smb_msg: Message to send
6f49f46b
JL
130 * @sent: amount of data sent on socket is stored here
131 *
132 * Our basic "send data to server" function. Should be called with srv_mutex
133 * held. The caller is responsible for handling the results.
134 */
d6e04ae6 135static int
3ab3f2a1
AV
136smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
137 size_t *sent)
1da177e4
LT
138{
139 int rc = 0;
3ab3f2a1 140 int retries = 0;
edf1ae40 141 struct socket *ssocket = server->ssocket;
50c2f753 142
6f49f46b
JL
143 *sent = 0;
144
3ab3f2a1
AV
145 smb_msg->msg_name = (struct sockaddr *) &server->dstaddr;
146 smb_msg->msg_namelen = sizeof(struct sockaddr);
147 smb_msg->msg_control = NULL;
148 smb_msg->msg_controllen = 0;
0496e02d 149 if (server->noblocksnd)
3ab3f2a1 150 smb_msg->msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
edf1ae40 151 else
3ab3f2a1 152 smb_msg->msg_flags = MSG_NOSIGNAL;
1da177e4 153
3ab3f2a1 154 while (msg_data_left(smb_msg)) {
6f49f46b
JL
155 /*
156 * If blocking send, we try 3 times, since each can block
157 * for 5 seconds. For nonblocking we have to try more
158 * but wait increasing amounts of time allowing time for
159 * socket to clear. The overall time we wait in either
160 * case to send on the socket is about 15 seconds.
161 * Similarly we wait for 15 seconds for a response from
162 * the server in SendReceive[2] for the server to send
163 * a response back for most types of requests (except
164 * SMB Write past end of file which can be slow, and
165 * blocking lock operations). NFS waits slightly longer
166 * than CIFS, but this can make it take longer for
167 * nonresponsive servers to be detected and 15 seconds
168 * is more than enough time for modern networks to
169 * send a packet. In most cases if we fail to send
170 * after the retries we will kill the socket and
171 * reconnect which may clear the network problem.
172 */
3ab3f2a1 173 rc = sock_sendmsg(ssocket, smb_msg);
ce6c44e4 174 if (rc == -EAGAIN) {
3ab3f2a1
AV
175 retries++;
176 if (retries >= 14 ||
177 (!server->noblocksnd && (retries > 2))) {
f96637be
JP
178 cifs_dbg(VFS, "sends on sock %p stuck for 15 seconds\n",
179 ssocket);
3ab3f2a1 180 return -EAGAIN;
1da177e4 181 }
3ab3f2a1 182 msleep(1 << retries);
1da177e4
LT
183 continue;
184 }
6f49f46b 185
79a58d1f 186 if (rc < 0)
3ab3f2a1 187 return rc;
6f49f46b 188
79a58d1f 189 if (rc == 0) {
3e84469d
SF
190 /* should never happen, letting socket clear before
191 retrying is our only obvious option here */
f96637be 192 cifs_dbg(VFS, "tcp sent no data\n");
3e84469d
SF
193 msleep(500);
194 continue;
d6e04ae6 195 }
6f49f46b 196
3ab3f2a1
AV
197 /* send was at least partially successful */
198 *sent += rc;
199 retries = 0; /* in case we get ENOSPC on the next send */
1da177e4 200 }
3ab3f2a1 201 return 0;
97bc00b3
JL
202}
203
a26054d1
JL
204static unsigned long
205rqst_len(struct smb_rqst *rqst)
206{
207 unsigned int i;
208 struct kvec *iov = rqst->rq_iov;
209 unsigned long buflen = 0;
210
211 /* total up iov array first */
212 for (i = 0; i < rqst->rq_nvec; i++)
213 buflen += iov[i].iov_len;
214
215 /* add in the page array if there is one */
216 if (rqst->rq_npages) {
217 buflen += rqst->rq_pagesz * (rqst->rq_npages - 1);
218 buflen += rqst->rq_tailsz;
219 }
220
221 return buflen;
222}
223
6f49f46b 224static int
7fb8986e 225__smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
6f49f46b
JL
226{
227 int rc;
228 struct kvec *iov = rqst->rq_iov;
229 int n_vec = rqst->rq_nvec;
230 unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
a26054d1 231 unsigned long send_length;
97bc00b3 232 unsigned int i;
3ab3f2a1 233 size_t total_len = 0, sent, size;
b8eed283 234 struct socket *ssocket = server->ssocket;
3ab3f2a1 235 struct msghdr smb_msg;
b8eed283 236 int val = 1;
9762c2d0
LL
237 if (cifs_rdma_enabled(server) && server->smbd_conn) {
238 rc = smbd_send(server->smbd_conn, rqst);
239 goto smbd_done;
240 }
ea702b80
JL
241 if (ssocket == NULL)
242 return -ENOTSOCK;
243
a26054d1
JL
244 /* sanity check send length */
245 send_length = rqst_len(rqst);
246 if (send_length != smb_buf_length + 4) {
247 WARN(1, "Send length mismatch(send_length=%lu smb_buf_length=%u)\n",
248 send_length, smb_buf_length);
249 return -EIO;
250 }
251
738f9de5
PS
252 if (n_vec < 2)
253 return -EIO;
254
f96637be 255 cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length);
6f49f46b 256 dump_smb(iov[0].iov_base, iov[0].iov_len);
738f9de5 257 dump_smb(iov[1].iov_base, iov[1].iov_len);
6f49f46b 258
b8eed283
JL
259 /* cork the socket */
260 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
261 (char *)&val, sizeof(val));
262
3ab3f2a1
AV
263 size = 0;
264 for (i = 0; i < n_vec; i++)
265 size += iov[i].iov_len;
266
267 iov_iter_kvec(&smb_msg.msg_iter, WRITE | ITER_KVEC, iov, n_vec, size);
268
269 rc = smb_send_kvec(server, &smb_msg, &sent);
97bc00b3
JL
270 if (rc < 0)
271 goto uncork;
272
273 total_len += sent;
274
275 /* now walk the page array and send each page in it */
276 for (i = 0; i < rqst->rq_npages; i++) {
3ab3f2a1
AV
277 size_t len = i == rqst->rq_npages - 1
278 ? rqst->rq_tailsz
279 : rqst->rq_pagesz;
280 struct bio_vec bvec = {
281 .bv_page = rqst->rq_pages[i],
282 .bv_len = len
283 };
284 iov_iter_bvec(&smb_msg.msg_iter, WRITE | ITER_BVEC,
285 &bvec, 1, len);
286 rc = smb_send_kvec(server, &smb_msg, &sent);
97bc00b3
JL
287 if (rc < 0)
288 break;
289
290 total_len += sent;
291 }
1da177e4 292
97bc00b3 293uncork:
b8eed283
JL
294 /* uncork it */
295 val = 0;
296 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
297 (char *)&val, sizeof(val));
298
edf1ae40 299 if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
f96637be
JP
300 cifs_dbg(FYI, "partial send (wanted=%u sent=%zu): terminating session\n",
301 smb_buf_length + 4, total_len);
6f49f46b
JL
302 /*
303 * If we have only sent part of an SMB then the next SMB could
304 * be taken as the remainder of this one. We need to kill the
305 * socket so the server throws away the partial SMB
306 */
edf1ae40
SF
307 server->tcpStatus = CifsNeedReconnect;
308 }
9762c2d0 309smbd_done:
d804d41d 310 if (rc < 0 && rc != -EINTR)
f96637be
JP
311 cifs_dbg(VFS, "Error %d sending data on socket to server\n",
312 rc);
d804d41d 313 else
1da177e4 314 rc = 0;
1da177e4
LT
315
316 return rc;
317}
318
6f49f46b 319static int
7fb8986e 320smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags)
6f49f46b 321{
7fb8986e
PS
322 struct smb_rqst cur_rqst;
323 int rc;
324
325 if (!(flags & CIFS_TRANSFORM_REQ))
326 return __smb_send_rqst(server, rqst);
327
328 if (!server->ops->init_transform_rq ||
329 !server->ops->free_transform_rq) {
330 cifs_dbg(VFS, "Encryption requested but transform callbacks are missed\n");
331 return -EIO;
332 }
6f49f46b 333
7fb8986e
PS
334 rc = server->ops->init_transform_rq(server, &cur_rqst, rqst);
335 if (rc)
336 return rc;
337
338 rc = __smb_send_rqst(server, &cur_rqst);
339 server->ops->free_transform_rq(&cur_rqst);
340 return rc;
6f49f46b
JL
341}
342
0496e02d
JL
343int
344smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
345 unsigned int smb_buf_length)
346{
738f9de5 347 struct kvec iov[2];
7fb8986e
PS
348 struct smb_rqst rqst = { .rq_iov = iov,
349 .rq_nvec = 2 };
0496e02d 350
738f9de5
PS
351 iov[0].iov_base = smb_buffer;
352 iov[0].iov_len = 4;
353 iov[1].iov_base = (char *)smb_buffer + 4;
354 iov[1].iov_len = smb_buf_length;
0496e02d 355
7fb8986e 356 return __smb_send_rqst(server, &rqst);
0496e02d
JL
357}
358
fc40f9cf 359static int
a891f0f8 360wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
bc205ed1 361 int *credits)
1da177e4 362{
5bc59498
PS
363 int rc;
364
fc40f9cf 365 spin_lock(&server->req_lock);
a891f0f8 366 if (timeout == CIFS_ASYNC_OP) {
1da177e4 367 /* oplock breaks must not be held up */
fc40f9cf 368 server->in_flight++;
bc205ed1 369 *credits -= 1;
fc40f9cf 370 spin_unlock(&server->req_lock);
27a97a61
VL
371 return 0;
372 }
373
27a97a61 374 while (1) {
bc205ed1 375 if (*credits <= 0) {
fc40f9cf 376 spin_unlock(&server->req_lock);
789e6661 377 cifs_num_waiters_inc(server);
5bc59498 378 rc = wait_event_killable(server->request_q,
bc205ed1 379 has_credits(server, credits));
789e6661 380 cifs_num_waiters_dec(server);
5bc59498
PS
381 if (rc)
382 return rc;
fc40f9cf 383 spin_lock(&server->req_lock);
27a97a61 384 } else {
c5797a94 385 if (server->tcpStatus == CifsExiting) {
fc40f9cf 386 spin_unlock(&server->req_lock);
27a97a61 387 return -ENOENT;
1da177e4 388 }
27a97a61 389
2d86dbc9
PS
390 /*
391 * Can not count locking commands against total
392 * as they are allowed to block on server.
393 */
27a97a61
VL
394
395 /* update # of requests on the wire to server */
a891f0f8 396 if (timeout != CIFS_BLOCKING_OP) {
bc205ed1 397 *credits -= 1;
fc40f9cf 398 server->in_flight++;
2d86dbc9 399 }
fc40f9cf 400 spin_unlock(&server->req_lock);
27a97a61 401 break;
1da177e4
LT
402 }
403 }
7ee1af76
JA
404 return 0;
405}
1da177e4 406
bc205ed1 407static int
a891f0f8
PS
408wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
409 const int optype)
bc205ed1 410{
eb4c7df6
SP
411 int *val;
412
413 val = server->ops->get_credits_field(server, optype);
414 /* Since an echo is already inflight, no need to wait to send another */
415 if (*val <= 0 && optype == CIFS_ECHO_OP)
416 return -EAGAIN;
417 return wait_for_free_credits(server, timeout, val);
bc205ed1
PS
418}
419
cb7e9eab
PS
420int
421cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
422 unsigned int *num, unsigned int *credits)
423{
424 *num = size;
425 *credits = 0;
426 return 0;
427}
428
96daf2b0 429static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
7ee1af76
JA
430 struct mid_q_entry **ppmidQ)
431{
1da177e4 432 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 433 return -ENOENT;
8fbbd365
VL
434 }
435
436 if (ses->server->tcpStatus == CifsNeedReconnect) {
f96637be 437 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
7ee1af76 438 return -EAGAIN;
8fbbd365
VL
439 }
440
7f48558e 441 if (ses->status == CifsNew) {
79a58d1f 442 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 443 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 444 return -EAGAIN;
ad7a2926 445 /* else ok - we are setting up session */
1da177e4 446 }
7f48558e
SP
447
448 if (ses->status == CifsExiting) {
449 /* check if SMB session is bad because we are setting it up */
450 if (in_buf->Command != SMB_COM_LOGOFF_ANDX)
451 return -EAGAIN;
452 /* else ok - we are shutting down session */
453 }
454
24b9b06b 455 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 456 if (*ppmidQ == NULL)
7ee1af76 457 return -ENOMEM;
ddc8cf8f
JL
458 spin_lock(&GlobalMid_Lock);
459 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
460 spin_unlock(&GlobalMid_Lock);
7ee1af76
JA
461 return 0;
462}
463
0ade640e
JL
464static int
465wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
7ee1af76 466{
0ade640e 467 int error;
7ee1af76 468
5853cc2a 469 error = wait_event_freezekillable_unsafe(server->response_q,
7c9421e1 470 midQ->mid_state != MID_REQUEST_SUBMITTED);
0ade640e
JL
471 if (error < 0)
472 return -ERESTARTSYS;
7ee1af76 473
0ade640e 474 return 0;
7ee1af76
JA
475}
476
fec344e3
JL
477struct mid_q_entry *
478cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
792af7b0
PS
479{
480 int rc;
fec344e3 481 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
482 struct mid_q_entry *mid;
483
738f9de5
PS
484 if (rqst->rq_iov[0].iov_len != 4 ||
485 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
486 return ERR_PTR(-EIO);
487
792af7b0 488 /* enable signing if server requires it */
38d77c50 489 if (server->sign)
792af7b0
PS
490 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
491
492 mid = AllocMidQEntry(hdr, server);
493 if (mid == NULL)
fec344e3 494 return ERR_PTR(-ENOMEM);
792af7b0 495
fec344e3 496 rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);
ffc61ccb
SP
497 if (rc) {
498 DeleteMidQEntry(mid);
fec344e3 499 return ERR_PTR(rc);
ffc61ccb
SP
500 }
501
fec344e3 502 return mid;
792af7b0 503}
133672ef 504
a6827c18
JL
505/*
506 * Send a SMB request and set the callback function in the mid to handle
507 * the result. Caller is responsible for dealing with timeouts.
508 */
509int
fec344e3 510cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
9b7c18a2
PS
511 mid_receive_t *receive, mid_callback_t *callback,
512 mid_handle_t *handle, void *cbdata, const int flags)
a6827c18 513{
a891f0f8 514 int rc, timeout, optype;
a6827c18 515 struct mid_q_entry *mid;
cb7e9eab 516 unsigned int credits = 0;
a6827c18 517
a891f0f8
PS
518 timeout = flags & CIFS_TIMEOUT_MASK;
519 optype = flags & CIFS_OP_MASK;
520
cb7e9eab
PS
521 if ((flags & CIFS_HAS_CREDITS) == 0) {
522 rc = wait_for_free_request(server, timeout, optype);
523 if (rc)
524 return rc;
525 credits = 1;
526 }
a6827c18
JL
527
528 mutex_lock(&server->srv_mutex);
fec344e3
JL
529 mid = server->ops->setup_async_request(server, rqst);
530 if (IS_ERR(mid)) {
a6827c18 531 mutex_unlock(&server->srv_mutex);
cb7e9eab 532 add_credits_and_wake_if(server, credits, optype);
fec344e3 533 return PTR_ERR(mid);
a6827c18
JL
534 }
535
44d22d84 536 mid->receive = receive;
a6827c18
JL
537 mid->callback = callback;
538 mid->callback_data = cbdata;
9b7c18a2 539 mid->handle = handle;
7c9421e1 540 mid->mid_state = MID_REQUEST_SUBMITTED;
789e6661 541
ffc61ccb
SP
542 /* put it on the pending_mid_q */
543 spin_lock(&GlobalMid_Lock);
544 list_add_tail(&mid->qhead, &server->pending_mid_q);
545 spin_unlock(&GlobalMid_Lock);
546
93d2cb6c
LL
547 /*
548 * Need to store the time in mid before calling I/O. For call_async,
549 * I/O response may come back and free the mid entry on another thread.
550 */
551 cifs_save_when_sent(mid);
789e6661 552 cifs_in_send_inc(server);
7fb8986e 553 rc = smb_send_rqst(server, rqst, flags);
789e6661 554 cifs_in_send_dec(server);
ad313cb8 555
820962dc 556 if (rc < 0) {
ad313cb8 557 server->sequence_number -= 2;
820962dc
RV
558 cifs_delete_mid(mid);
559 }
560
a6827c18 561 mutex_unlock(&server->srv_mutex);
789e6661 562
ffc61ccb
SP
563 if (rc == 0)
564 return 0;
a6827c18 565
cb7e9eab 566 add_credits_and_wake_if(server, credits, optype);
a6827c18
JL
567 return rc;
568}
569
133672ef
SF
570/*
571 *
572 * Send an SMB Request. No response info (other than return code)
573 * needs to be parsed.
574 *
575 * flags indicate the type of request buffer and how long to wait
576 * and whether to log NT STATUS code (error) before mapping it to POSIX error
577 *
578 */
579int
96daf2b0 580SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
792af7b0 581 char *in_buf, int flags)
133672ef
SF
582{
583 int rc;
584 struct kvec iov[1];
da502f7d 585 struct kvec rsp_iov;
133672ef
SF
586 int resp_buf_type;
587
792af7b0
PS
588 iov[0].iov_base = in_buf;
589 iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
133672ef 590 flags |= CIFS_NO_RESP;
da502f7d 591 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
f96637be 592 cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
90c81e0b 593
133672ef
SF
594 return rc;
595}
596
053d5034 597static int
3c1105df 598cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
053d5034
JL
599{
600 int rc = 0;
601
f96637be
JP
602 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
603 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
053d5034 604
74dd92a8 605 spin_lock(&GlobalMid_Lock);
7c9421e1 606 switch (mid->mid_state) {
74dd92a8 607 case MID_RESPONSE_RECEIVED:
053d5034
JL
608 spin_unlock(&GlobalMid_Lock);
609 return rc;
74dd92a8
JL
610 case MID_RETRY_NEEDED:
611 rc = -EAGAIN;
612 break;
71823baf
JL
613 case MID_RESPONSE_MALFORMED:
614 rc = -EIO;
615 break;
3c1105df
JL
616 case MID_SHUTDOWN:
617 rc = -EHOSTDOWN;
618 break;
74dd92a8 619 default:
3c1105df 620 list_del_init(&mid->qhead);
f96637be
JP
621 cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
622 __func__, mid->mid, mid->mid_state);
74dd92a8 623 rc = -EIO;
053d5034
JL
624 }
625 spin_unlock(&GlobalMid_Lock);
626
2b84a36c 627 DeleteMidQEntry(mid);
053d5034
JL
628 return rc;
629}
630
121b046a 631static inline int
fb2036d8
PS
632send_cancel(struct TCP_Server_Info *server, struct smb_rqst *rqst,
633 struct mid_q_entry *mid)
76dcc26f 634{
121b046a 635 return server->ops->send_cancel ?
fb2036d8 636 server->ops->send_cancel(server, rqst, mid) : 0;
76dcc26f
JL
637}
638
2c8f981d
JL
639int
640cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
641 bool log_error)
642{
792af7b0 643 unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
826a95e4
JL
644
645 dump_smb(mid->resp_buf, min_t(u32, 92, len));
2c8f981d
JL
646
647 /* convert the length into a more usable form */
38d77c50 648 if (server->sign) {
738f9de5 649 struct kvec iov[2];
985e4ff0 650 int rc = 0;
738f9de5
PS
651 struct smb_rqst rqst = { .rq_iov = iov,
652 .rq_nvec = 2 };
826a95e4 653
738f9de5
PS
654 iov[0].iov_base = mid->resp_buf;
655 iov[0].iov_len = 4;
656 iov[1].iov_base = (char *)mid->resp_buf + 4;
657 iov[1].iov_len = len - 4;
2c8f981d 658 /* FIXME: add code to kill session */
bf5ea0e2 659 rc = cifs_verify_signature(&rqst, server,
0124cc45 660 mid->sequence_number);
985e4ff0 661 if (rc)
f96637be
JP
662 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
663 rc);
2c8f981d
JL
664 }
665
666 /* BB special case reconnect tid and uid here? */
667 return map_smb_to_linux_error(mid->resp_buf, log_error);
668}
669
fec344e3
JL
670struct mid_q_entry *
671cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
792af7b0
PS
672{
673 int rc;
fec344e3 674 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
675 struct mid_q_entry *mid;
676
738f9de5
PS
677 if (rqst->rq_iov[0].iov_len != 4 ||
678 rqst->rq_iov[0].iov_base + 4 != rqst->rq_iov[1].iov_base)
679 return ERR_PTR(-EIO);
680
792af7b0
PS
681 rc = allocate_mid(ses, hdr, &mid);
682 if (rc)
fec344e3
JL
683 return ERR_PTR(rc);
684 rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
685 if (rc) {
3c1bf7e4 686 cifs_delete_mid(mid);
fec344e3
JL
687 return ERR_PTR(rc);
688 }
689 return mid;
792af7b0
PS
690}
691
b8f57ee8 692int
738f9de5
PS
693cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
694 struct smb_rqst *rqst, int *resp_buf_type, const int flags,
695 struct kvec *resp_iov)
7ee1af76
JA
696{
697 int rc = 0;
a891f0f8 698 int timeout, optype;
7ee1af76 699 struct mid_q_entry *midQ;
a891f0f8 700 unsigned int credits = 1;
738f9de5 701 char *buf;
50c2f753 702
a891f0f8
PS
703 timeout = flags & CIFS_TIMEOUT_MASK;
704 optype = flags & CIFS_OP_MASK;
133672ef 705
a891f0f8 706 *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */
7ee1af76
JA
707
708 if ((ses == NULL) || (ses->server == NULL)) {
f96637be 709 cifs_dbg(VFS, "Null session\n");
7ee1af76
JA
710 return -EIO;
711 }
712
da502f7d 713 if (ses->server->tcpStatus == CifsExiting)
7ee1af76 714 return -ENOENT;
7ee1af76 715
792af7b0
PS
716 /*
717 * Ensure that we do not send more than 50 overlapping requests
718 * to the same server. We may make this configurable later or
719 * use ses->maxReq.
720 */
7ee1af76 721
a891f0f8 722 rc = wait_for_free_request(ses->server, timeout, optype);
da502f7d 723 if (rc)
7ee1af76 724 return rc;
7ee1af76 725
792af7b0
PS
726 /*
727 * Make sure that we sign in the same order that we send on this socket
728 * and avoid races inside tcp sendmsg code that could cause corruption
729 * of smb data.
730 */
7ee1af76 731
72ca545b 732 mutex_lock(&ses->server->srv_mutex);
7ee1af76 733
738f9de5 734 midQ = ses->server->ops->setup_request(ses, rqst);
fec344e3 735 if (IS_ERR(midQ)) {
72ca545b 736 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 737 /* Update # of requests on wire to server */
a891f0f8 738 add_credits(ses->server, 1, optype);
fec344e3 739 return PTR_ERR(midQ);
1da177e4 740 }
1da177e4 741
7c9421e1 742 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 743 cifs_in_send_inc(ses->server);
7fb8986e 744 rc = smb_send_rqst(ses->server, rqst, flags);
789e6661
SF
745 cifs_in_send_dec(ses->server);
746 cifs_save_when_sent(midQ);
7ee1af76 747
ad313cb8
JL
748 if (rc < 0)
749 ses->server->sequence_number -= 2;
72ca545b 750 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 751
da502f7d 752 if (rc < 0)
7ee1af76 753 goto out;
4b8f930f 754
8bd68c6e 755#ifdef CONFIG_CIFS_SMB311
0d5ec281 756 if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
8bd68c6e
AA
757 smb311_update_preauth_hash(ses, rqst->rq_iov+1,
758 rqst->rq_nvec-1);
759#endif
760
da502f7d 761 if (timeout == CIFS_ASYNC_OP)
133672ef 762 goto out;
d6e04ae6 763
0ade640e 764 rc = wait_for_response(ses->server, midQ);
1be912dd 765 if (rc != 0) {
38bd4906 766 cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid);
738f9de5 767 send_cancel(ses->server, rqst, midQ);
1be912dd 768 spin_lock(&GlobalMid_Lock);
7c9421e1 769 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
38bd4906 770 midQ->mid_flags |= MID_WAIT_CANCELLED;
1be912dd
JL
771 midQ->callback = DeleteMidQEntry;
772 spin_unlock(&GlobalMid_Lock);
a891f0f8 773 add_credits(ses->server, 1, optype);
1be912dd
JL
774 return rc;
775 }
776 spin_unlock(&GlobalMid_Lock);
777 }
d6e04ae6 778
3c1105df 779 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 780 if (rc != 0) {
a891f0f8 781 add_credits(ses->server, 1, optype);
d6e04ae6
SF
782 return rc;
783 }
50c2f753 784
7c9421e1 785 if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
d6e04ae6 786 rc = -EIO;
f96637be 787 cifs_dbg(FYI, "Bad MID state?\n");
2b2bdfba
SF
788 goto out;
789 }
790
792af7b0 791 buf = (char *)midQ->resp_buf;
da502f7d 792 resp_iov->iov_base = buf;
e19b2bc0 793 resp_iov->iov_len = midQ->resp_buf_size +
93012bf9 794 ses->server->vals->header_preamble_size;
7c9421e1 795 if (midQ->large_buf)
a891f0f8 796 *resp_buf_type = CIFS_LARGE_BUFFER;
2c8f981d 797 else
a891f0f8
PS
798 *resp_buf_type = CIFS_SMALL_BUFFER;
799
8bd68c6e 800#ifdef CONFIG_CIFS_SMB311
0d5ec281 801 if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
8bd68c6e 802 struct kvec iov = {
977b6170
RS
803 .iov_base = buf,
804 .iov_len = midQ->resp_buf_size
8bd68c6e
AA
805 };
806 smb311_update_preauth_hash(ses, &iov, 1);
807 }
808#endif
809
a891f0f8 810 credits = ses->server->ops->get_credits(midQ);
2b2bdfba 811
082d0642
PS
812 rc = ses->server->ops->check_receive(midQ, ses->server,
813 flags & CIFS_LOG_ERROR);
1da177e4 814
3c1bf7e4 815 /* mark it so buf will not be freed by cifs_delete_mid */
2c8f981d
JL
816 if ((flags & CIFS_NO_RESP) == 0)
817 midQ->resp_buf = NULL;
7ee1af76 818out:
3c1bf7e4 819 cifs_delete_mid(midQ);
a891f0f8 820 add_credits(ses->server, credits, optype);
1da177e4 821
d6e04ae6
SF
822 return rc;
823}
1da177e4 824
738f9de5
PS
825int
826SendReceive2(const unsigned int xid, struct cifs_ses *ses,
827 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
828 const int flags, struct kvec *resp_iov)
829{
830 struct smb_rqst rqst;
3cecf486 831 struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov;
738f9de5
PS
832 int rc;
833
3cecf486
RS
834 if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
835 new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1),
836 GFP_KERNEL);
117e3b7f
SF
837 if (!new_iov) {
838 /* otherwise cifs_send_recv below sets resp_buf_type */
839 *resp_buf_type = CIFS_NO_BUFFER;
3cecf486 840 return -ENOMEM;
117e3b7f 841 }
3cecf486
RS
842 } else
843 new_iov = s_iov;
738f9de5
PS
844
845 /* 1st iov is a RFC1001 length followed by the rest of the packet */
846 memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec));
847
848 new_iov[0].iov_base = new_iov[1].iov_base;
849 new_iov[0].iov_len = 4;
850 new_iov[1].iov_base += 4;
851 new_iov[1].iov_len -= 4;
852
853 memset(&rqst, 0, sizeof(struct smb_rqst));
854 rqst.rq_iov = new_iov;
855 rqst.rq_nvec = n_vec + 1;
856
857 rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
3cecf486
RS
858 if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
859 kfree(new_iov);
738f9de5
PS
860 return rc;
861}
862
83b77391
RS
863/* Like SendReceive2 but iov[0] does not contain an rfc1002 header */
864int
865smb2_send_recv(const unsigned int xid, struct cifs_ses *ses,
866 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
867 const int flags, struct kvec *resp_iov)
868{
869 struct smb_rqst rqst;
3cecf486 870 struct kvec s_iov[CIFS_MAX_IOV_SIZE], *new_iov;
83b77391
RS
871 int rc;
872 int i;
873 __u32 count;
874 __be32 rfc1002_marker;
875
3cecf486
RS
876 if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
877 new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1),
878 GFP_KERNEL);
879 if (!new_iov)
880 return -ENOMEM;
881 } else
882 new_iov = s_iov;
83b77391
RS
883
884 /* 1st iov is an RFC1002 Session Message length */
885 memcpy(new_iov + 1, iov, (sizeof(struct kvec) * n_vec));
886
887 count = 0;
888 for (i = 1; i < n_vec + 1; i++)
889 count += new_iov[i].iov_len;
890
891 rfc1002_marker = cpu_to_be32(count);
892
893 new_iov[0].iov_base = &rfc1002_marker;
894 new_iov[0].iov_len = 4;
895
896 memset(&rqst, 0, sizeof(struct smb_rqst));
897 rqst.rq_iov = new_iov;
898 rqst.rq_nvec = n_vec + 1;
899
900 rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
3cecf486
RS
901 if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
902 kfree(new_iov);
83b77391
RS
903 return rc;
904}
905
1da177e4 906int
96daf2b0 907SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4 908 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
a891f0f8 909 int *pbytes_returned, const int timeout)
1da177e4
LT
910{
911 int rc = 0;
1da177e4 912 struct mid_q_entry *midQ;
fb2036d8
PS
913 unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
914 struct kvec iov = { .iov_base = in_buf, .iov_len = len };
915 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
1da177e4
LT
916
917 if (ses == NULL) {
f96637be 918 cifs_dbg(VFS, "Null smb session\n");
1da177e4
LT
919 return -EIO;
920 }
79a58d1f 921 if (ses->server == NULL) {
f96637be 922 cifs_dbg(VFS, "Null tcp session\n");
1da177e4
LT
923 return -EIO;
924 }
925
79a58d1f 926 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
927 return -ENOENT;
928
79a58d1f 929 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
930 to the same server. We may make this configurable later or
931 use ses->maxReq */
1da177e4 932
fb2036d8 933 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
f96637be 934 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
fb2036d8 935 len);
6d9c6d54
VL
936 return -EIO;
937 }
938
a891f0f8 939 rc = wait_for_free_request(ses->server, timeout, 0);
7ee1af76
JA
940 if (rc)
941 return rc;
942
79a58d1f 943 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
944 and avoid races inside tcp sendmsg code that could cause corruption
945 of smb data */
946
72ca545b 947 mutex_lock(&ses->server->srv_mutex);
1da177e4 948
7ee1af76
JA
949 rc = allocate_mid(ses, in_buf, &midQ);
950 if (rc) {
72ca545b 951 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 952 /* Update # of requests on wire to server */
a891f0f8 953 add_credits(ses->server, 1, 0);
7ee1af76 954 return rc;
1da177e4
LT
955 }
956
ad009ac9 957 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
958 if (rc) {
959 mutex_unlock(&ses->server->srv_mutex);
960 goto out;
961 }
1da177e4 962
7c9421e1 963 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661
SF
964
965 cifs_in_send_inc(ses->server);
fb2036d8 966 rc = smb_send(ses->server, in_buf, len);
789e6661
SF
967 cifs_in_send_dec(ses->server);
968 cifs_save_when_sent(midQ);
ad313cb8
JL
969
970 if (rc < 0)
971 ses->server->sequence_number -= 2;
972
72ca545b 973 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 974
79a58d1f 975 if (rc < 0)
7ee1af76
JA
976 goto out;
977
a891f0f8 978 if (timeout == CIFS_ASYNC_OP)
7ee1af76 979 goto out;
1da177e4 980
0ade640e 981 rc = wait_for_response(ses->server, midQ);
1be912dd 982 if (rc != 0) {
fb2036d8 983 send_cancel(ses->server, &rqst, midQ);
1be912dd 984 spin_lock(&GlobalMid_Lock);
7c9421e1 985 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
986 /* no longer considered to be "in-flight" */
987 midQ->callback = DeleteMidQEntry;
988 spin_unlock(&GlobalMid_Lock);
a891f0f8 989 add_credits(ses->server, 1, 0);
1be912dd
JL
990 return rc;
991 }
992 spin_unlock(&GlobalMid_Lock);
993 }
1da177e4 994
3c1105df 995 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 996 if (rc != 0) {
a891f0f8 997 add_credits(ses->server, 1, 0);
1da177e4
LT
998 return rc;
999 }
50c2f753 1000
2c8f981d 1001 if (!midQ->resp_buf || !out_buf ||
7c9421e1 1002 midQ->mid_state != MID_RESPONSE_RECEIVED) {
2b2bdfba 1003 rc = -EIO;
f96637be 1004 cifs_dbg(VFS, "Bad MID state?\n");
2c8f981d 1005 goto out;
1da177e4 1006 }
7ee1af76 1007
d4e4854f 1008 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1009 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1010 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 1011out:
3c1bf7e4 1012 cifs_delete_mid(midQ);
a891f0f8 1013 add_credits(ses->server, 1, 0);
1da177e4 1014
7ee1af76
JA
1015 return rc;
1016}
1da177e4 1017
7ee1af76
JA
1018/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
1019 blocking lock to return. */
1020
1021static int
96daf2b0 1022send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
1023 struct smb_hdr *in_buf,
1024 struct smb_hdr *out_buf)
1025{
1026 int bytes_returned;
96daf2b0 1027 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
1028 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
1029
1030 /* We just modify the current in_buf to change
1031 the type of lock from LOCKING_ANDX_SHARED_LOCK
1032 or LOCKING_ANDX_EXCLUSIVE_LOCK to
1033 LOCKING_ANDX_CANCEL_LOCK. */
1034
1035 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
1036 pSMB->Timeout = 0;
88257360 1037 pSMB->hdr.Mid = get_next_mid(ses->server);
7ee1af76
JA
1038
1039 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 1040 &bytes_returned, 0);
7ee1af76
JA
1041}
1042
1043int
96daf2b0 1044SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
1045 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
1046 int *pbytes_returned)
1047{
1048 int rc = 0;
1049 int rstart = 0;
7ee1af76 1050 struct mid_q_entry *midQ;
96daf2b0 1051 struct cifs_ses *ses;
fb2036d8
PS
1052 unsigned int len = be32_to_cpu(in_buf->smb_buf_length);
1053 struct kvec iov = { .iov_base = in_buf, .iov_len = len };
1054 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 };
7ee1af76
JA
1055
1056 if (tcon == NULL || tcon->ses == NULL) {
f96637be 1057 cifs_dbg(VFS, "Null smb session\n");
7ee1af76
JA
1058 return -EIO;
1059 }
1060 ses = tcon->ses;
1061
79a58d1f 1062 if (ses->server == NULL) {
f96637be 1063 cifs_dbg(VFS, "Null tcp session\n");
7ee1af76
JA
1064 return -EIO;
1065 }
1066
79a58d1f 1067 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
1068 return -ENOENT;
1069
79a58d1f 1070 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
1071 to the same server. We may make this configurable later or
1072 use ses->maxReq */
1073
fb2036d8 1074 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
f96637be 1075 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
fb2036d8 1076 len);
6d9c6d54
VL
1077 return -EIO;
1078 }
1079
a891f0f8 1080 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0);
7ee1af76
JA
1081 if (rc)
1082 return rc;
1083
79a58d1f 1084 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
1085 and avoid races inside tcp sendmsg code that could cause corruption
1086 of smb data */
1087
72ca545b 1088 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
1089
1090 rc = allocate_mid(ses, in_buf, &midQ);
1091 if (rc) {
72ca545b 1092 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
1093 return rc;
1094 }
1095
7ee1af76 1096 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 1097 if (rc) {
3c1bf7e4 1098 cifs_delete_mid(midQ);
829049cb
VL
1099 mutex_unlock(&ses->server->srv_mutex);
1100 return rc;
1101 }
1da177e4 1102
7c9421e1 1103 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 1104 cifs_in_send_inc(ses->server);
fb2036d8 1105 rc = smb_send(ses->server, in_buf, len);
789e6661
SF
1106 cifs_in_send_dec(ses->server);
1107 cifs_save_when_sent(midQ);
ad313cb8
JL
1108
1109 if (rc < 0)
1110 ses->server->sequence_number -= 2;
1111
72ca545b 1112 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 1113
79a58d1f 1114 if (rc < 0) {
3c1bf7e4 1115 cifs_delete_mid(midQ);
7ee1af76
JA
1116 return rc;
1117 }
1118
1119 /* Wait for a reply - allow signals to interrupt. */
1120 rc = wait_event_interruptible(ses->server->response_q,
7c9421e1 1121 (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
1122 ((ses->server->tcpStatus != CifsGood) &&
1123 (ses->server->tcpStatus != CifsNew)));
1124
1125 /* Were we interrupted by a signal ? */
1126 if ((rc == -ERESTARTSYS) &&
7c9421e1 1127 (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
7ee1af76
JA
1128 ((ses->server->tcpStatus == CifsGood) ||
1129 (ses->server->tcpStatus == CifsNew))) {
1130
1131 if (in_buf->Command == SMB_COM_TRANSACTION2) {
1132 /* POSIX lock. We send a NT_CANCEL SMB to cause the
1133 blocking lock to return. */
fb2036d8 1134 rc = send_cancel(ses->server, &rqst, midQ);
7ee1af76 1135 if (rc) {
3c1bf7e4 1136 cifs_delete_mid(midQ);
7ee1af76
JA
1137 return rc;
1138 }
1139 } else {
1140 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
1141 to cause the blocking lock to return. */
1142
1143 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
1144
1145 /* If we get -ENOLCK back the lock may have
1146 already been removed. Don't exit in this case. */
1147 if (rc && rc != -ENOLCK) {
3c1bf7e4 1148 cifs_delete_mid(midQ);
7ee1af76
JA
1149 return rc;
1150 }
1151 }
1152
1be912dd
JL
1153 rc = wait_for_response(ses->server, midQ);
1154 if (rc) {
fb2036d8 1155 send_cancel(ses->server, &rqst, midQ);
1be912dd 1156 spin_lock(&GlobalMid_Lock);
7c9421e1 1157 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
1158 /* no longer considered to be "in-flight" */
1159 midQ->callback = DeleteMidQEntry;
1160 spin_unlock(&GlobalMid_Lock);
1161 return rc;
1162 }
1163 spin_unlock(&GlobalMid_Lock);
7ee1af76 1164 }
1be912dd
JL
1165
1166 /* We got the response - restart system call. */
1167 rstart = 1;
7ee1af76
JA
1168 }
1169
3c1105df 1170 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 1171 if (rc != 0)
7ee1af76 1172 return rc;
50c2f753 1173
17c8bfed 1174 /* rcvd frame is ok */
7c9421e1 1175 if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
698e96a8 1176 rc = -EIO;
f96637be 1177 cifs_dbg(VFS, "Bad MID state?\n");
698e96a8
VL
1178 goto out;
1179 }
1da177e4 1180
d4e4854f 1181 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1182 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1183 rc = cifs_check_receive(midQ, ses->server, 0);
17c8bfed 1184out:
3c1bf7e4 1185 cifs_delete_mid(midQ);
7ee1af76
JA
1186 if (rstart && rc == -EACCES)
1187 return -ERESTARTSYS;
1da177e4
LT
1188 return rc;
1189}