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