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