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