sunrpc: Include missing smp_lock.h
[linux-2.6-block.git] / fs / cifs / transport.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/transport.c
3 *
ad7a2926 4 * Copyright (C) International Business Machines Corp., 2002,2008
1da177e4 5 * Author(s): Steve French (sfrench@us.ibm.com)
14a441a2 6 * Jeremy Allison (jra@samba.org) 2006.
79a58d1f 7 *
1da177e4
LT
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
16 * the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software
79a58d1f 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1da177e4
LT
21 */
22
23#include <linux/fs.h>
24#include <linux/list.h>
25#include <linux/wait.h>
26#include <linux/net.h>
27#include <linux/delay.h>
28#include <asm/uaccess.h>
29#include <asm/processor.h>
30#include <linux/mempool.h>
31#include "cifspdu.h"
32#include "cifsglob.h"
33#include "cifsproto.h"
34#include "cifs_debug.h"
50c2f753 35
1da177e4 36extern mempool_t *cifs_mid_poolp;
e18b890b 37extern struct kmem_cache *cifs_oplock_cachep;
1da177e4
LT
38
39static struct mid_q_entry *
24b9b06b 40AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
1da177e4
LT
41{
42 struct mid_q_entry *temp;
43
24b9b06b 44 if (server == NULL) {
1da177e4
LT
45 cERROR(1, ("Null TCP session in AllocMidQEntry"));
46 return NULL;
47 }
50c2f753 48
232087cb 49 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
1da177e4
LT
50 if (temp == NULL)
51 return temp;
52 else {
26f57364 53 memset(temp, 0, sizeof(struct mid_q_entry));
1da177e4
LT
54 temp->mid = smb_buffer->Mid; /* always LE */
55 temp->pid = current->pid;
56 temp->command = smb_buffer->Command;
57 cFYI(1, ("For smb_command %d", temp->command));
1047abc1
SF
58 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
59 /* when mid allocated can be before when sent */
60 temp->when_alloc = jiffies;
1da177e4
LT
61 temp->tsk = current;
62 }
63
64 spin_lock(&GlobalMid_Lock);
24b9b06b 65 list_add_tail(&temp->qhead, &server->pending_mid_q);
1da177e4
LT
66 atomic_inc(&midCount);
67 temp->midState = MID_REQUEST_ALLOCATED;
68 spin_unlock(&GlobalMid_Lock);
69 return temp;
70}
71
72static void
73DeleteMidQEntry(struct mid_q_entry *midEntry)
74{
1047abc1
SF
75#ifdef CONFIG_CIFS_STATS2
76 unsigned long now;
77#endif
1da177e4
LT
78 spin_lock(&GlobalMid_Lock);
79 midEntry->midState = MID_FREE;
80 list_del(&midEntry->qhead);
81 atomic_dec(&midCount);
82 spin_unlock(&GlobalMid_Lock);
79a58d1f 83 if (midEntry->largeBuf)
b8643e1b
SF
84 cifs_buf_release(midEntry->resp_buf);
85 else
86 cifs_small_buf_release(midEntry->resp_buf);
1047abc1
SF
87#ifdef CONFIG_CIFS_STATS2
88 now = jiffies;
89 /* commands taking longer than one second are indications that
90 something is wrong, unless it is quite a slow link or server */
79a58d1f
SF
91 if ((now - midEntry->when_alloc) > HZ) {
92 if ((cifsFYI & CIFS_TIMER) &&
1047abc1
SF
93 (midEntry->command != SMB_COM_LOCKING_ANDX)) {
94 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
95 midEntry->command, midEntry->mid);
96 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
97 now - midEntry->when_alloc,
98 now - midEntry->when_sent,
99 now - midEntry->when_received);
100 }
101 }
102#endif
1da177e4
LT
103 mempool_free(midEntry, cifs_mid_poolp);
104}
105
d6e04ae6 106static int
0496e02d 107smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
1da177e4
LT
108{
109 int rc = 0;
110 int i = 0;
111 struct msghdr smb_msg;
3e84469d
SF
112 struct smb_hdr *smb_buffer = iov[0].iov_base;
113 unsigned int len = iov[0].iov_len;
114 unsigned int total_len;
115 int first_vec = 0;
7ee1af76 116 unsigned int smb_buf_length = smb_buffer->smb_buf_length;
edf1ae40 117 struct socket *ssocket = server->ssocket;
50c2f753 118
79a58d1f 119 if (ssocket == NULL)
1da177e4 120 return -ENOTSOCK; /* BB eventually add reconnect code here */
3e84469d 121
0496e02d 122 smb_msg.msg_name = (struct sockaddr *) &server->addr.sockAddr;
26f57364 123 smb_msg.msg_namelen = sizeof(struct sockaddr);
1da177e4
LT
124 smb_msg.msg_control = NULL;
125 smb_msg.msg_controllen = 0;
0496e02d 126 if (server->noblocksnd)
edf1ae40
SF
127 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
128 else
129 smb_msg.msg_flags = MSG_NOSIGNAL;
1da177e4
LT
130
131 /* smb header is converted in header_assemble. bcc and rest of SMB word
79a58d1f
SF
132 area, and byte area if necessary, is converted to littleendian in
133 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
1da177e4
LT
134 Flags2 is converted in SendReceive */
135
3e84469d
SF
136
137 total_len = 0;
138 for (i = 0; i < n_vec; i++)
139 total_len += iov[i].iov_len;
140
1da177e4 141 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
3e84469d 142 cFYI(1, ("Sending smb: total_len %d", total_len));
1da177e4
LT
143 dump_smb(smb_buffer, len);
144
17680356 145 i = 0;
3e84469d
SF
146 while (total_len) {
147 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
148 n_vec - first_vec, total_len);
1da177e4
LT
149 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
150 i++;
da505c38
SF
151 /* if blocking send we try 3 times, since each can block
152 for 5 seconds. For nonblocking we have to try more
153 but wait increasing amounts of time allowing time for
154 socket to clear. The overall time we wait in either
155 case to send on the socket is about 15 seconds.
156 Similarly we wait for 15 seconds for
157 a response from the server in SendReceive[2]
158 for the server to send a response back for
159 most types of requests (except SMB Write
160 past end of file which can be slow, and
161 blocking lock operations). NFS waits slightly longer
162 than CIFS, but this can make it take longer for
163 nonresponsive servers to be detected and 15 seconds
164 is more than enough time for modern networks to
165 send a packet. In most cases if we fail to send
166 after the retries we will kill the socket and
167 reconnect which may clear the network problem.
168 */
169 if ((i >= 14) || (!server->noblocksnd && (i > 2))) {
1da177e4 170 cERROR(1,
68058e75 171 ("sends on sock %p stuck for 15 seconds",
1da177e4
LT
172 ssocket));
173 rc = -EAGAIN;
174 break;
175 }
68058e75 176 msleep(1 << i);
1da177e4
LT
177 continue;
178 }
79a58d1f 179 if (rc < 0)
1da177e4 180 break;
3e84469d 181
61de800d
SF
182 if (rc == total_len) {
183 total_len = 0;
184 break;
185 } else if (rc > total_len) {
186 cERROR(1, ("sent %d requested %d", rc, total_len));
3e84469d
SF
187 break;
188 }
79a58d1f 189 if (rc == 0) {
3e84469d
SF
190 /* should never happen, letting socket clear before
191 retrying is our only obvious option here */
79a58d1f 192 cERROR(1, ("tcp sent no data"));
3e84469d
SF
193 msleep(500);
194 continue;
d6e04ae6 195 }
3e84469d 196 total_len -= rc;
68058e75 197 /* the line below resets i */
3e84469d
SF
198 for (i = first_vec; i < n_vec; i++) {
199 if (iov[i].iov_len) {
200 if (rc > iov[i].iov_len) {
201 rc -= iov[i].iov_len;
202 iov[i].iov_len = 0;
203 } else {
204 iov[i].iov_base += rc;
205 iov[i].iov_len -= rc;
206 first_vec = i;
207 break;
208 }
209 }
d6e04ae6 210 }
5e1253b5 211 i = 0; /* in case we get ENOSPC on the next send */
1da177e4
LT
212 }
213
edf1ae40
SF
214 if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
215 cFYI(1, ("partial send (%d remaining), terminating session",
216 total_len));
217 /* If we have only sent part of an SMB then the next SMB
218 could be taken as the remainder of this one. We need
219 to kill the socket so the server throws away the partial
220 SMB */
221 server->tcpStatus = CifsNeedReconnect;
222 }
223
1da177e4 224 if (rc < 0) {
79a58d1f 225 cERROR(1, ("Error %d sending data on socket to server", rc));
3e84469d 226 } else
1da177e4 227 rc = 0;
1da177e4 228
7ee1af76
JA
229 /* Don't want to modify the buffer as a
230 side effect of this call. */
231 smb_buffer->smb_buf_length = smb_buf_length;
232
1da177e4
LT
233 return rc;
234}
235
0496e02d
JL
236int
237smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
238 unsigned int smb_buf_length)
239{
240 struct kvec iov;
241
242 iov.iov_base = smb_buffer;
243 iov.iov_len = smb_buf_length + 4;
244
245 return smb_sendv(server, &iov, 1);
246}
247
7ee1af76 248static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
1da177e4 249{
133672ef 250 if (long_op == CIFS_ASYNC_OP) {
1da177e4
LT
251 /* oplock breaks must not be held up */
252 atomic_inc(&ses->server->inFlight);
27a97a61
VL
253 return 0;
254 }
255
256 spin_lock(&GlobalMid_Lock);
257 while (1) {
258 if (atomic_read(&ses->server->inFlight) >=
259 cifs_max_pending){
260 spin_unlock(&GlobalMid_Lock);
131afd0b 261#ifdef CONFIG_CIFS_STATS2
27a97a61 262 atomic_inc(&ses->server->num_waiters);
131afd0b 263#endif
27a97a61
VL
264 wait_event(ses->server->request_q,
265 atomic_read(&ses->server->inFlight)
266 < cifs_max_pending);
131afd0b 267#ifdef CONFIG_CIFS_STATS2
27a97a61 268 atomic_dec(&ses->server->num_waiters);
131afd0b 269#endif
27a97a61
VL
270 spin_lock(&GlobalMid_Lock);
271 } else {
272 if (ses->server->tcpStatus == CifsExiting) {
1da177e4 273 spin_unlock(&GlobalMid_Lock);
27a97a61 274 return -ENOENT;
1da177e4 275 }
27a97a61
VL
276
277 /* can not count locking commands against total
278 as they are allowed to block on server */
279
280 /* update # of requests on the wire to server */
281 if (long_op != CIFS_BLOCKING_OP)
282 atomic_inc(&ses->server->inFlight);
283 spin_unlock(&GlobalMid_Lock);
284 break;
1da177e4
LT
285 }
286 }
7ee1af76
JA
287 return 0;
288}
1da177e4 289
7ee1af76
JA
290static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
291 struct mid_q_entry **ppmidQ)
292{
1da177e4 293 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 294 return -ENOENT;
8fbbd365
VL
295 }
296
297 if (ses->server->tcpStatus == CifsNeedReconnect) {
79a58d1f 298 cFYI(1, ("tcp session dead - return to caller to retry"));
7ee1af76 299 return -EAGAIN;
8fbbd365
VL
300 }
301
302 if (ses->status != CifsGood) {
1da177e4 303 /* check if SMB session is bad because we are setting it up */
79a58d1f 304 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 305 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 306 return -EAGAIN;
ad7a2926 307 /* else ok - we are setting up session */
1da177e4 308 }
24b9b06b 309 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 310 if (*ppmidQ == NULL)
7ee1af76 311 return -ENOMEM;
7ee1af76
JA
312 return 0;
313}
314
79a58d1f 315static int wait_for_response(struct cifsSesInfo *ses,
7ee1af76
JA
316 struct mid_q_entry *midQ,
317 unsigned long timeout,
318 unsigned long time_to_wait)
319{
320 unsigned long curr_timeout;
321
322 for (;;) {
323 curr_timeout = timeout + jiffies;
85705524
JL
324 wait_event_timeout(ses->server->response_q,
325 midQ->midState != MID_REQUEST_SUBMITTED, timeout);
7ee1af76
JA
326
327 if (time_after(jiffies, curr_timeout) &&
328 (midQ->midState == MID_REQUEST_SUBMITTED) &&
329 ((ses->server->tcpStatus == CifsGood) ||
330 (ses->server->tcpStatus == CifsNew))) {
331
332 unsigned long lrt;
333
334 /* We timed out. Is the server still
335 sending replies ? */
336 spin_lock(&GlobalMid_Lock);
337 lrt = ses->server->lstrp;
338 spin_unlock(&GlobalMid_Lock);
339
340 /* Calculate time_to_wait past last receive time.
79a58d1f 341 Although we prefer not to time out if the
7ee1af76 342 server is still responding - we will time
79a58d1f 343 out if the server takes more than 15 (or 45
7ee1af76 344 or 180) seconds to respond to this request
79a58d1f 345 and has not responded to any request from
7ee1af76
JA
346 other threads on the client within 10 seconds */
347 lrt += time_to_wait;
348 if (time_after(jiffies, lrt)) {
349 /* No replies for time_to_wait. */
79a58d1f 350 cERROR(1, ("server not responding"));
7ee1af76
JA
351 return -1;
352 }
353 } else {
354 return 0;
355 }
356 }
357}
358
133672ef
SF
359
360/*
361 *
362 * Send an SMB Request. No response info (other than return code)
363 * needs to be parsed.
364 *
365 * flags indicate the type of request buffer and how long to wait
366 * and whether to log NT STATUS code (error) before mapping it to POSIX error
367 *
368 */
369int
370SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
371 struct smb_hdr *in_buf, int flags)
372{
373 int rc;
374 struct kvec iov[1];
375 int resp_buf_type;
376
377 iov[0].iov_base = (char *)in_buf;
378 iov[0].iov_len = in_buf->smb_buf_length + 4;
379 flags |= CIFS_NO_RESP;
380 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
90c81e0b
SF
381 cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc));
382
133672ef
SF
383 return rc;
384}
385
7ee1af76 386int
79a58d1f
SF
387SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
388 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
133672ef 389 const int flags)
7ee1af76
JA
390{
391 int rc = 0;
133672ef 392 int long_op;
7ee1af76
JA
393 unsigned int receive_len;
394 unsigned long timeout;
395 struct mid_q_entry *midQ;
396 struct smb_hdr *in_buf = iov[0].iov_base;
50c2f753 397
133672ef
SF
398 long_op = flags & CIFS_TIMEOUT_MASK;
399
7ee1af76
JA
400 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
401
402 if ((ses == NULL) || (ses->server == NULL)) {
403 cifs_small_buf_release(in_buf);
79a58d1f 404 cERROR(1, ("Null session"));
7ee1af76
JA
405 return -EIO;
406 }
407
79a58d1f 408 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76
JA
409 cifs_small_buf_release(in_buf);
410 return -ENOENT;
411 }
412
79a58d1f 413 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
414 to the same server. We may make this configurable later or
415 use ses->maxReq */
416
417 rc = wait_for_free_request(ses, long_op);
418 if (rc) {
419 cifs_small_buf_release(in_buf);
420 return rc;
421 }
422
79a58d1f 423 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
424 and avoid races inside tcp sendmsg code that could cause corruption
425 of smb data */
426
72ca545b 427 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
428
429 rc = allocate_mid(ses, in_buf, &midQ);
430 if (rc) {
72ca545b 431 mutex_unlock(&ses->server->srv_mutex);
4b8f930f 432 cifs_small_buf_release(in_buf);
7ee1af76 433 /* Update # of requests on wire to server */
79a58d1f 434 atomic_dec(&ses->server->inFlight);
7ee1af76
JA
435 wake_up(&ses->server->request_q);
436 return rc;
1da177e4 437 }
79a58d1f 438 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
829049cb
VL
439 if (rc) {
440 mutex_unlock(&ses->server->srv_mutex);
441 cifs_small_buf_release(in_buf);
442 goto out;
443 }
1da177e4
LT
444
445 midQ->midState = MID_REQUEST_SUBMITTED;
131afd0b
SF
446#ifdef CONFIG_CIFS_STATS2
447 atomic_inc(&ses->server->inSend);
448#endif
0496e02d 449 rc = smb_sendv(ses->server, iov, n_vec);
131afd0b
SF
450#ifdef CONFIG_CIFS_STATS2
451 atomic_dec(&ses->server->inSend);
1047abc1 452 midQ->when_sent = jiffies;
131afd0b 453#endif
7ee1af76 454
72ca545b 455 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
456 cifs_small_buf_release(in_buf);
457
79a58d1f 458 if (rc < 0)
7ee1af76 459 goto out;
4b8f930f 460
133672ef
SF
461 if (long_op == CIFS_STD_OP)
462 timeout = 15 * HZ;
463 else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
37c0eb46 464 timeout = 180 * HZ;
133672ef 465 else if (long_op == CIFS_LONG_OP)
79a58d1f 466 timeout = 45 * HZ; /* should be greater than
d6e04ae6 467 servers oplock break timeout (about 43 seconds) */
133672ef
SF
468 else if (long_op == CIFS_ASYNC_OP)
469 goto out;
470 else if (long_op == CIFS_BLOCKING_OP)
471 timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */
472 else {
473 cERROR(1, ("unknown timeout flag %d", long_op));
474 rc = -EIO;
475 goto out;
476 }
7ee1af76 477
79a58d1f 478 /* wait for 15 seconds or until woken up due to response arriving or
d6e04ae6
SF
479 due to last connection to this server being unmounted */
480 if (signal_pending(current)) {
481 /* if signal pending do not hold up user for full smb timeout
8a236264 482 but we still give response a chance to complete */
d6e04ae6 483 timeout = 2 * HZ;
79a58d1f 484 }
d6e04ae6
SF
485
486 /* No user interrupts in wait - wreaks havoc with performance */
7ee1af76 487 wait_for_response(ses, midQ, timeout, 10 * HZ);
d6e04ae6
SF
488
489 spin_lock(&GlobalMid_Lock);
8e4f2e8a
VL
490
491 if (midQ->resp_buf == NULL) {
79a58d1f 492 cERROR(1, ("No response to cmd %d mid %d",
37c0eb46 493 midQ->command, midQ->mid));
79a58d1f
SF
494 if (midQ->midState == MID_REQUEST_SUBMITTED) {
495 if (ses->server->tcpStatus == CifsExiting)
d6e04ae6
SF
496 rc = -EHOSTDOWN;
497 else {
498 ses->server->tcpStatus = CifsNeedReconnect;
499 midQ->midState = MID_RETRY_NEEDED;
500 }
501 }
502
503 if (rc != -EHOSTDOWN) {
79a58d1f 504 if (midQ->midState == MID_RETRY_NEEDED) {
d6e04ae6 505 rc = -EAGAIN;
79a58d1f 506 cFYI(1, ("marking request for retry"));
d6e04ae6
SF
507 } else {
508 rc = -EIO;
509 }
510 }
511 spin_unlock(&GlobalMid_Lock);
512 DeleteMidQEntry(midQ);
7ee1af76 513 /* Update # of requests on wire to server */
79a58d1f 514 atomic_dec(&ses->server->inFlight);
7ee1af76 515 wake_up(&ses->server->request_q);
d6e04ae6
SF
516 return rc;
517 }
50c2f753 518
8e4f2e8a
VL
519 spin_unlock(&GlobalMid_Lock);
520 receive_len = midQ->resp_buf->smb_buf_length;
521
d6e04ae6
SF
522 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
523 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
524 receive_len, xid));
525 rc = -EIO;
2b2bdfba
SF
526 goto out;
527 }
528
529 /* rcvd frame is ok */
530
531 if (midQ->resp_buf &&
532 (midQ->midState == MID_RESPONSE_RECEIVED)) {
533
534 iov[0].iov_base = (char *)midQ->resp_buf;
535 if (midQ->largeBuf)
536 *pRespBufType = CIFS_LARGE_BUFFER;
537 else
538 *pRespBufType = CIFS_SMALL_BUFFER;
539 iov[0].iov_len = receive_len + 4;
540
541 dump_smb(midQ->resp_buf, 80);
542 /* convert the length into a more usable form */
543 if ((receive_len > 24) &&
544 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
545 SECMODE_SIGN_ENABLED))) {
546 rc = cifs_verify_signature(midQ->resp_buf,
b609f06a 547 &ses->server->mac_signing_key,
d6e04ae6 548 midQ->sequence_number+1);
2b2bdfba
SF
549 if (rc) {
550 cERROR(1, ("Unexpected SMB signature"));
551 /* BB FIXME add code to kill session */
d6e04ae6 552 }
d6e04ae6 553 }
2b2bdfba
SF
554
555 /* BB special case reconnect tid and uid here? */
556 rc = map_smb_to_linux_error(midQ->resp_buf,
557 flags & CIFS_LOG_ERROR);
558
559 /* convert ByteCount if necessary */
560 if (receive_len >= sizeof(struct smb_hdr) - 4
561 /* do not count RFC1001 header */ +
562 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
563 BCC(midQ->resp_buf) =
564 le16_to_cpu(BCC_LE(midQ->resp_buf));
565 if ((flags & CIFS_NO_RESP) == 0)
566 midQ->resp_buf = NULL; /* mark it so buf will
567 not be freed by
568 DeleteMidQEntry */
569 } else {
570 rc = -EIO;
571 cFYI(1, ("Bad MID state?"));
d6e04ae6 572 }
1da177e4 573
7ee1af76 574out:
7ee1af76 575 DeleteMidQEntry(midQ);
79a58d1f 576 atomic_dec(&ses->server->inFlight);
7ee1af76 577 wake_up(&ses->server->request_q);
1da177e4 578
d6e04ae6
SF
579 return rc;
580}
1da177e4
LT
581
582int
583SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
584 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
585 int *pbytes_returned, const int long_op)
586{
587 int rc = 0;
588 unsigned int receive_len;
589 unsigned long timeout;
590 struct mid_q_entry *midQ;
591
592 if (ses == NULL) {
79a58d1f 593 cERROR(1, ("Null smb session"));
1da177e4
LT
594 return -EIO;
595 }
79a58d1f
SF
596 if (ses->server == NULL) {
597 cERROR(1, ("Null tcp session"));
1da177e4
LT
598 return -EIO;
599 }
600
79a58d1f 601 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
602 return -ENOENT;
603
79a58d1f 604 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
605 to the same server. We may make this configurable later or
606 use ses->maxReq */
1da177e4 607
6d9c6d54
VL
608 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
609 cERROR(1, ("Illegal length, greater than maximum frame, %d",
610 in_buf->smb_buf_length));
611 return -EIO;
612 }
613
7ee1af76
JA
614 rc = wait_for_free_request(ses, long_op);
615 if (rc)
616 return rc;
617
79a58d1f 618 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
619 and avoid races inside tcp sendmsg code that could cause corruption
620 of smb data */
621
72ca545b 622 mutex_lock(&ses->server->srv_mutex);
1da177e4 623
7ee1af76
JA
624 rc = allocate_mid(ses, in_buf, &midQ);
625 if (rc) {
72ca545b 626 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 627 /* Update # of requests on wire to server */
79a58d1f 628 atomic_dec(&ses->server->inFlight);
7ee1af76
JA
629 wake_up(&ses->server->request_q);
630 return rc;
1da177e4
LT
631 }
632
ad009ac9 633 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
634 if (rc) {
635 mutex_unlock(&ses->server->srv_mutex);
636 goto out;
637 }
1da177e4
LT
638
639 midQ->midState = MID_REQUEST_SUBMITTED;
131afd0b
SF
640#ifdef CONFIG_CIFS_STATS2
641 atomic_inc(&ses->server->inSend);
642#endif
0496e02d 643 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
131afd0b
SF
644#ifdef CONFIG_CIFS_STATS2
645 atomic_dec(&ses->server->inSend);
1047abc1 646 midQ->when_sent = jiffies;
131afd0b 647#endif
72ca545b 648 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 649
79a58d1f 650 if (rc < 0)
7ee1af76
JA
651 goto out;
652
133672ef
SF
653 if (long_op == CIFS_STD_OP)
654 timeout = 15 * HZ;
655 /* wait for 15 seconds or until woken up due to response arriving or
656 due to last connection to this server being unmounted */
657 else if (long_op == CIFS_ASYNC_OP)
7ee1af76 658 goto out;
133672ef 659 else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
37c0eb46 660 timeout = 180 * HZ;
133672ef 661 else if (long_op == CIFS_LONG_OP)
79a58d1f 662 timeout = 45 * HZ; /* should be greater than
1da177e4 663 servers oplock break timeout (about 43 seconds) */
133672ef
SF
664 else if (long_op == CIFS_BLOCKING_OP)
665 timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
666 else {
667 cERROR(1, ("unknown timeout flag %d", long_op));
668 rc = -EIO;
669 goto out;
670 }
671
1da177e4
LT
672 if (signal_pending(current)) {
673 /* if signal pending do not hold up user for full smb timeout
8a236264 674 but we still give response a chance to complete */
1da177e4 675 timeout = 2 * HZ;
79a58d1f 676 }
1da177e4
LT
677
678 /* No user interrupts in wait - wreaks havoc with performance */
7ee1af76 679 wait_for_response(ses, midQ, timeout, 10 * HZ);
1da177e4
LT
680
681 spin_lock(&GlobalMid_Lock);
8e4f2e8a 682 if (midQ->resp_buf == NULL) {
79a58d1f 683 cERROR(1, ("No response for cmd %d mid %d",
37c0eb46 684 midQ->command, midQ->mid));
79a58d1f
SF
685 if (midQ->midState == MID_REQUEST_SUBMITTED) {
686 if (ses->server->tcpStatus == CifsExiting)
1da177e4
LT
687 rc = -EHOSTDOWN;
688 else {
689 ses->server->tcpStatus = CifsNeedReconnect;
690 midQ->midState = MID_RETRY_NEEDED;
691 }
692 }
693
694 if (rc != -EHOSTDOWN) {
79a58d1f 695 if (midQ->midState == MID_RETRY_NEEDED) {
1da177e4 696 rc = -EAGAIN;
79a58d1f 697 cFYI(1, ("marking request for retry"));
1da177e4
LT
698 } else {
699 rc = -EIO;
700 }
701 }
702 spin_unlock(&GlobalMid_Lock);
703 DeleteMidQEntry(midQ);
7ee1af76 704 /* Update # of requests on wire to server */
79a58d1f 705 atomic_dec(&ses->server->inFlight);
7ee1af76 706 wake_up(&ses->server->request_q);
1da177e4
LT
707 return rc;
708 }
50c2f753 709
8e4f2e8a
VL
710 spin_unlock(&GlobalMid_Lock);
711 receive_len = midQ->resp_buf->smb_buf_length;
712
1da177e4 713 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
ad009ac9 714 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
1da177e4
LT
715 receive_len, xid));
716 rc = -EIO;
2b2bdfba
SF
717 goto out;
718 }
719
720 /* rcvd frame is ok */
721
722 if (midQ->resp_buf && out_buf
723 && (midQ->midState == MID_RESPONSE_RECEIVED)) {
724 out_buf->smb_buf_length = receive_len;
725 memcpy((char *)out_buf + 4,
726 (char *)midQ->resp_buf + 4,
727 receive_len);
728
729 dump_smb(out_buf, 92);
730 /* convert the length into a more usable form */
731 if ((receive_len > 24) &&
732 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
733 SECMODE_SIGN_ENABLED))) {
734 rc = cifs_verify_signature(out_buf,
b609f06a 735 &ses->server->mac_signing_key,
ad009ac9 736 midQ->sequence_number+1);
2b2bdfba
SF
737 if (rc) {
738 cERROR(1, ("Unexpected SMB signature"));
739 /* BB FIXME add code to kill session */
1da177e4 740 }
2b2bdfba 741 }
1da177e4 742
2b2bdfba 743 *pbytes_returned = out_buf->smb_buf_length;
1da177e4 744
2b2bdfba
SF
745 /* BB special case reconnect tid and uid here? */
746 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
1da177e4 747
2b2bdfba
SF
748 /* convert ByteCount if necessary */
749 if (receive_len >= sizeof(struct smb_hdr) - 4
750 /* do not count RFC1001 header */ +
751 (2 * out_buf->WordCount) + 2 /* bcc */ )
752 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
753 } else {
754 rc = -EIO;
755 cERROR(1, ("Bad MID state?"));
1da177e4 756 }
7ee1af76
JA
757
758out:
1da177e4 759 DeleteMidQEntry(midQ);
79a58d1f 760 atomic_dec(&ses->server->inFlight);
7ee1af76 761 wake_up(&ses->server->request_q);
1da177e4 762
7ee1af76
JA
763 return rc;
764}
1da177e4 765
7ee1af76
JA
766/* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
767
768static int
769send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
770 struct mid_q_entry *midQ)
771{
772 int rc = 0;
773 struct cifsSesInfo *ses = tcon->ses;
774 __u16 mid = in_buf->Mid;
775
776 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
777 in_buf->Mid = mid;
72ca545b 778 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
779 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
780 if (rc) {
72ca545b 781 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
782 return rc;
783 }
0496e02d 784 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
72ca545b 785 mutex_unlock(&ses->server->srv_mutex);
1da177e4 786 return rc;
7ee1af76
JA
787}
788
789/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
790 blocking lock to return. */
791
792static int
793send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
794 struct smb_hdr *in_buf,
795 struct smb_hdr *out_buf)
796{
797 int bytes_returned;
798 struct cifsSesInfo *ses = tcon->ses;
799 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
800
801 /* We just modify the current in_buf to change
802 the type of lock from LOCKING_ANDX_SHARED_LOCK
803 or LOCKING_ANDX_EXCLUSIVE_LOCK to
804 LOCKING_ANDX_CANCEL_LOCK. */
805
806 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
807 pSMB->Timeout = 0;
808 pSMB->hdr.Mid = GetNextMid(ses->server);
809
810 return SendReceive(xid, ses, in_buf, out_buf,
133672ef 811 &bytes_returned, CIFS_STD_OP);
7ee1af76
JA
812}
813
814int
815SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
816 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
817 int *pbytes_returned)
818{
819 int rc = 0;
820 int rstart = 0;
821 unsigned int receive_len;
822 struct mid_q_entry *midQ;
823 struct cifsSesInfo *ses;
824
825 if (tcon == NULL || tcon->ses == NULL) {
79a58d1f 826 cERROR(1, ("Null smb session"));
7ee1af76
JA
827 return -EIO;
828 }
829 ses = tcon->ses;
830
79a58d1f
SF
831 if (ses->server == NULL) {
832 cERROR(1, ("Null tcp session"));
7ee1af76
JA
833 return -EIO;
834 }
835
79a58d1f 836 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
837 return -ENOENT;
838
79a58d1f 839 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
840 to the same server. We may make this configurable later or
841 use ses->maxReq */
842
6d9c6d54
VL
843 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
844 cERROR(1, ("Illegal length, greater than maximum frame, %d",
845 in_buf->smb_buf_length));
846 return -EIO;
847 }
848
133672ef 849 rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
7ee1af76
JA
850 if (rc)
851 return rc;
852
79a58d1f 853 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
854 and avoid races inside tcp sendmsg code that could cause corruption
855 of smb data */
856
72ca545b 857 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
858
859 rc = allocate_mid(ses, in_buf, &midQ);
860 if (rc) {
72ca545b 861 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
862 return rc;
863 }
864
7ee1af76 865 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
866 if (rc) {
867 DeleteMidQEntry(midQ);
868 mutex_unlock(&ses->server->srv_mutex);
869 return rc;
870 }
1da177e4 871
7ee1af76
JA
872 midQ->midState = MID_REQUEST_SUBMITTED;
873#ifdef CONFIG_CIFS_STATS2
874 atomic_inc(&ses->server->inSend);
875#endif
0496e02d 876 rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);
7ee1af76
JA
877#ifdef CONFIG_CIFS_STATS2
878 atomic_dec(&ses->server->inSend);
879 midQ->when_sent = jiffies;
880#endif
72ca545b 881 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 882
79a58d1f 883 if (rc < 0) {
7ee1af76
JA
884 DeleteMidQEntry(midQ);
885 return rc;
886 }
887
888 /* Wait for a reply - allow signals to interrupt. */
889 rc = wait_event_interruptible(ses->server->response_q,
79a58d1f 890 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
891 ((ses->server->tcpStatus != CifsGood) &&
892 (ses->server->tcpStatus != CifsNew)));
893
894 /* Were we interrupted by a signal ? */
895 if ((rc == -ERESTARTSYS) &&
896 (midQ->midState == MID_REQUEST_SUBMITTED) &&
897 ((ses->server->tcpStatus == CifsGood) ||
898 (ses->server->tcpStatus == CifsNew))) {
899
900 if (in_buf->Command == SMB_COM_TRANSACTION2) {
901 /* POSIX lock. We send a NT_CANCEL SMB to cause the
902 blocking lock to return. */
903
904 rc = send_nt_cancel(tcon, in_buf, midQ);
905 if (rc) {
906 DeleteMidQEntry(midQ);
907 return rc;
908 }
909 } else {
910 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
911 to cause the blocking lock to return. */
912
913 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
914
915 /* If we get -ENOLCK back the lock may have
916 already been removed. Don't exit in this case. */
917 if (rc && rc != -ENOLCK) {
918 DeleteMidQEntry(midQ);
919 return rc;
920 }
921 }
922
923 /* Wait 5 seconds for the response. */
79a58d1f 924 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {
7ee1af76
JA
925 /* We got the response - restart system call. */
926 rstart = 1;
927 }
928 }
929
930 spin_lock(&GlobalMid_Lock);
931 if (midQ->resp_buf) {
932 spin_unlock(&GlobalMid_Lock);
933 receive_len = midQ->resp_buf->smb_buf_length;
934 } else {
79a58d1f 935 cERROR(1, ("No response for cmd %d mid %d",
7ee1af76 936 midQ->command, midQ->mid));
79a58d1f
SF
937 if (midQ->midState == MID_REQUEST_SUBMITTED) {
938 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
939 rc = -EHOSTDOWN;
940 else {
941 ses->server->tcpStatus = CifsNeedReconnect;
942 midQ->midState = MID_RETRY_NEEDED;
943 }
944 }
945
946 if (rc != -EHOSTDOWN) {
79a58d1f 947 if (midQ->midState == MID_RETRY_NEEDED) {
7ee1af76 948 rc = -EAGAIN;
79a58d1f 949 cFYI(1, ("marking request for retry"));
7ee1af76
JA
950 } else {
951 rc = -EIO;
952 }
953 }
954 spin_unlock(&GlobalMid_Lock);
955 DeleteMidQEntry(midQ);
956 return rc;
1da177e4 957 }
50c2f753 958
7ee1af76
JA
959 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
960 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
961 receive_len, xid));
962 rc = -EIO;
17c8bfed
VL
963 goto out;
964 }
7ee1af76 965
17c8bfed 966 /* rcvd frame is ok */
7ee1af76 967
ac6a3ef4 968 if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
698e96a8
VL
969 rc = -EIO;
970 cERROR(1, ("Bad MID state?"));
971 goto out;
972 }
1da177e4 973
698e96a8
VL
974 out_buf->smb_buf_length = receive_len;
975 memcpy((char *)out_buf + 4,
976 (char *)midQ->resp_buf + 4,
977 receive_len);
978
979 dump_smb(out_buf, 92);
980 /* convert the length into a more usable form */
981 if ((receive_len > 24) &&
982 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
983 SECMODE_SIGN_ENABLED))) {
984 rc = cifs_verify_signature(out_buf,
985 &ses->server->mac_signing_key,
986 midQ->sequence_number+1);
987 if (rc) {
988 cERROR(1, ("Unexpected SMB signature"));
989 /* BB FIXME add code to kill session */
7ee1af76 990 }
698e96a8 991 }
17c8bfed 992
698e96a8 993 *pbytes_returned = out_buf->smb_buf_length;
17c8bfed 994
698e96a8
VL
995 /* BB special case reconnect tid and uid here? */
996 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
17c8bfed 997
698e96a8
VL
998 /* convert ByteCount if necessary */
999 if (receive_len >= sizeof(struct smb_hdr) - 4
1000 /* do not count RFC1001 header */ +
1001 (2 * out_buf->WordCount) + 2 /* bcc */ )
1002 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
17c8bfed
VL
1003
1004out:
7ee1af76
JA
1005 DeleteMidQEntry(midQ);
1006 if (rstart && rc == -EACCES)
1007 return -ERESTARTSYS;
1da177e4
LT
1008 return rc;
1009}