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