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