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