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