]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - fs/cifs/transport.c
cifs: have calc_lanman_hash take more granular args
[mirror_ubuntu-artful-kernel.git] / fs / cifs / transport.c
1 /*
2 * fs/cifs/transport.c
3 *
4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * Jeremy Allison (jra@samba.org) 2006.
7 *
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
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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"
35
36 extern mempool_t *cifs_mid_poolp;
37 extern struct kmem_cache *cifs_oplock_cachep;
38
39 static struct mid_q_entry *
40 AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
41 {
42 struct mid_q_entry *temp;
43
44 if (server == NULL) {
45 cERROR(1, ("Null TCP session in AllocMidQEntry"));
46 return NULL;
47 }
48
49 temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
50 if (temp == NULL)
51 return temp;
52 else {
53 memset(temp, 0, sizeof(struct mid_q_entry));
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));
58 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
59 /* when mid allocated can be before when sent */
60 temp->when_alloc = jiffies;
61 temp->tsk = current;
62 }
63
64 spin_lock(&GlobalMid_Lock);
65 list_add_tail(&temp->qhead, &server->pending_mid_q);
66 atomic_inc(&midCount);
67 temp->midState = MID_REQUEST_ALLOCATED;
68 spin_unlock(&GlobalMid_Lock);
69 return temp;
70 }
71
72 static void
73 DeleteMidQEntry(struct mid_q_entry *midEntry)
74 {
75 #ifdef CONFIG_CIFS_STATS2
76 unsigned long now;
77 #endif
78 spin_lock(&GlobalMid_Lock);
79 midEntry->midState = MID_FREE;
80 list_del(&midEntry->qhead);
81 atomic_dec(&midCount);
82 spin_unlock(&GlobalMid_Lock);
83 if (midEntry->largeBuf)
84 cifs_buf_release(midEntry->resp_buf);
85 else
86 cifs_small_buf_release(midEntry->resp_buf);
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 */
91 if ((now - midEntry->when_alloc) > HZ) {
92 if ((cifsFYI & CIFS_TIMER) &&
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
103 mempool_free(midEntry, cifs_mid_poolp);
104 }
105
106 struct oplock_q_entry *
107 AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
108 {
109 struct oplock_q_entry *temp;
110 if ((pinode == NULL) || (tcon == NULL)) {
111 cERROR(1, ("Null parms passed to AllocOplockQEntry"));
112 return NULL;
113 }
114 temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep,
115 GFP_KERNEL);
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
130 void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
131 {
132 spin_lock(&GlobalMid_Lock);
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
139
140 void 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
157 int
158 smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
159 unsigned int smb_buf_length, struct sockaddr *sin, bool noblocksnd)
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
167 if (ssocket == NULL)
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;
173 smb_msg.msg_namelen = sizeof(struct sockaddr);
174 smb_msg.msg_control = NULL;
175 smb_msg.msg_controllen = 0;
176 if (noblocksnd)
177 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
178 else
179 smb_msg.msg_flags = MSG_NOSIGNAL;
180
181 /* smb header is converted in header_assemble. bcc and rest of SMB word
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
184 Flags2 is converted in SendReceive */
185
186 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
187 cFYI(1, ("Sending smb of length %d", smb_buf_length));
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++;
194 /* smaller timeout here than send2 since smaller size */
195 /* Although it may not be required, this also is smaller
196 oplock break time */
197 if (i > 12) {
198 cERROR(1,
199 ("sends on sock %p stuck for 7 seconds",
200 ssocket));
201 rc = -EAGAIN;
202 break;
203 }
204 msleep(1 << i);
205 continue;
206 }
207 if (rc < 0)
208 break;
209 else
210 i = 0; /* reset i after each successful send */
211 iov.iov_base += rc;
212 iov.iov_len -= rc;
213 len -= rc;
214 }
215
216 if (rc < 0) {
217 cERROR(1, ("Error %d sending data on socket to server", rc));
218 } else {
219 rc = 0;
220 }
221
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
226 return rc;
227 }
228
229 static int
230 smb_send2(struct TCP_Server_Info *server, struct kvec *iov, int n_vec,
231 struct sockaddr *sin, bool noblocksnd)
232 {
233 int rc = 0;
234 int i = 0;
235 struct msghdr smb_msg;
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;
240 unsigned int smb_buf_length = smb_buffer->smb_buf_length;
241 struct socket *ssocket = server->ssocket;
242
243 if (ssocket == NULL)
244 return -ENOTSOCK; /* BB eventually add reconnect code here */
245
246 smb_msg.msg_name = sin;
247 smb_msg.msg_namelen = sizeof(struct sockaddr);
248 smb_msg.msg_control = NULL;
249 smb_msg.msg_controllen = 0;
250 if (noblocksnd)
251 smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
252 else
253 smb_msg.msg_flags = MSG_NOSIGNAL;
254
255 /* smb header is converted in header_assemble. bcc and rest of SMB word
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
258 Flags2 is converted in SendReceive */
259
260
261 total_len = 0;
262 for (i = 0; i < n_vec; i++)
263 total_len += iov[i].iov_len;
264
265 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
266 cFYI(1, ("Sending smb: total_len %d", total_len));
267 dump_smb(smb_buffer, len);
268
269 i = 0;
270 while (total_len) {
271 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
272 n_vec - first_vec, total_len);
273 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
274 i++;
275 if (i >= 14) {
276 cERROR(1,
277 ("sends on sock %p stuck for 15 seconds",
278 ssocket));
279 rc = -EAGAIN;
280 break;
281 }
282 msleep(1 << i);
283 continue;
284 }
285 if (rc < 0)
286 break;
287
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));
293 break;
294 }
295 if (rc == 0) {
296 /* should never happen, letting socket clear before
297 retrying is our only obvious option here */
298 cERROR(1, ("tcp sent no data"));
299 msleep(500);
300 continue;
301 }
302 total_len -= rc;
303 /* the line below resets i */
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 }
316 }
317 i = 0; /* in case we get ENOSPC on the next send */
318 }
319
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
330 if (rc < 0) {
331 cERROR(1, ("Error %d sending data on socket to server", rc));
332 } else
333 rc = 0;
334
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
339 return rc;
340 }
341
342 static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
343 {
344 if (long_op == CIFS_ASYNC_OP) {
345 /* oplock breaks must not be held up */
346 atomic_inc(&ses->server->inFlight);
347 } else {
348 spin_lock(&GlobalMid_Lock);
349 while (1) {
350 if (atomic_read(&ses->server->inFlight) >=
351 cifs_max_pending){
352 spin_unlock(&GlobalMid_Lock);
353 #ifdef CONFIG_CIFS_STATS2
354 atomic_inc(&ses->server->num_waiters);
355 #endif
356 wait_event(ses->server->request_q,
357 atomic_read(&ses->server->inFlight)
358 < cifs_max_pending);
359 #ifdef CONFIG_CIFS_STATS2
360 atomic_dec(&ses->server->num_waiters);
361 #endif
362 spin_lock(&GlobalMid_Lock);
363 } else {
364 if (ses->server->tcpStatus == CifsExiting) {
365 spin_unlock(&GlobalMid_Lock);
366 return -ENOENT;
367 }
368
369 /* can not count locking commands against total
370 as they are allowed to block on server */
371
372 /* update # of requests on the wire to server */
373 if (long_op != CIFS_BLOCKING_OP)
374 atomic_inc(&ses->server->inFlight);
375 spin_unlock(&GlobalMid_Lock);
376 break;
377 }
378 }
379 }
380 return 0;
381 }
382
383 static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
384 struct mid_q_entry **ppmidQ)
385 {
386 if (ses->server->tcpStatus == CifsExiting) {
387 return -ENOENT;
388 } else if (ses->server->tcpStatus == CifsNeedReconnect) {
389 cFYI(1, ("tcp session dead - return to caller to retry"));
390 return -EAGAIN;
391 } else if (ses->status != CifsGood) {
392 /* check if SMB session is bad because we are setting it up */
393 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
394 (in_buf->Command != SMB_COM_NEGOTIATE))
395 return -EAGAIN;
396 /* else ok - we are setting up session */
397 }
398 *ppmidQ = AllocMidQEntry(in_buf, ses->server);
399 if (*ppmidQ == NULL)
400 return -ENOMEM;
401 return 0;
402 }
403
404 static int wait_for_response(struct cifsSesInfo *ses,
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;
413 wait_event_timeout(ses->server->response_q,
414 midQ->midState != MID_REQUEST_SUBMITTED, timeout);
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.
430 Although we prefer not to time out if the
431 server is still responding - we will time
432 out if the server takes more than 15 (or 45
433 or 180) seconds to respond to this request
434 and has not responded to any request from
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. */
439 cERROR(1, ("server not responding"));
440 return -1;
441 }
442 } else {
443 return 0;
444 }
445 }
446 }
447
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 */
458 int
459 SendReceiveNoRsp(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);
470 cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc));
471
472 return rc;
473 }
474
475 int
476 SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
477 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
478 const int flags)
479 {
480 int rc = 0;
481 int long_op;
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;
486
487 long_op = flags & CIFS_TIMEOUT_MASK;
488
489 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
490
491 if ((ses == NULL) || (ses->server == NULL)) {
492 cifs_small_buf_release(in_buf);
493 cERROR(1, ("Null session"));
494 return -EIO;
495 }
496
497 if (ses->server->tcpStatus == CifsExiting) {
498 cifs_small_buf_release(in_buf);
499 return -ENOENT;
500 }
501
502 /* Ensure that we do not send more than 50 overlapping requests
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
512 /* make sure that we sign in the same order that we send on this socket
513 and avoid races inside tcp sendmsg code that could cause corruption
514 of smb data */
515
516 mutex_lock(&ses->server->srv_mutex);
517
518 rc = allocate_mid(ses, in_buf, &midQ);
519 if (rc) {
520 mutex_unlock(&ses->server->srv_mutex);
521 cifs_small_buf_release(in_buf);
522 /* Update # of requests on wire to server */
523 atomic_dec(&ses->server->inFlight);
524 wake_up(&ses->server->request_q);
525 return rc;
526 }
527 rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
528
529 midQ->midState = MID_REQUEST_SUBMITTED;
530 #ifdef CONFIG_CIFS_STATS2
531 atomic_inc(&ses->server->inSend);
532 #endif
533 rc = smb_send2(ses->server, iov, n_vec,
534 (struct sockaddr *) &(ses->server->addr.sockAddr),
535 ses->server->noblocksnd);
536 #ifdef CONFIG_CIFS_STATS2
537 atomic_dec(&ses->server->inSend);
538 midQ->when_sent = jiffies;
539 #endif
540
541 mutex_unlock(&ses->server->srv_mutex);
542 cifs_small_buf_release(in_buf);
543
544 if (rc < 0)
545 goto out;
546
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 */
550 timeout = 180 * HZ;
551 else if (long_op == CIFS_LONG_OP)
552 timeout = 45 * HZ; /* should be greater than
553 servers oplock break timeout (about 43 seconds) */
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 }
563
564 /* wait for 15 seconds or until woken up due to response arriving or
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
568 but we still give response a chance to complete */
569 timeout = 2 * HZ;
570 }
571
572 /* No user interrupts in wait - wreaks havoc with performance */
573 wait_for_response(ses, midQ, timeout, 10 * HZ);
574
575 spin_lock(&GlobalMid_Lock);
576 if (midQ->resp_buf) {
577 spin_unlock(&GlobalMid_Lock);
578 receive_len = midQ->resp_buf->smb_buf_length;
579 } else {
580 cERROR(1, ("No response to cmd %d mid %d",
581 midQ->command, midQ->mid));
582 if (midQ->midState == MID_REQUEST_SUBMITTED) {
583 if (ses->server->tcpStatus == CifsExiting)
584 rc = -EHOSTDOWN;
585 else {
586 ses->server->tcpStatus = CifsNeedReconnect;
587 midQ->midState = MID_RETRY_NEEDED;
588 }
589 }
590
591 if (rc != -EHOSTDOWN) {
592 if (midQ->midState == MID_RETRY_NEEDED) {
593 rc = -EAGAIN;
594 cFYI(1, ("marking request for retry"));
595 } else {
596 rc = -EIO;
597 }
598 }
599 spin_unlock(&GlobalMid_Lock);
600 DeleteMidQEntry(midQ);
601 /* Update # of requests on wire to server */
602 atomic_dec(&ses->server->inFlight);
603 wake_up(&ses->server->request_q);
604 return rc;
605 }
606
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 */
612 if (midQ->resp_buf &&
613 (midQ->midState == MID_RESPONSE_RECEIVED)) {
614
615 iov[0].iov_base = (char *)midQ->resp_buf;
616 if (midQ->largeBuf)
617 *pRespBufType = CIFS_LARGE_BUFFER;
618 else
619 *pRespBufType = CIFS_SMALL_BUFFER;
620 iov[0].iov_len = receive_len + 4;
621
622 dump_smb(midQ->resp_buf, 80);
623 /* convert the length into a more usable form */
624 if ((receive_len > 24) &&
625 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
626 SECMODE_SIGN_ENABLED))) {
627 rc = cifs_verify_signature(midQ->resp_buf,
628 &ses->server->mac_signing_key,
629 midQ->sequence_number+1);
630 if (rc) {
631 cERROR(1, ("Unexpected SMB signature"));
632 /* BB FIXME add code to kill session */
633 }
634 }
635
636 /* BB special case reconnect tid and uid here? */
637 rc = map_smb_to_linux_error(midQ->resp_buf,
638 flags & CIFS_LOG_ERROR);
639
640 /* convert ByteCount if necessary */
641 if (receive_len >= sizeof(struct smb_hdr) - 4
642 /* do not count RFC1001 header */ +
643 (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
644 BCC(midQ->resp_buf) =
645 le16_to_cpu(BCC_LE(midQ->resp_buf));
646 if ((flags & CIFS_NO_RESP) == 0)
647 midQ->resp_buf = NULL; /* mark it so buf will
648 not be freed by
649 DeleteMidQEntry */
650 } else {
651 rc = -EIO;
652 cFYI(1, ("Bad MID state?"));
653 }
654 }
655
656 out:
657 DeleteMidQEntry(midQ);
658 atomic_dec(&ses->server->inFlight);
659 wake_up(&ses->server->request_q);
660
661 return rc;
662 }
663
664 int
665 SendReceive(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) {
675 cERROR(1, ("Null smb session"));
676 return -EIO;
677 }
678 if (ses->server == NULL) {
679 cERROR(1, ("Null tcp session"));
680 return -EIO;
681 }
682
683 if (ses->server->tcpStatus == CifsExiting)
684 return -ENOENT;
685
686 /* Ensure that we do not send more than 50 overlapping requests
687 to the same server. We may make this configurable later or
688 use ses->maxReq */
689
690 rc = wait_for_free_request(ses, long_op);
691 if (rc)
692 return rc;
693
694 /* make sure that we sign in the same order that we send on this socket
695 and avoid races inside tcp sendmsg code that could cause corruption
696 of smb data */
697
698 mutex_lock(&ses->server->srv_mutex);
699
700 rc = allocate_mid(ses, in_buf, &midQ);
701 if (rc) {
702 mutex_unlock(&ses->server->srv_mutex);
703 /* Update # of requests on wire to server */
704 atomic_dec(&ses->server->inFlight);
705 wake_up(&ses->server->request_q);
706 return rc;
707 }
708
709 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
710 cERROR(1, ("Illegal length, greater than maximum frame, %d",
711 in_buf->smb_buf_length));
712 DeleteMidQEntry(midQ);
713 mutex_unlock(&ses->server->srv_mutex);
714 /* Update # of requests on wire to server */
715 atomic_dec(&ses->server->inFlight);
716 wake_up(&ses->server->request_q);
717 return -EIO;
718 }
719
720 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
721
722 midQ->midState = MID_REQUEST_SUBMITTED;
723 #ifdef CONFIG_CIFS_STATS2
724 atomic_inc(&ses->server->inSend);
725 #endif
726 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
727 (struct sockaddr *) &(ses->server->addr.sockAddr),
728 ses->server->noblocksnd);
729 #ifdef CONFIG_CIFS_STATS2
730 atomic_dec(&ses->server->inSend);
731 midQ->when_sent = jiffies;
732 #endif
733 mutex_unlock(&ses->server->srv_mutex);
734
735 if (rc < 0)
736 goto out;
737
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)
743 goto out;
744 else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */
745 timeout = 180 * HZ;
746 else if (long_op == CIFS_LONG_OP)
747 timeout = 45 * HZ; /* should be greater than
748 servers oplock break timeout (about 43 seconds) */
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
757 if (signal_pending(current)) {
758 /* if signal pending do not hold up user for full smb timeout
759 but we still give response a chance to complete */
760 timeout = 2 * HZ;
761 }
762
763 /* No user interrupts in wait - wreaks havoc with performance */
764 wait_for_response(ses, midQ, timeout, 10 * HZ);
765
766 spin_lock(&GlobalMid_Lock);
767 if (midQ->resp_buf) {
768 spin_unlock(&GlobalMid_Lock);
769 receive_len = midQ->resp_buf->smb_buf_length;
770 } else {
771 cERROR(1, ("No response for cmd %d mid %d",
772 midQ->command, midQ->mid));
773 if (midQ->midState == MID_REQUEST_SUBMITTED) {
774 if (ses->server->tcpStatus == CifsExiting)
775 rc = -EHOSTDOWN;
776 else {
777 ses->server->tcpStatus = CifsNeedReconnect;
778 midQ->midState = MID_RETRY_NEEDED;
779 }
780 }
781
782 if (rc != -EHOSTDOWN) {
783 if (midQ->midState == MID_RETRY_NEEDED) {
784 rc = -EAGAIN;
785 cFYI(1, ("marking request for retry"));
786 } else {
787 rc = -EIO;
788 }
789 }
790 spin_unlock(&GlobalMid_Lock);
791 DeleteMidQEntry(midQ);
792 /* Update # of requests on wire to server */
793 atomic_dec(&ses->server->inFlight);
794 wake_up(&ses->server->request_q);
795 return rc;
796 }
797
798 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
799 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
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 */
813 if ((receive_len > 24) &&
814 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
815 SECMODE_SIGN_ENABLED))) {
816 rc = cifs_verify_signature(out_buf,
817 &ses->server->mac_signing_key,
818 midQ->sequence_number+1);
819 if (rc) {
820 cERROR(1, ("Unexpected SMB signature"));
821 /* BB FIXME add code to kill session */
822 }
823 }
824
825 *pbytes_returned = out_buf->smb_buf_length;
826
827 /* BB special case reconnect tid and uid here? */
828 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
829
830 /* convert ByteCount if necessary */
831 if (receive_len >= sizeof(struct smb_hdr) - 4
832 /* do not count RFC1001 header */ +
833 (2 * out_buf->WordCount) + 2 /* bcc */ )
834 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
835 } else {
836 rc = -EIO;
837 cERROR(1, ("Bad MID state?"));
838 }
839 }
840
841 out:
842 DeleteMidQEntry(midQ);
843 atomic_dec(&ses->server->inFlight);
844 wake_up(&ses->server->request_q);
845
846 return rc;
847 }
848
849 /* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */
850
851 static int
852 send_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;
861 mutex_lock(&ses->server->srv_mutex);
862 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
863 if (rc) {
864 mutex_unlock(&ses->server->srv_mutex);
865 return rc;
866 }
867 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
868 (struct sockaddr *) &(ses->server->addr.sockAddr),
869 ses->server->noblocksnd);
870 mutex_unlock(&ses->server->srv_mutex);
871 return rc;
872 }
873
874 /* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
875 blocking lock to return. */
876
877 static int
878 send_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,
896 &bytes_returned, CIFS_STD_OP);
897 }
898
899 int
900 SendReceiveBlockingLock(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) {
911 cERROR(1, ("Null smb session"));
912 return -EIO;
913 }
914 ses = tcon->ses;
915
916 if (ses->server == NULL) {
917 cERROR(1, ("Null tcp session"));
918 return -EIO;
919 }
920
921 if (ses->server->tcpStatus == CifsExiting)
922 return -ENOENT;
923
924 /* Ensure that we do not send more than 50 overlapping requests
925 to the same server. We may make this configurable later or
926 use ses->maxReq */
927
928 rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
929 if (rc)
930 return rc;
931
932 /* make sure that we sign in the same order that we send on this socket
933 and avoid races inside tcp sendmsg code that could cause corruption
934 of smb data */
935
936 mutex_lock(&ses->server->srv_mutex);
937
938 rc = allocate_mid(ses, in_buf, &midQ);
939 if (rc) {
940 mutex_unlock(&ses->server->srv_mutex);
941 return rc;
942 }
943
944 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
945 mutex_unlock(&ses->server->srv_mutex);
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);
953
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,
959 (struct sockaddr *) &(ses->server->addr.sockAddr),
960 ses->server->noblocksnd);
961 #ifdef CONFIG_CIFS_STATS2
962 atomic_dec(&ses->server->inSend);
963 midQ->when_sent = jiffies;
964 #endif
965 mutex_unlock(&ses->server->srv_mutex);
966
967 if (rc < 0) {
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,
974 (!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
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. */
1008 if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {
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 {
1019 cERROR(1, ("No response for cmd %d mid %d",
1020 midQ->command, midQ->mid));
1021 if (midQ->midState == MID_REQUEST_SUBMITTED) {
1022 if (ses->server->tcpStatus == CifsExiting)
1023 rc = -EHOSTDOWN;
1024 else {
1025 ses->server->tcpStatus = CifsNeedReconnect;
1026 midQ->midState = MID_RETRY_NEEDED;
1027 }
1028 }
1029
1030 if (rc != -EHOSTDOWN) {
1031 if (midQ->midState == MID_RETRY_NEEDED) {
1032 rc = -EAGAIN;
1033 cFYI(1, ("marking request for retry"));
1034 } else {
1035 rc = -EIO;
1036 }
1037 }
1038 spin_unlock(&GlobalMid_Lock);
1039 DeleteMidQEntry(midQ);
1040 return rc;
1041 }
1042
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 */
1058 if ((receive_len > 24) &&
1059 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
1060 SECMODE_SIGN_ENABLED))) {
1061 rc = cifs_verify_signature(out_buf,
1062 &ses->server->mac_signing_key,
1063 midQ->sequence_number+1);
1064 if (rc) {
1065 cERROR(1, ("Unexpected SMB signature"));
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? */
1073 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
1074
1075 /* convert ByteCount if necessary */
1076 if (receive_len >= sizeof(struct smb_hdr) - 4
1077 /* do not count RFC1001 header */ +
1078 (2 * out_buf->WordCount) + 2 /* bcc */ )
1079 BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
1080 } else {
1081 rc = -EIO;
1082 cERROR(1, ("Bad MID state?"));
1083 }
1084 }
1085 DeleteMidQEntry(midQ);
1086 if (rstart && rc == -EACCES)
1087 return -ERESTARTSYS;
1088 return rc;
1089 }