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