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