]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/transport.c
Linux 2.6.29-rc3
[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 *
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);
27a97a61
VL
347 return 0;
348 }
349
350 spin_lock(&GlobalMid_Lock);
351 while (1) {
352 if (atomic_read(&ses->server->inFlight) >=
353 cifs_max_pending){
354 spin_unlock(&GlobalMid_Lock);
131afd0b 355#ifdef CONFIG_CIFS_STATS2
27a97a61 356 atomic_inc(&ses->server->num_waiters);
131afd0b 357#endif
27a97a61
VL
358 wait_event(ses->server->request_q,
359 atomic_read(&ses->server->inFlight)
360 < cifs_max_pending);
131afd0b 361#ifdef CONFIG_CIFS_STATS2
27a97a61 362 atomic_dec(&ses->server->num_waiters);
131afd0b 363#endif
27a97a61
VL
364 spin_lock(&GlobalMid_Lock);
365 } else {
366 if (ses->server->tcpStatus == CifsExiting) {
1da177e4 367 spin_unlock(&GlobalMid_Lock);
27a97a61 368 return -ENOENT;
1da177e4 369 }
27a97a61
VL
370
371 /* can not count locking commands against total
372 as they are allowed to block on server */
373
374 /* update # of requests on the wire to server */
375 if (long_op != CIFS_BLOCKING_OP)
376 atomic_inc(&ses->server->inFlight);
377 spin_unlock(&GlobalMid_Lock);
378 break;
1da177e4
LT
379 }
380 }
7ee1af76
JA
381 return 0;
382}
1da177e4 383
7ee1af76
JA
384static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
385 struct mid_q_entry **ppmidQ)
386{
1da177e4 387 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76 388 return -ENOENT;
8fbbd365
VL
389 }
390
391 if (ses->server->tcpStatus == CifsNeedReconnect) {
79a58d1f 392 cFYI(1, ("tcp session dead - return to caller to retry"));
7ee1af76 393 return -EAGAIN;
8fbbd365
VL
394 }
395
396 if (ses->status != CifsGood) {
1da177e4 397 /* check if SMB session is bad because we are setting it up */
79a58d1f 398 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
ad7a2926 399 (in_buf->Command != SMB_COM_NEGOTIATE))
7ee1af76 400 return -EAGAIN;
ad7a2926 401 /* else ok - we are setting up session */
1da177e4 402 }
24b9b06b 403 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
26f57364 404 if (*ppmidQ == NULL)
7ee1af76 405 return -ENOMEM;
7ee1af76
JA
406 return 0;
407}
408
79a58d1f 409static int wait_for_response(struct cifsSesInfo *ses,
7ee1af76
JA
410 struct mid_q_entry *midQ,
411 unsigned long timeout,
412 unsigned long time_to_wait)
413{
414 unsigned long curr_timeout;
415
416 for (;;) {
417 curr_timeout = timeout + jiffies;
85705524
JL
418 wait_event_timeout(ses->server->response_q,
419 midQ->midState != MID_REQUEST_SUBMITTED, timeout);
7ee1af76
JA
420
421 if (time_after(jiffies, curr_timeout) &&
422 (midQ->midState == MID_REQUEST_SUBMITTED) &&
423 ((ses->server->tcpStatus == CifsGood) ||
424 (ses->server->tcpStatus == CifsNew))) {
425
426 unsigned long lrt;
427
428 /* We timed out. Is the server still
429 sending replies ? */
430 spin_lock(&GlobalMid_Lock);
431 lrt = ses->server->lstrp;
432 spin_unlock(&GlobalMid_Lock);
433
434 /* Calculate time_to_wait past last receive time.
79a58d1f 435 Although we prefer not to time out if the
7ee1af76 436 server is still responding - we will time
79a58d1f 437 out if the server takes more than 15 (or 45
7ee1af76 438 or 180) seconds to respond to this request
79a58d1f 439 and has not responded to any request from
7ee1af76
JA
440 other threads on the client within 10 seconds */
441 lrt += time_to_wait;
442 if (time_after(jiffies, lrt)) {
443 /* No replies for time_to_wait. */
79a58d1f 444 cERROR(1, ("server not responding"));
7ee1af76
JA
445 return -1;
446 }
447 } else {
448 return 0;
449 }
450 }
451}
452
133672ef
SF
453
454/*
455 *
456 * Send an SMB Request. No response info (other than return code)
457 * needs to be parsed.
458 *
459 * flags indicate the type of request buffer and how long to wait
460 * and whether to log NT STATUS code (error) before mapping it to POSIX error
461 *
462 */
463int
464SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
465 struct smb_hdr *in_buf, int flags)
466{
467 int rc;
468 struct kvec iov[1];
469 int resp_buf_type;
470
471 iov[0].iov_base = (char *)in_buf;
472 iov[0].iov_len = in_buf->smb_buf_length + 4;
473 flags |= CIFS_NO_RESP;
474 rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
90c81e0b
SF
475 cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc));
476
133672ef
SF
477 return rc;
478}
479
7ee1af76 480int
79a58d1f
SF
481SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
482 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
133672ef 483 const int flags)
7ee1af76
JA
484{
485 int rc = 0;
133672ef 486 int long_op;
7ee1af76
JA
487 unsigned int receive_len;
488 unsigned long timeout;
489 struct mid_q_entry *midQ;
490 struct smb_hdr *in_buf = iov[0].iov_base;
50c2f753 491
133672ef
SF
492 long_op = flags & CIFS_TIMEOUT_MASK;
493
7ee1af76
JA
494 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
495
496 if ((ses == NULL) || (ses->server == NULL)) {
497 cifs_small_buf_release(in_buf);
79a58d1f 498 cERROR(1, ("Null session"));
7ee1af76
JA
499 return -EIO;
500 }
501
79a58d1f 502 if (ses->server->tcpStatus == CifsExiting) {
7ee1af76
JA
503 cifs_small_buf_release(in_buf);
504 return -ENOENT;
505 }
506
79a58d1f 507 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
508 to the same server. We may make this configurable later or
509 use ses->maxReq */
510
511 rc = wait_for_free_request(ses, long_op);
512 if (rc) {
513 cifs_small_buf_release(in_buf);
514 return rc;
515 }
516
79a58d1f 517 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
518 and avoid races inside tcp sendmsg code that could cause corruption
519 of smb data */
520
72ca545b 521 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
522
523 rc = allocate_mid(ses, in_buf, &midQ);
524 if (rc) {
72ca545b 525 mutex_unlock(&ses->server->srv_mutex);
4b8f930f 526 cifs_small_buf_release(in_buf);
7ee1af76 527 /* Update # of requests on wire to server */
79a58d1f 528 atomic_dec(&ses->server->inFlight);
7ee1af76
JA
529 wake_up(&ses->server->request_q);
530 return rc;
1da177e4 531 }
79a58d1f 532 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
829049cb
VL
533 if (rc) {
534 mutex_unlock(&ses->server->srv_mutex);
535 cifs_small_buf_release(in_buf);
536 goto out;
537 }
1da177e4
LT
538
539 midQ->midState = MID_REQUEST_SUBMITTED;
131afd0b
SF
540#ifdef CONFIG_CIFS_STATS2
541 atomic_inc(&ses->server->inSend);
542#endif
edf1ae40
SF
543 rc = smb_send2(ses->server, iov, n_vec,
544 (struct sockaddr *) &(ses->server->addr.sockAddr),
545 ses->server->noblocksnd);
131afd0b
SF
546#ifdef CONFIG_CIFS_STATS2
547 atomic_dec(&ses->server->inSend);
1047abc1 548 midQ->when_sent = jiffies;
131afd0b 549#endif
7ee1af76 550
72ca545b 551 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
552 cifs_small_buf_release(in_buf);
553
79a58d1f 554 if (rc < 0)
7ee1af76 555 goto out;
4b8f930f 556
133672ef
SF
557 if (long_op == CIFS_STD_OP)
558 timeout = 15 * HZ;
559 else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */
37c0eb46 560 timeout = 180 * HZ;
133672ef 561 else if (long_op == CIFS_LONG_OP)
79a58d1f 562 timeout = 45 * HZ; /* should be greater than
d6e04ae6 563 servers oplock break timeout (about 43 seconds) */
133672ef
SF
564 else if (long_op == CIFS_ASYNC_OP)
565 goto out;
566 else if (long_op == CIFS_BLOCKING_OP)
567 timeout = 0x7FFFFFFF; /* large, but not so large as to wrap */
568 else {
569 cERROR(1, ("unknown timeout flag %d", long_op));
570 rc = -EIO;
571 goto out;
572 }
7ee1af76 573
79a58d1f 574 /* wait for 15 seconds or until woken up due to response arriving or
d6e04ae6
SF
575 due to last connection to this server being unmounted */
576 if (signal_pending(current)) {
577 /* if signal pending do not hold up user for full smb timeout
8a236264 578 but we still give response a chance to complete */
d6e04ae6 579 timeout = 2 * HZ;
79a58d1f 580 }
d6e04ae6
SF
581
582 /* No user interrupts in wait - wreaks havoc with performance */
7ee1af76 583 wait_for_response(ses, midQ, timeout, 10 * HZ);
d6e04ae6
SF
584
585 spin_lock(&GlobalMid_Lock);
8e4f2e8a
VL
586
587 if (midQ->resp_buf == NULL) {
79a58d1f 588 cERROR(1, ("No response to cmd %d mid %d",
37c0eb46 589 midQ->command, midQ->mid));
79a58d1f
SF
590 if (midQ->midState == MID_REQUEST_SUBMITTED) {
591 if (ses->server->tcpStatus == CifsExiting)
d6e04ae6
SF
592 rc = -EHOSTDOWN;
593 else {
594 ses->server->tcpStatus = CifsNeedReconnect;
595 midQ->midState = MID_RETRY_NEEDED;
596 }
597 }
598
599 if (rc != -EHOSTDOWN) {
79a58d1f 600 if (midQ->midState == MID_RETRY_NEEDED) {
d6e04ae6 601 rc = -EAGAIN;
79a58d1f 602 cFYI(1, ("marking request for retry"));
d6e04ae6
SF
603 } else {
604 rc = -EIO;
605 }
606 }
607 spin_unlock(&GlobalMid_Lock);
608 DeleteMidQEntry(midQ);
7ee1af76 609 /* Update # of requests on wire to server */
79a58d1f 610 atomic_dec(&ses->server->inFlight);
7ee1af76 611 wake_up(&ses->server->request_q);
d6e04ae6
SF
612 return rc;
613 }
50c2f753 614
8e4f2e8a
VL
615 spin_unlock(&GlobalMid_Lock);
616 receive_len = midQ->resp_buf->smb_buf_length;
617
d6e04ae6
SF
618 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
619 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
620 receive_len, xid));
621 rc = -EIO;
2b2bdfba
SF
622 goto out;
623 }
624
625 /* rcvd frame is ok */
626
627 if (midQ->resp_buf &&
628 (midQ->midState == MID_RESPONSE_RECEIVED)) {
629
630 iov[0].iov_base = (char *)midQ->resp_buf;
631 if (midQ->largeBuf)
632 *pRespBufType = CIFS_LARGE_BUFFER;
633 else
634 *pRespBufType = CIFS_SMALL_BUFFER;
635 iov[0].iov_len = receive_len + 4;
636
637 dump_smb(midQ->resp_buf, 80);
638 /* convert the length into a more usable form */
639 if ((receive_len > 24) &&
640 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
641 SECMODE_SIGN_ENABLED))) {
642 rc = cifs_verify_signature(midQ->resp_buf,
b609f06a 643 &ses->server->mac_signing_key,
d6e04ae6 644 midQ->sequence_number+1);
2b2bdfba
SF
645 if (rc) {
646 cERROR(1, ("Unexpected SMB signature"));
647 /* BB FIXME add code to kill session */
d6e04ae6 648 }
d6e04ae6 649 }
2b2bdfba
SF
650
651 /* BB special case reconnect tid and uid here? */
652 rc = map_smb_to_linux_error(midQ->resp_buf,
653 flags & CIFS_LOG_ERROR);
654
655 /* convert ByteCount if necessary */
656 if (receive_len >= sizeof(struct smb_hdr) - 4
657 /* do not count RFC1001 header */ +
658 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
659 BCC(midQ->resp_buf) =
660 le16_to_cpu(BCC_LE(midQ->resp_buf));
661 if ((flags & CIFS_NO_RESP) == 0)
662 midQ->resp_buf = NULL; /* mark it so buf will
663 not be freed by
664 DeleteMidQEntry */
665 } else {
666 rc = -EIO;
667 cFYI(1, ("Bad MID state?"));
d6e04ae6 668 }
1da177e4 669
7ee1af76 670out:
7ee1af76 671 DeleteMidQEntry(midQ);
79a58d1f 672 atomic_dec(&ses->server->inFlight);
7ee1af76 673 wake_up(&ses->server->request_q);
1da177e4 674
d6e04ae6
SF
675 return rc;
676}
1da177e4
LT
677
678int
679SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
680 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
681 int *pbytes_returned, const int long_op)
682{
683 int rc = 0;
684 unsigned int receive_len;
685 unsigned long timeout;
686 struct mid_q_entry *midQ;
687
688 if (ses == NULL) {
79a58d1f 689 cERROR(1, ("Null smb session"));
1da177e4
LT
690 return -EIO;
691 }
79a58d1f
SF
692 if (ses->server == NULL) {
693 cERROR(1, ("Null tcp session"));
1da177e4
LT
694 return -EIO;
695 }
696
79a58d1f 697 if (ses->server->tcpStatus == CifsExiting)
31ca3bc3
SF
698 return -ENOENT;
699
79a58d1f 700 /* Ensure that we do not send more than 50 overlapping requests
1da177e4
LT
701 to the same server. We may make this configurable later or
702 use ses->maxReq */
1da177e4 703
6d9c6d54
VL
704 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
705 cERROR(1, ("Illegal length, greater than maximum frame, %d",
706 in_buf->smb_buf_length));
707 return -EIO;
708 }
709
7ee1af76
JA
710 rc = wait_for_free_request(ses, long_op);
711 if (rc)
712 return rc;
713
79a58d1f 714 /* make sure that we sign in the same order that we send on this socket
1da177e4
LT
715 and avoid races inside tcp sendmsg code that could cause corruption
716 of smb data */
717
72ca545b 718 mutex_lock(&ses->server->srv_mutex);
1da177e4 719
7ee1af76
JA
720 rc = allocate_mid(ses, in_buf, &midQ);
721 if (rc) {
72ca545b 722 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 723 /* Update # of requests on wire to server */
79a58d1f 724 atomic_dec(&ses->server->inFlight);
7ee1af76
JA
725 wake_up(&ses->server->request_q);
726 return rc;
1da177e4
LT
727 }
728
ad009ac9 729 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
730 if (rc) {
731 mutex_unlock(&ses->server->srv_mutex);
732 goto out;
733 }
1da177e4
LT
734
735 midQ->midState = MID_REQUEST_SUBMITTED;
131afd0b
SF
736#ifdef CONFIG_CIFS_STATS2
737 atomic_inc(&ses->server->inSend);
738#endif
1da177e4 739 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
edf1ae40
SF
740 (struct sockaddr *) &(ses->server->addr.sockAddr),
741 ses->server->noblocksnd);
131afd0b
SF
742#ifdef CONFIG_CIFS_STATS2
743 atomic_dec(&ses->server->inSend);
1047abc1 744 midQ->when_sent = jiffies;
131afd0b 745#endif
72ca545b 746 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 747
79a58d1f 748 if (rc < 0)
7ee1af76
JA
749 goto out;
750
133672ef
SF
751 if (long_op == CIFS_STD_OP)
752 timeout = 15 * HZ;
753 /* wait for 15 seconds or until woken up due to response arriving or
754 due to last connection to this server being unmounted */
755 else if (long_op == CIFS_ASYNC_OP)
7ee1af76 756 goto out;
133672ef 757 else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
37c0eb46 758 timeout = 180 * HZ;
133672ef 759 else if (long_op == CIFS_LONG_OP)
79a58d1f 760 timeout = 45 * HZ; /* should be greater than
1da177e4 761 servers oplock break timeout (about 43 seconds) */
133672ef
SF
762 else if (long_op == CIFS_BLOCKING_OP)
763 timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
764 else {
765 cERROR(1, ("unknown timeout flag %d", long_op));
766 rc = -EIO;
767 goto out;
768 }
769
1da177e4
LT
770 if (signal_pending(current)) {
771 /* if signal pending do not hold up user for full smb timeout
8a236264 772 but we still give response a chance to complete */
1da177e4 773 timeout = 2 * HZ;
79a58d1f 774 }
1da177e4
LT
775
776 /* No user interrupts in wait - wreaks havoc with performance */
7ee1af76 777 wait_for_response(ses, midQ, timeout, 10 * HZ);
1da177e4
LT
778
779 spin_lock(&GlobalMid_Lock);
8e4f2e8a 780 if (midQ->resp_buf == NULL) {
79a58d1f 781 cERROR(1, ("No response for cmd %d mid %d",
37c0eb46 782 midQ->command, midQ->mid));
79a58d1f
SF
783 if (midQ->midState == MID_REQUEST_SUBMITTED) {
784 if (ses->server->tcpStatus == CifsExiting)
1da177e4
LT
785 rc = -EHOSTDOWN;
786 else {
787 ses->server->tcpStatus = CifsNeedReconnect;
788 midQ->midState = MID_RETRY_NEEDED;
789 }
790 }
791
792 if (rc != -EHOSTDOWN) {
79a58d1f 793 if (midQ->midState == MID_RETRY_NEEDED) {
1da177e4 794 rc = -EAGAIN;
79a58d1f 795 cFYI(1, ("marking request for retry"));
1da177e4
LT
796 } else {
797 rc = -EIO;
798 }
799 }
800 spin_unlock(&GlobalMid_Lock);
801 DeleteMidQEntry(midQ);
7ee1af76 802 /* Update # of requests on wire to server */
79a58d1f 803 atomic_dec(&ses->server->inFlight);
7ee1af76 804 wake_up(&ses->server->request_q);
1da177e4
LT
805 return rc;
806 }
50c2f753 807
8e4f2e8a
VL
808 spin_unlock(&GlobalMid_Lock);
809 receive_len = midQ->resp_buf->smb_buf_length;
810
1da177e4 811 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
ad009ac9 812 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
1da177e4
LT
813 receive_len, xid));
814 rc = -EIO;
2b2bdfba
SF
815 goto out;
816 }
817
818 /* rcvd frame is ok */
819
820 if (midQ->resp_buf && out_buf
821 && (midQ->midState == MID_RESPONSE_RECEIVED)) {
822 out_buf->smb_buf_length = receive_len;
823 memcpy((char *)out_buf + 4,
824 (char *)midQ->resp_buf + 4,
825 receive_len);
826
827 dump_smb(out_buf, 92);
828 /* convert the length into a more usable form */
829 if ((receive_len > 24) &&
830 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
831 SECMODE_SIGN_ENABLED))) {
832 rc = cifs_verify_signature(out_buf,
b609f06a 833 &ses->server->mac_signing_key,
ad009ac9 834 midQ->sequence_number+1);
2b2bdfba
SF
835 if (rc) {
836 cERROR(1, ("Unexpected SMB signature"));
837 /* BB FIXME add code to kill session */
1da177e4 838 }
2b2bdfba 839 }
1da177e4 840
2b2bdfba 841 *pbytes_returned = out_buf->smb_buf_length;
1da177e4 842
2b2bdfba
SF
843 /* BB special case reconnect tid and uid here? */
844 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
1da177e4 845
2b2bdfba
SF
846 /* convert ByteCount if necessary */
847 if (receive_len >= sizeof(struct smb_hdr) - 4
848 /* do not count RFC1001 header */ +
849 (2 * out_buf->WordCount) + 2 /* bcc */ )
850 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
851 } else {
852 rc = -EIO;
853 cERROR(1, ("Bad MID state?"));
1da177e4 854 }
7ee1af76
JA
855
856out:
1da177e4 857 DeleteMidQEntry(midQ);
79a58d1f 858 atomic_dec(&ses->server->inFlight);
7ee1af76 859 wake_up(&ses->server->request_q);
1da177e4 860
7ee1af76
JA
861 return rc;
862}
1da177e4 863
7ee1af76
JA
864/* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
865
866static int
867send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
868 struct mid_q_entry *midQ)
869{
870 int rc = 0;
871 struct cifsSesInfo *ses = tcon->ses;
872 __u16 mid = in_buf->Mid;
873
874 header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
875 in_buf->Mid = mid;
72ca545b 876 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
877 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
878 if (rc) {
72ca545b 879 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
880 return rc;
881 }
882 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
edf1ae40
SF
883 (struct sockaddr *) &(ses->server->addr.sockAddr),
884 ses->server->noblocksnd);
72ca545b 885 mutex_unlock(&ses->server->srv_mutex);
1da177e4 886 return rc;
7ee1af76
JA
887}
888
889/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
890 blocking lock to return. */
891
892static int
893send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
894 struct smb_hdr *in_buf,
895 struct smb_hdr *out_buf)
896{
897 int bytes_returned;
898 struct cifsSesInfo *ses = tcon->ses;
899 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
900
901 /* We just modify the current in_buf to change
902 the type of lock from LOCKING_ANDX_SHARED_LOCK
903 or LOCKING_ANDX_EXCLUSIVE_LOCK to
904 LOCKING_ANDX_CANCEL_LOCK. */
905
906 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
907 pSMB->Timeout = 0;
908 pSMB->hdr.Mid = GetNextMid(ses->server);
909
910 return SendReceive(xid, ses, in_buf, out_buf,
133672ef 911 &bytes_returned, CIFS_STD_OP);
7ee1af76
JA
912}
913
914int
915SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
916 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
917 int *pbytes_returned)
918{
919 int rc = 0;
920 int rstart = 0;
921 unsigned int receive_len;
922 struct mid_q_entry *midQ;
923 struct cifsSesInfo *ses;
924
925 if (tcon == NULL || tcon->ses == NULL) {
79a58d1f 926 cERROR(1, ("Null smb session"));
7ee1af76
JA
927 return -EIO;
928 }
929 ses = tcon->ses;
930
79a58d1f
SF
931 if (ses->server == NULL) {
932 cERROR(1, ("Null tcp session"));
7ee1af76
JA
933 return -EIO;
934 }
935
79a58d1f 936 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
937 return -ENOENT;
938
79a58d1f 939 /* Ensure that we do not send more than 50 overlapping requests
7ee1af76
JA
940 to the same server. We may make this configurable later or
941 use ses->maxReq */
942
6d9c6d54
VL
943 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
944 cERROR(1, ("Illegal length, greater than maximum frame, %d",
945 in_buf->smb_buf_length));
946 return -EIO;
947 }
948
133672ef 949 rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
7ee1af76
JA
950 if (rc)
951 return rc;
952
79a58d1f 953 /* make sure that we sign in the same order that we send on this socket
7ee1af76
JA
954 and avoid races inside tcp sendmsg code that could cause corruption
955 of smb data */
956
72ca545b 957 mutex_lock(&ses->server->srv_mutex);
7ee1af76
JA
958
959 rc = allocate_mid(ses, in_buf, &midQ);
960 if (rc) {
72ca545b 961 mutex_unlock(&ses->server->srv_mutex);
7ee1af76
JA
962 return rc;
963 }
964
7ee1af76 965 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
829049cb
VL
966 if (rc) {
967 DeleteMidQEntry(midQ);
968 mutex_unlock(&ses->server->srv_mutex);
969 return rc;
970 }
1da177e4 971
7ee1af76
JA
972 midQ->midState = MID_REQUEST_SUBMITTED;
973#ifdef CONFIG_CIFS_STATS2
974 atomic_inc(&ses->server->inSend);
975#endif
976 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
edf1ae40
SF
977 (struct sockaddr *) &(ses->server->addr.sockAddr),
978 ses->server->noblocksnd);
7ee1af76
JA
979#ifdef CONFIG_CIFS_STATS2
980 atomic_dec(&ses->server->inSend);
981 midQ->when_sent = jiffies;
982#endif
72ca545b 983 mutex_unlock(&ses->server->srv_mutex);
7ee1af76 984
79a58d1f 985 if (rc < 0) {
7ee1af76
JA
986 DeleteMidQEntry(midQ);
987 return rc;
988 }
989
990 /* Wait for a reply - allow signals to interrupt. */
991 rc = wait_event_interruptible(ses->server->response_q,
79a58d1f 992 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
7ee1af76
JA
993 ((ses->server->tcpStatus != CifsGood) &&
994 (ses->server->tcpStatus != CifsNew)));
995
996 /* Were we interrupted by a signal ? */
997 if ((rc == -ERESTARTSYS) &&
998 (midQ->midState == MID_REQUEST_SUBMITTED) &&
999 ((ses->server->tcpStatus == CifsGood) ||
1000 (ses->server->tcpStatus == CifsNew))) {
1001
1002 if (in_buf->Command == SMB_COM_TRANSACTION2) {
1003 /* POSIX lock. We send a NT_CANCEL SMB to cause the
1004 blocking lock to return. */
1005
1006 rc = send_nt_cancel(tcon, in_buf, midQ);
1007 if (rc) {
1008 DeleteMidQEntry(midQ);
1009 return rc;
1010 }
1011 } else {
1012 /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
1013 to cause the blocking lock to return. */
1014
1015 rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
1016
1017 /* If we get -ENOLCK back the lock may have
1018 already been removed. Don't exit in this case. */
1019 if (rc && rc != -ENOLCK) {
1020 DeleteMidQEntry(midQ);
1021 return rc;
1022 }
1023 }
1024
1025 /* Wait 5 seconds for the response. */
79a58d1f 1026 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {
7ee1af76
JA
1027 /* We got the response - restart system call. */
1028 rstart = 1;
1029 }
1030 }
1031
1032 spin_lock(&GlobalMid_Lock);
1033 if (midQ->resp_buf) {
1034 spin_unlock(&GlobalMid_Lock);
1035 receive_len = midQ->resp_buf->smb_buf_length;
1036 } else {
79a58d1f 1037 cERROR(1, ("No response for cmd %d mid %d",
7ee1af76 1038 midQ->command, midQ->mid));
79a58d1f
SF
1039 if (midQ->midState == MID_REQUEST_SUBMITTED) {
1040 if (ses->server->tcpStatus == CifsExiting)
7ee1af76
JA
1041 rc = -EHOSTDOWN;
1042 else {
1043 ses->server->tcpStatus = CifsNeedReconnect;
1044 midQ->midState = MID_RETRY_NEEDED;
1045 }
1046 }
1047
1048 if (rc != -EHOSTDOWN) {
79a58d1f 1049 if (midQ->midState == MID_RETRY_NEEDED) {
7ee1af76 1050 rc = -EAGAIN;
79a58d1f 1051 cFYI(1, ("marking request for retry"));
7ee1af76
JA
1052 } else {
1053 rc = -EIO;
1054 }
1055 }
1056 spin_unlock(&GlobalMid_Lock);
1057 DeleteMidQEntry(midQ);
1058 return rc;
1da177e4 1059 }
50c2f753 1060
7ee1af76
JA
1061 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
1062 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
1063 receive_len, xid));
1064 rc = -EIO;
17c8bfed
VL
1065 goto out;
1066 }
7ee1af76 1067
17c8bfed 1068 /* rcvd frame is ok */
7ee1af76 1069
ac6a3ef4 1070 if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
698e96a8
VL
1071 rc = -EIO;
1072 cERROR(1, ("Bad MID state?"));
1073 goto out;
1074 }
1da177e4 1075
698e96a8
VL
1076 out_buf->smb_buf_length = receive_len;
1077 memcpy((char *)out_buf + 4,
1078 (char *)midQ->resp_buf + 4,
1079 receive_len);
1080
1081 dump_smb(out_buf, 92);
1082 /* convert the length into a more usable form */
1083 if ((receive_len > 24) &&
1084 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
1085 SECMODE_SIGN_ENABLED))) {
1086 rc = cifs_verify_signature(out_buf,
1087 &ses->server->mac_signing_key,
1088 midQ->sequence_number+1);
1089 if (rc) {
1090 cERROR(1, ("Unexpected SMB signature"));
1091 /* BB FIXME add code to kill session */
7ee1af76 1092 }
698e96a8 1093 }
17c8bfed 1094
698e96a8 1095 *pbytes_returned = out_buf->smb_buf_length;
17c8bfed 1096
698e96a8
VL
1097 /* BB special case reconnect tid and uid here? */
1098 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
17c8bfed 1099
698e96a8
VL
1100 /* convert ByteCount if necessary */
1101 if (receive_len >= sizeof(struct smb_hdr) - 4
1102 /* do not count RFC1001 header */ +
1103 (2 * out_buf->WordCount) + 2 /* bcc */ )
1104 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
17c8bfed
VL
1105
1106out:
7ee1af76
JA
1107 DeleteMidQEntry(midQ);
1108 if (rstart && rc == -EACCES)
1109 return -ERESTARTSYS;
1da177e4
LT
1110 return rc;
1111}