Merge branch 'pm-cpufreq'
[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)) {
7c9421e1 102 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %llu",
1047abc1
SF
103 midEntry->command, midEntry->mid);
104 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
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
6f49f46b
JL
273static int
274smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst)
275{
276 int rc;
277 struct kvec *iov = rqst->rq_iov;
278 int n_vec = rqst->rq_nvec;
279 unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
97bc00b3
JL
280 unsigned int i;
281 size_t total_len = 0, sent;
b8eed283
JL
282 struct socket *ssocket = server->ssocket;
283 int val = 1;
6f49f46b 284
ea702b80
JL
285 if (ssocket == NULL)
286 return -ENOTSOCK;
287
f96637be 288 cifs_dbg(FYI, "Sending smb: smb_len=%u\n", smb_buf_length);
6f49f46b
JL
289 dump_smb(iov[0].iov_base, iov[0].iov_len);
290
b8eed283
JL
291 /* cork the socket */
292 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
293 (char *)&val, sizeof(val));
294
97bc00b3
JL
295 rc = smb_send_kvec(server, iov, n_vec, &sent);
296 if (rc < 0)
297 goto uncork;
298
299 total_len += sent;
300
301 /* now walk the page array and send each page in it */
302 for (i = 0; i < rqst->rq_npages; i++) {
303 struct kvec p_iov;
304
305 cifs_rqst_page_to_kvec(rqst, i, &p_iov);
306 rc = smb_send_kvec(server, &p_iov, 1, &sent);
307 kunmap(rqst->rq_pages[i]);
308 if (rc < 0)
309 break;
310
311 total_len += sent;
312 }
1da177e4 313
97bc00b3 314uncork:
b8eed283
JL
315 /* uncork it */
316 val = 0;
317 kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
318 (char *)&val, sizeof(val));
319
edf1ae40 320 if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
f96637be
JP
321 cifs_dbg(FYI, "partial send (wanted=%u sent=%zu): terminating session\n",
322 smb_buf_length + 4, total_len);
6f49f46b
JL
323 /*
324 * If we have only sent part of an SMB then the next SMB could
325 * be taken as the remainder of this one. We need to kill the
326 * socket so the server throws away the partial SMB
327 */
edf1ae40
SF
328 server->tcpStatus = CifsNeedReconnect;
329 }
330
d804d41d 331 if (rc < 0 && rc != -EINTR)
f96637be
JP
332 cifs_dbg(VFS, "Error %d sending data on socket to server\n",
333 rc);
d804d41d 334 else
1da177e4 335 rc = 0;
1da177e4
LT
336
337 return rc;
338}
339
6f49f46b
JL
340static int
341smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
342{
343 struct smb_rqst rqst = { .rq_iov = iov,
344 .rq_nvec = n_vec };
345
346 return smb_send_rqst(server, &rqst);
347}
348
0496e02d
JL
349int
350smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
351 unsigned int smb_buf_length)
352{
353 struct kvec iov;
354
355 iov.iov_base = smb_buffer;
356 iov.iov_len = smb_buf_length + 4;
357
358 return smb_sendv(server, &iov, 1);
359}
360
fc40f9cf 361static int
a891f0f8 362wait_for_free_credits(struct TCP_Server_Info *server, const int timeout,
bc205ed1 363 int *credits)
1da177e4 364{
5bc59498
PS
365 int rc;
366
fc40f9cf 367 spin_lock(&server->req_lock);
a891f0f8 368 if (timeout == CIFS_ASYNC_OP) {
1da177e4 369 /* oplock breaks must not be held up */
fc40f9cf 370 server->in_flight++;
bc205ed1 371 *credits -= 1;
fc40f9cf 372 spin_unlock(&server->req_lock);
27a97a61
VL
373 return 0;
374 }
375
27a97a61 376 while (1) {
bc205ed1 377 if (*credits <= 0) {
fc40f9cf 378 spin_unlock(&server->req_lock);
789e6661 379 cifs_num_waiters_inc(server);
5bc59498 380 rc = wait_event_killable(server->request_q,
bc205ed1 381 has_credits(server, credits));
789e6661 382 cifs_num_waiters_dec(server);
5bc59498
PS
383 if (rc)
384 return rc;
fc40f9cf 385 spin_lock(&server->req_lock);
27a97a61 386 } else {
c5797a94 387 if (server->tcpStatus == CifsExiting) {
fc40f9cf 388 spin_unlock(&server->req_lock);
27a97a61 389 return -ENOENT;
1da177e4 390 }
27a97a61 391
2d86dbc9
PS
392 /*
393 * Can not count locking commands against total
394 * as they are allowed to block on server.
395 */
27a97a61
VL
396
397 /* update # of requests on the wire to server */
a891f0f8 398 if (timeout != CIFS_BLOCKING_OP) {
bc205ed1 399 *credits -= 1;
fc40f9cf 400 server->in_flight++;
2d86dbc9 401 }
fc40f9cf 402 spin_unlock(&server->req_lock);
27a97a61 403 break;
1da177e4
LT
404 }
405 }
7ee1af76
JA
406 return 0;
407}
1da177e4 408
bc205ed1 409static int
a891f0f8
PS
410wait_for_free_request(struct TCP_Server_Info *server, const int timeout,
411 const int optype)
bc205ed1 412{
eb4c7df6
SP
413 int *val;
414
415 val = server->ops->get_credits_field(server, optype);
416 /* Since an echo is already inflight, no need to wait to send another */
417 if (*val <= 0 && optype == CIFS_ECHO_OP)
418 return -EAGAIN;
419 return wait_for_free_credits(server, timeout, val);
bc205ed1
PS
420}
421
96daf2b0 422static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
7ee1af76
JA
423 struct mid_q_entry **ppmidQ)
424{
1da177e4 425 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 426 return -ENOENT;
8fbbd365
VL
427 }
428
429 if (ses->server->tcpStatus == CifsNeedReconnect) {
f96637be 430 cifs_dbg(FYI, "tcp session dead - return to caller to retry\n");
7ee1af76 431 return -EAGAIN;
8fbbd365
VL
432 }
433
7f48558e 434 if (ses->status == CifsNew) {
79a58d1f 435 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 436 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 437 return -EAGAIN;
ad7a2926 438 /* else ok - we are setting up session */
1da177e4 439 }
7f48558e
SP
440
441 if (ses->status == CifsExiting) {
442 /* check if SMB session is bad because we are setting it up */
443 if (in_buf->Command != SMB_COM_LOGOFF_ANDX)
444 return -EAGAIN;
445 /* else ok - we are shutting down session */
446 }
447
24b9b06b 448 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 449 if (*ppmidQ == NULL)
7ee1af76 450 return -ENOMEM;
ddc8cf8f
JL
451 spin_lock(&GlobalMid_Lock);
452 list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
453 spin_unlock(&GlobalMid_Lock);
7ee1af76
JA
454 return 0;
455}
456
0ade640e
JL
457static int
458wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
7ee1af76 459{
0ade640e 460 int error;
7ee1af76 461
5853cc2a 462 error = wait_event_freezekillable_unsafe(server->response_q,
7c9421e1 463 midQ->mid_state != MID_REQUEST_SUBMITTED);
0ade640e
JL
464 if (error < 0)
465 return -ERESTARTSYS;
7ee1af76 466
0ade640e 467 return 0;
7ee1af76
JA
468}
469
fec344e3
JL
470struct mid_q_entry *
471cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst)
792af7b0
PS
472{
473 int rc;
fec344e3 474 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
475 struct mid_q_entry *mid;
476
477 /* enable signing if server requires it */
38d77c50 478 if (server->sign)
792af7b0
PS
479 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
480
481 mid = AllocMidQEntry(hdr, server);
482 if (mid == NULL)
fec344e3 483 return ERR_PTR(-ENOMEM);
792af7b0 484
fec344e3 485 rc = cifs_sign_rqst(rqst, server, &mid->sequence_number);
ffc61ccb
SP
486 if (rc) {
487 DeleteMidQEntry(mid);
fec344e3 488 return ERR_PTR(rc);
ffc61ccb
SP
489 }
490
fec344e3 491 return mid;
792af7b0 492}
133672ef 493
a6827c18
JL
494/*
495 * Send a SMB request and set the callback function in the mid to handle
496 * the result. Caller is responsible for dealing with timeouts.
497 */
498int
fec344e3
JL
499cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
500 mid_receive_t *receive, mid_callback_t *callback,
501 void *cbdata, const int flags)
a6827c18 502{
a891f0f8 503 int rc, timeout, optype;
a6827c18
JL
504 struct mid_q_entry *mid;
505
a891f0f8
PS
506 timeout = flags & CIFS_TIMEOUT_MASK;
507 optype = flags & CIFS_OP_MASK;
508
509 rc = wait_for_free_request(server, timeout, optype);
a6827c18
JL
510 if (rc)
511 return rc;
512
513 mutex_lock(&server->srv_mutex);
fec344e3
JL
514 mid = server->ops->setup_async_request(server, rqst);
515 if (IS_ERR(mid)) {
a6827c18 516 mutex_unlock(&server->srv_mutex);
a891f0f8 517 add_credits(server, 1, optype);
0193e072 518 wake_up(&server->request_q);
fec344e3 519 return PTR_ERR(mid);
a6827c18
JL
520 }
521
44d22d84 522 mid->receive = receive;
a6827c18
JL
523 mid->callback = callback;
524 mid->callback_data = cbdata;
7c9421e1 525 mid->mid_state = MID_REQUEST_SUBMITTED;
789e6661 526
ffc61ccb
SP
527 /* put it on the pending_mid_q */
528 spin_lock(&GlobalMid_Lock);
529 list_add_tail(&mid->qhead, &server->pending_mid_q);
530 spin_unlock(&GlobalMid_Lock);
531
532
789e6661 533 cifs_in_send_inc(server);
fec344e3 534 rc = smb_send_rqst(server, rqst);
789e6661
SF
535 cifs_in_send_dec(server);
536 cifs_save_when_sent(mid);
ad313cb8
JL
537
538 if (rc < 0)
539 server->sequence_number -= 2;
a6827c18 540 mutex_unlock(&server->srv_mutex);
789e6661 541
ffc61ccb
SP
542 if (rc == 0)
543 return 0;
a6827c18 544
3c1bf7e4 545 cifs_delete_mid(mid);
a891f0f8 546 add_credits(server, 1, optype);
a6827c18
JL
547 wake_up(&server->request_q);
548 return rc;
549}
550
133672ef
SF
551/*
552 *
553 * Send an SMB Request. No response info (other than return code)
554 * needs to be parsed.
555 *
556 * flags indicate the type of request buffer and how long to wait
557 * and whether to log NT STATUS code (error) before mapping it to POSIX error
558 *
559 */
560int
96daf2b0 561SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
792af7b0 562 char *in_buf, int flags)
133672ef
SF
563{
564 int rc;
565 struct kvec iov[1];
566 int resp_buf_type;
567
792af7b0
PS
568 iov[0].iov_base = in_buf;
569 iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
133672ef
SF
570 flags |= CIFS_NO_RESP;
571 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
f96637be 572 cifs_dbg(NOISY, "SendRcvNoRsp flags %d rc %d\n", flags, rc);
90c81e0b 573
133672ef
SF
574 return rc;
575}
576
053d5034 577static int
3c1105df 578cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
053d5034
JL
579{
580 int rc = 0;
581
f96637be
JP
582 cifs_dbg(FYI, "%s: cmd=%d mid=%llu state=%d\n",
583 __func__, le16_to_cpu(mid->command), mid->mid, mid->mid_state);
053d5034 584
74dd92a8 585 spin_lock(&GlobalMid_Lock);
7c9421e1 586 switch (mid->mid_state) {
74dd92a8 587 case MID_RESPONSE_RECEIVED:
053d5034
JL
588 spin_unlock(&GlobalMid_Lock);
589 return rc;
74dd92a8
JL
590 case MID_RETRY_NEEDED:
591 rc = -EAGAIN;
592 break;
71823baf
JL
593 case MID_RESPONSE_MALFORMED:
594 rc = -EIO;
595 break;
3c1105df
JL
596 case MID_SHUTDOWN:
597 rc = -EHOSTDOWN;
598 break;
74dd92a8 599 default:
3c1105df 600 list_del_init(&mid->qhead);
f96637be
JP
601 cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
602 __func__, mid->mid, mid->mid_state);
74dd92a8 603 rc = -EIO;
053d5034
JL
604 }
605 spin_unlock(&GlobalMid_Lock);
606
2b84a36c 607 DeleteMidQEntry(mid);
053d5034
JL
608 return rc;
609}
610
121b046a
JL
611static inline int
612send_cancel(struct TCP_Server_Info *server, void *buf, struct mid_q_entry *mid)
76dcc26f 613{
121b046a
JL
614 return server->ops->send_cancel ?
615 server->ops->send_cancel(server, buf, mid) : 0;
76dcc26f
JL
616}
617
2c8f981d
JL
618int
619cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
620 bool log_error)
621{
792af7b0 622 unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
826a95e4
JL
623
624 dump_smb(mid->resp_buf, min_t(u32, 92, len));
2c8f981d
JL
625
626 /* convert the length into a more usable form */
38d77c50 627 if (server->sign) {
826a95e4 628 struct kvec iov;
985e4ff0 629 int rc = 0;
bf5ea0e2
JL
630 struct smb_rqst rqst = { .rq_iov = &iov,
631 .rq_nvec = 1 };
826a95e4
JL
632
633 iov.iov_base = mid->resp_buf;
634 iov.iov_len = len;
2c8f981d 635 /* FIXME: add code to kill session */
bf5ea0e2 636 rc = cifs_verify_signature(&rqst, server,
0124cc45 637 mid->sequence_number);
985e4ff0 638 if (rc)
f96637be
JP
639 cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
640 rc);
2c8f981d
JL
641 }
642
643 /* BB special case reconnect tid and uid here? */
644 return map_smb_to_linux_error(mid->resp_buf, log_error);
645}
646
fec344e3
JL
647struct mid_q_entry *
648cifs_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst)
792af7b0
PS
649{
650 int rc;
fec344e3 651 struct smb_hdr *hdr = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
792af7b0
PS
652 struct mid_q_entry *mid;
653
654 rc = allocate_mid(ses, hdr, &mid);
655 if (rc)
fec344e3
JL
656 return ERR_PTR(rc);
657 rc = cifs_sign_rqst(rqst, ses->server, &mid->sequence_number);
658 if (rc) {
3c1bf7e4 659 cifs_delete_mid(mid);
fec344e3
JL
660 return ERR_PTR(rc);
661 }
662 return mid;
792af7b0
PS
663}
664
7ee1af76 665int
96daf2b0 666SendReceive2(const unsigned int xid, struct cifs_ses *ses,
a891f0f8 667 struct kvec *iov, int n_vec, int *resp_buf_type /* ret */,
133672ef 668 const int flags)
7ee1af76
JA
669{
670 int rc = 0;
a891f0f8 671 int timeout, optype;
7ee1af76 672 struct mid_q_entry *midQ;
792af7b0 673 char *buf = iov[0].iov_base;
a891f0f8 674 unsigned int credits = 1;
fec344e3
JL
675 struct smb_rqst rqst = { .rq_iov = iov,
676 .rq_nvec = n_vec };
50c2f753 677
a891f0f8
PS
678 timeout = flags & CIFS_TIMEOUT_MASK;
679 optype = flags & CIFS_OP_MASK;
133672ef 680
a891f0f8 681 *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */
7ee1af76
JA
682
683 if ((ses == NULL) || (ses->server == NULL)) {
792af7b0 684 cifs_small_buf_release(buf);
f96637be 685 cifs_dbg(VFS, "Null session\n");
7ee1af76
JA
686 return -EIO;
687 }
688
79a58d1f 689 if (ses->server->tcpStatus == CifsExiting) {
792af7b0 690 cifs_small_buf_release(buf);
7ee1af76
JA
691 return -ENOENT;
692 }
693
792af7b0
PS
694 /*
695 * Ensure that we do not send more than 50 overlapping requests
696 * to the same server. We may make this configurable later or
697 * use ses->maxReq.
698 */
7ee1af76 699
a891f0f8 700 rc = wait_for_free_request(ses->server, timeout, optype);
7ee1af76 701 if (rc) {
792af7b0 702 cifs_small_buf_release(buf);
7ee1af76
JA
703 return rc;
704 }
705
792af7b0
PS
706 /*
707 * Make sure that we sign in the same order that we send on this socket
708 * and avoid races inside tcp sendmsg code that could cause corruption
709 * of smb data.
710 */
7ee1af76 711
72ca545b 712 mutex_lock(&ses->server->srv_mutex);
7ee1af76 713
fec344e3
JL
714 midQ = ses->server->ops->setup_request(ses, &rqst);
715 if (IS_ERR(midQ)) {
72ca545b 716 mutex_unlock(&ses->server->srv_mutex);
792af7b0 717 cifs_small_buf_release(buf);
7ee1af76 718 /* Update # of requests on wire to server */
a891f0f8 719 add_credits(ses->server, 1, optype);
fec344e3 720 return PTR_ERR(midQ);
1da177e4 721 }
1da177e4 722
7c9421e1 723 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 724 cifs_in_send_inc(ses->server);
0496e02d 725 rc = smb_sendv(ses->server, iov, n_vec);
789e6661
SF
726 cifs_in_send_dec(ses->server);
727 cifs_save_when_sent(midQ);
7ee1af76 728
ad313cb8
JL
729 if (rc < 0)
730 ses->server->sequence_number -= 2;
72ca545b 731 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 732
2db7c581 733 if (rc < 0) {
792af7b0 734 cifs_small_buf_release(buf);
7ee1af76 735 goto out;
2db7c581 736 }
4b8f930f 737
a891f0f8 738 if (timeout == CIFS_ASYNC_OP) {
792af7b0 739 cifs_small_buf_release(buf);
133672ef 740 goto out;
2db7c581 741 }
d6e04ae6 742
0ade640e 743 rc = wait_for_response(ses->server, midQ);
1be912dd 744 if (rc != 0) {
121b046a 745 send_cancel(ses->server, buf, midQ);
1be912dd 746 spin_lock(&GlobalMid_Lock);
7c9421e1 747 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
748 midQ->callback = DeleteMidQEntry;
749 spin_unlock(&GlobalMid_Lock);
792af7b0 750 cifs_small_buf_release(buf);
a891f0f8 751 add_credits(ses->server, 1, optype);
1be912dd
JL
752 return rc;
753 }
754 spin_unlock(&GlobalMid_Lock);
755 }
d6e04ae6 756
792af7b0 757 cifs_small_buf_release(buf);
2db7c581 758
3c1105df 759 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 760 if (rc != 0) {
a891f0f8 761 add_credits(ses->server, 1, optype);
d6e04ae6
SF
762 return rc;
763 }
50c2f753 764
7c9421e1 765 if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
d6e04ae6 766 rc = -EIO;
f96637be 767 cifs_dbg(FYI, "Bad MID state?\n");
2b2bdfba
SF
768 goto out;
769 }
770
792af7b0
PS
771 buf = (char *)midQ->resp_buf;
772 iov[0].iov_base = buf;
773 iov[0].iov_len = get_rfc1002_length(buf) + 4;
7c9421e1 774 if (midQ->large_buf)
a891f0f8 775 *resp_buf_type = CIFS_LARGE_BUFFER;
2c8f981d 776 else
a891f0f8
PS
777 *resp_buf_type = CIFS_SMALL_BUFFER;
778
779 credits = ses->server->ops->get_credits(midQ);
2b2bdfba 780
082d0642
PS
781 rc = ses->server->ops->check_receive(midQ, ses->server,
782 flags & CIFS_LOG_ERROR);
1da177e4 783
3c1bf7e4 784 /* mark it so buf will not be freed by cifs_delete_mid */
2c8f981d
JL
785 if ((flags & CIFS_NO_RESP) == 0)
786 midQ->resp_buf = NULL;
7ee1af76 787out:
3c1bf7e4 788 cifs_delete_mid(midQ);
a891f0f8 789 add_credits(ses->server, credits, optype);
1da177e4 790
d6e04ae6
SF
791 return rc;
792}
1da177e4
LT
793
794int
96daf2b0 795SendReceive(const unsigned int xid, struct cifs_ses *ses,
1da177e4 796 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
a891f0f8 797 int *pbytes_returned, const int timeout)
1da177e4
LT
798{
799 int rc = 0;
1da177e4
LT
800 struct mid_q_entry *midQ;
801
802 if (ses == NULL) {
f96637be 803 cifs_dbg(VFS, "Null smb session\n");
1da177e4
LT
804 return -EIO;
805 }
79a58d1f 806 if (ses->server == NULL) {
f96637be 807 cifs_dbg(VFS, "Null tcp session\n");
1da177e4
LT
808 return -EIO;
809 }
810
79a58d1f 811 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
812 return -ENOENT;
813
79a58d1f 814 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
815 to the same server. We may make this configurable later or
816 use ses->maxReq */
1da177e4 817
be8e3b00
SF
818 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
819 MAX_CIFS_HDR_SIZE - 4) {
f96637be
JP
820 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
821 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
822 return -EIO;
823 }
824
a891f0f8 825 rc = wait_for_free_request(ses->server, timeout, 0);
7ee1af76
JA
826 if (rc)
827 return rc;
828
79a58d1f 829 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
830 and avoid races inside tcp sendmsg code that could cause corruption
831 of smb data */
832
72ca545b 833 mutex_lock(&ses->server->srv_mutex);
1da177e4 834
7ee1af76
JA
835 rc = allocate_mid(ses, in_buf, &midQ);
836 if (rc) {
72ca545b 837 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 838 /* Update # of requests on wire to server */
a891f0f8 839 add_credits(ses->server, 1, 0);
7ee1af76 840 return rc;
1da177e4
LT
841 }
842
ad009ac9 843 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
844 if (rc) {
845 mutex_unlock(&ses->server->srv_mutex);
846 goto out;
847 }
1da177e4 848
7c9421e1 849 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661
SF
850
851 cifs_in_send_inc(ses->server);
be8e3b00 852 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
853 cifs_in_send_dec(ses->server);
854 cifs_save_when_sent(midQ);
ad313cb8
JL
855
856 if (rc < 0)
857 ses->server->sequence_number -= 2;
858
72ca545b 859 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 860
79a58d1f 861 if (rc < 0)
7ee1af76
JA
862 goto out;
863
a891f0f8 864 if (timeout == CIFS_ASYNC_OP)
7ee1af76 865 goto out;
1da177e4 866
0ade640e 867 rc = wait_for_response(ses->server, midQ);
1be912dd 868 if (rc != 0) {
121b046a 869 send_cancel(ses->server, in_buf, midQ);
1be912dd 870 spin_lock(&GlobalMid_Lock);
7c9421e1 871 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
872 /* no longer considered to be "in-flight" */
873 midQ->callback = DeleteMidQEntry;
874 spin_unlock(&GlobalMid_Lock);
a891f0f8 875 add_credits(ses->server, 1, 0);
1be912dd
JL
876 return rc;
877 }
878 spin_unlock(&GlobalMid_Lock);
879 }
1da177e4 880
3c1105df 881 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 882 if (rc != 0) {
a891f0f8 883 add_credits(ses->server, 1, 0);
1da177e4
LT
884 return rc;
885 }
50c2f753 886
2c8f981d 887 if (!midQ->resp_buf || !out_buf ||
7c9421e1 888 midQ->mid_state != MID_RESPONSE_RECEIVED) {
2b2bdfba 889 rc = -EIO;
f96637be 890 cifs_dbg(VFS, "Bad MID state?\n");
2c8f981d 891 goto out;
1da177e4 892 }
7ee1af76 893
d4e4854f 894 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
895 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
896 rc = cifs_check_receive(midQ, ses->server, 0);
7ee1af76 897out:
3c1bf7e4 898 cifs_delete_mid(midQ);
a891f0f8 899 add_credits(ses->server, 1, 0);
1da177e4 900
7ee1af76
JA
901 return rc;
902}
1da177e4 903
7ee1af76
JA
904/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
905 blocking lock to return. */
906
907static int
96daf2b0 908send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
909 struct smb_hdr *in_buf,
910 struct smb_hdr *out_buf)
911{
912 int bytes_returned;
96daf2b0 913 struct cifs_ses *ses = tcon->ses;
7ee1af76
JA
914 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
915
916 /* We just modify the current in_buf to change
917 the type of lock from LOCKING_ANDX_SHARED_LOCK
918 or LOCKING_ANDX_EXCLUSIVE_LOCK to
919 LOCKING_ANDX_CANCEL_LOCK. */
920
921 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
922 pSMB->Timeout = 0;
88257360 923 pSMB->hdr.Mid = get_next_mid(ses->server);
7ee1af76
JA
924
925 return SendReceive(xid, ses, in_buf, out_buf,
7749981e 926 &bytes_returned, 0);
7ee1af76
JA
927}
928
929int
96daf2b0 930SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
7ee1af76
JA
931 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
932 int *pbytes_returned)
933{
934 int rc = 0;
935 int rstart = 0;
7ee1af76 936 struct mid_q_entry *midQ;
96daf2b0 937 struct cifs_ses *ses;
7ee1af76
JA
938
939 if (tcon == NULL || tcon->ses == NULL) {
f96637be 940 cifs_dbg(VFS, "Null smb session\n");
7ee1af76
JA
941 return -EIO;
942 }
943 ses = tcon->ses;
944
79a58d1f 945 if (ses->server == NULL) {
f96637be 946 cifs_dbg(VFS, "Null tcp session\n");
7ee1af76
JA
947 return -EIO;
948 }
949
79a58d1f 950 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
951 return -ENOENT;
952
79a58d1f 953 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
954 to the same server. We may make this configurable later or
955 use ses->maxReq */
956
be8e3b00
SF
957 if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
958 MAX_CIFS_HDR_SIZE - 4) {
f96637be
JP
959 cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
960 be32_to_cpu(in_buf->smb_buf_length));
6d9c6d54
VL
961 return -EIO;
962 }
963
a891f0f8 964 rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, 0);
7ee1af76
JA
965 if (rc)
966 return rc;
967
79a58d1f 968 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
969 and avoid races inside tcp sendmsg code that could cause corruption
970 of smb data */
971
72ca545b 972 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
973
974 rc = allocate_mid(ses, in_buf, &midQ);
975 if (rc) {
72ca545b 976 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
977 return rc;
978 }
979
7ee1af76 980 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb 981 if (rc) {
3c1bf7e4 982 cifs_delete_mid(midQ);
829049cb
VL
983 mutex_unlock(&ses->server->srv_mutex);
984 return rc;
985 }
1da177e4 986
7c9421e1 987 midQ->mid_state = MID_REQUEST_SUBMITTED;
789e6661 988 cifs_in_send_inc(ses->server);
be8e3b00 989 rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
789e6661
SF
990 cifs_in_send_dec(ses->server);
991 cifs_save_when_sent(midQ);
ad313cb8
JL
992
993 if (rc < 0)
994 ses->server->sequence_number -= 2;
995
72ca545b 996 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 997
79a58d1f 998 if (rc < 0) {
3c1bf7e4 999 cifs_delete_mid(midQ);
7ee1af76
JA
1000 return rc;
1001 }
1002
1003 /* Wait for a reply - allow signals to interrupt. */
1004 rc = wait_event_interruptible(ses->server->response_q,
7c9421e1 1005 (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
1006 ((ses->server->tcpStatus != CifsGood) &&
1007 (ses->server->tcpStatus != CifsNew)));
1008
1009 /* Were we interrupted by a signal ? */
1010 if ((rc == -ERESTARTSYS) &&
7c9421e1 1011 (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
7ee1af76
JA
1012 ((ses->server->tcpStatus == CifsGood) ||
1013 (ses->server->tcpStatus == CifsNew))) {
1014
1015 if (in_buf->Command == SMB_COM_TRANSACTION2) {
1016 /* POSIX lock. We send a NT_CANCEL SMB to cause the
1017 blocking lock to return. */
121b046a 1018 rc = send_cancel(ses->server, in_buf, midQ);
7ee1af76 1019 if (rc) {
3c1bf7e4 1020 cifs_delete_mid(midQ);
7ee1af76
JA
1021 return rc;
1022 }
1023 } else {
1024 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
1025 to cause the blocking lock to return. */
1026
1027 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
1028
1029 /* If we get -ENOLCK back the lock may have
1030 already been removed. Don't exit in this case. */
1031 if (rc && rc != -ENOLCK) {
3c1bf7e4 1032 cifs_delete_mid(midQ);
7ee1af76
JA
1033 return rc;
1034 }
1035 }
1036
1be912dd
JL
1037 rc = wait_for_response(ses->server, midQ);
1038 if (rc) {
121b046a 1039 send_cancel(ses->server, in_buf, midQ);
1be912dd 1040 spin_lock(&GlobalMid_Lock);
7c9421e1 1041 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
1be912dd
JL
1042 /* no longer considered to be "in-flight" */
1043 midQ->callback = DeleteMidQEntry;
1044 spin_unlock(&GlobalMid_Lock);
1045 return rc;
1046 }
1047 spin_unlock(&GlobalMid_Lock);
7ee1af76 1048 }
1be912dd
JL
1049
1050 /* We got the response - restart system call. */
1051 rstart = 1;
7ee1af76
JA
1052 }
1053
3c1105df 1054 rc = cifs_sync_mid_result(midQ, ses->server);
053d5034 1055 if (rc != 0)
7ee1af76 1056 return rc;
50c2f753 1057
17c8bfed 1058 /* rcvd frame is ok */
7c9421e1 1059 if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
698e96a8 1060 rc = -EIO;
f96637be 1061 cifs_dbg(VFS, "Bad MID state?\n");
698e96a8
VL
1062 goto out;
1063 }
1da177e4 1064
d4e4854f 1065 *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
2c8f981d
JL
1066 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
1067 rc = cifs_check_receive(midQ, ses->server, 0);
17c8bfed 1068out:
3c1bf7e4 1069 cifs_delete_mid(midQ);
7ee1af76
JA
1070 if (rstart && rc == -EACCES)
1071 return -ERESTARTSYS;
1da177e4
LT
1072 return rc;
1073}
This page took 0.545472 seconds and 5 git commands to generate.