[PATCH] cifs: Do not init smb requests or block when sending requests

if cifsd thread is no longer running to demultixplex responses.

Do not send FindClose request when FindFirst failed without reaching end
of search. 

Signed-off-by: Steve French (sfrench@us.ibm.com)
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 437be1e..ac1f970 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -604,7 +604,13 @@
 	spin_lock(&GlobalMid_Lock);
 	server->tcpStatus = CifsExiting;
 	server->tsk = NULL;
-	atomic_set(&server->inFlight, 0);
+	/* check if we have blocked requests that need to free */
+	/* Note that cifs_max_pending is normally 50, but
+	can be set at module install time to as little as two */
+	if(atomic_read(&server->inFlight) >= cifs_max_pending)
+		atomic_set(&server->inFlight, cifs_max_pending - 1);
+	/* We do not want to set the max_pending too low or we
+	could end up with the counter going negative */
 	spin_unlock(&GlobalMid_Lock);
 	/* Although there should not be any requests blocked on 
 	this queue it can not hurt to be paranoid and try to wake up requests
@@ -640,6 +646,17 @@
 		}
 		read_unlock(&GlobalSMBSeslock);
 	} else {
+		/* although we can not zero the server struct pointer yet,
+		since there are active requests which may depnd on them,
+		mark the corresponding SMB sessions as exiting too */
+		list_for_each(tmp, &GlobalSMBSessionList) {
+			ses = list_entry(tmp, struct cifsSesInfo,
+					 cifsSessionList);
+			if (ses->server == server) {
+				ses->status = CifsExiting;
+			}
+		}
+
 		spin_lock(&GlobalMid_Lock);
 		list_for_each(tmp, &server->pending_mid_q) {
 		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
@@ -661,17 +678,34 @@
 	if (list_empty(&server->pending_mid_q)) {
 		/* mpx threads have not exited yet give them 
 		at least the smb send timeout time for long ops */
+		/* due to delays on oplock break requests, we need
+		to wait at least 45 seconds before giving up
+		on a request getting a response and going ahead
+		and killing cifsd */
 		cFYI(1, ("Wait for exit from demultiplex thread"));
-		msleep(46);
+		msleep(46000);
 		/* if threads still have not exited they are probably never
 		coming home not much else we can do but free the memory */
 	}
-	kfree(server);
 
 	write_lock(&GlobalSMBSeslock);
 	atomic_dec(&tcpSesAllocCount);
 	length = tcpSesAllocCount.counter;
+
+	/* last chance to mark ses pointers invalid
+	if there are any pointing to this (e.g
+	if a crazy root user tried to kill cifsd 
+	kernel thread explicitly this might happen) */
+	list_for_each(tmp, &GlobalSMBSessionList) {
+		ses = list_entry(tmp, struct cifsSesInfo,
+				cifsSessionList);
+		if (ses->server == server) {
+			ses->server = NULL;
+		}
+	}
 	write_unlock(&GlobalSMBSeslock);
+
+	kfree(server);
 	if(length  > 0) {
 		mempool_resize(cifs_req_poolp,
 			length + cifs_min_rcv,