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