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