kfree(server); 
cifs_demultiplex_thread(struct TCP_Server_Info *server){	int length;	unsigned int pdu_length, total_read;	struct smb_hdr *smb_buffer = NULL;	struct smb_hdr *bigbuf = NULL;	struct smb_hdr *smallbuf = NULL;	struct msghdr smb_msg;	struct kvec iov;	struct socket *csocket = server->ssocket;	struct list_head *tmp;	struct cifsSesInfo *ses;	struct task_struct *task_to_wake = NULL;	struct mid_q_entry *mid_entry;	char *temp;	int isLargeBuf = FALSE;	int isMultiRsp;	int reconnect;	daemonize("cifsd");	allow_signal(SIGKILL);	current->flags |= PF_MEMALLOC;	server->tsk = current;	/* save process info to wake at shutdown */	cFYI(1, ("Demultiplex PID: %d", current->pid));	write_lock(&GlobalSMBSeslock); 	atomic_inc(&tcpSesAllocCount);	length = tcpSesAllocCount.counter;	write_unlock(&GlobalSMBSeslock);	if(length  > 1) {		mempool_resize(cifs_req_poolp,			length + cifs_min_rcv,			GFP_KERNEL);	}	while (server->tcpStatus != CifsExiting) {		if (bigbuf == NULL) {			bigbuf = cifs_buf_get();			if(bigbuf == NULL) {				cERROR(1,("No memory for large SMB response"));				msleep(3000);				/* retry will check if exiting */				continue;			}		} else if(isLargeBuf) {			/* we are reusing a dirtry large buf, clear its start */			memset(bigbuf, 0, sizeof (struct smb_hdr));		}		if (smallbuf == NULL) {			smallbuf = cifs_small_buf_get();			if(smallbuf == NULL) {				cERROR(1,("No memory for SMB response"));				msleep(1000);				/* retry will check if exiting */				continue;			}			/* beginning of smb buffer is cleared in our buf_get */		} else /* if existing small buf clear beginning */			memset(smallbuf, 0, sizeof (struct smb_hdr));		isLargeBuf = FALSE;		isMultiRsp = FALSE;		smb_buffer = smallbuf;		iov.iov_base = smb_buffer;		iov.iov_len = 4;		smb_msg.msg_control = NULL;		smb_msg.msg_controllen = 0;		length =		    kernel_recvmsg(csocket, &smb_msg,				 &iov, 1, 4, 0 /* BB see socket.h flags */);		if(server->tcpStatus == CifsExiting) {			break;		} else if (server->tcpStatus == CifsNeedReconnect) {			cFYI(1,("Reconnect after server stopped responding"));			cifs_reconnect(server);			cFYI(1,("call to reconnect done"));			csocket = server->ssocket;			continue;		} else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {			msleep(1); /* minimum sleep to prevent looping				allowing socket to clear and app threads to set				tcpStatus CifsNeedReconnect if server hung */			continue;		} else if (length <= 0) {			if(server->tcpStatus == CifsNew) {				cFYI(1,("tcp session abend after SMBnegprot"));				/* some servers kill the TCP session rather than				   returning an SMB negprot error, in which				   case reconnecting here is not going to help,				   and so simply return error to mount */				break;			}			if(length == -EINTR) { 				cFYI(1,("cifsd thread killed"));				break;			}			cFYI(1,("Reconnect after unexpected peek error %d",				length));			cifs_reconnect(server);			csocket = server->ssocket;			wake_up(&server->response_q);			continue;		} else if (length < 4) {			cFYI(1,			    ("Frame under four bytes received (%d bytes long)",			      length));			cifs_reconnect(server);			csocket = server->ssocket;			wake_up(&server->response_q);			continue;		}		/* the right amount was read from socket - 4 bytes */		pdu_length = ntohl(smb_buffer->smb_buf_length);		cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4));		temp = (char *) smb_buffer;		if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {			continue; 		} else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {			cFYI(1,("Good RFC 1002 session rsp"));			continue;		} else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {			/* we get this from Windows 98 instead of 			   an error on SMB negprot response */			cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",				temp[4]));			if(server->tcpStatus == CifsNew) {				/* if nack on negprot (rather than 				ret of smb negprot error) reconnecting				not going to help, ret error to mount */				break;			} else {				/* give server a second to				clean up before reconnect attempt */				msleep(1000);				/* always try 445 first on reconnect				since we get NACK on some if we ever				connected to port 139 (the NACK is 				since we do not begin with RFC1001				session initialize frame) */				server->addr.sockAddr.sin_port = 					htons(CIFS_PORT);				cifs_reconnect(server);				csocket = server->ssocket;				wake_up(&server->response_q);				continue;			}		} else if (temp[0] != (char) 0) {			cERROR(1,("Unknown RFC 1002 frame"));			cifs_dump_mem(" Received Data: ", temp, length);			cifs_reconnect(server);			csocket = server->ssocket;			continue;		}		/* else we have an SMB response */		if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||			    (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {			cERROR(1, ("Invalid size SMB length %d pdu_length %d",					length, pdu_length+4));			cifs_reconnect(server);			csocket = server->ssocket;			wake_up(&server->response_q);			continue;		} 		/* else length ok */		reconnect = 0;		if(pdu_length > MAX_CIFS_HDR_SIZE - 4) {			isLargeBuf = TRUE;			memcpy(bigbuf, smallbuf, 4);			smb_buffer = bigbuf;		}		length = 0;		iov.iov_base = 4 + (char *)smb_buffer;		iov.iov_len = pdu_length;		for (total_read = 0; total_read < pdu_length; 		     total_read += length) {			length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,						pdu_length - total_read, 0);			if((server->tcpStatus == CifsExiting) ||			    (length == -EINTR)) {				/* then will exit */				reconnect = 2;				break;			} else if (server->tcpStatus == CifsNeedReconnect) {				cifs_reconnect(server);				csocket = server->ssocket;			        /* Reconnect wakes up rspns q */				/* Now we will reread sock */				reconnect = 1;				break;			} else if ((length == -ERESTARTSYS) || 				   (length == -EAGAIN)) {				msleep(1); /* minimum sleep to prevent looping,                                              allowing socket to clear and app 					      threads to set tcpStatus					      CifsNeedReconnect if server hung*/				continue;			} else if (length <= 0) {				cERROR(1,("Received no data, expecting %d",					      pdu_length - total_read));				cifs_reconnect(server);				csocket = server->ssocket;				reconnect = 1;				break;			}		}		if(reconnect == 2)			break;		else if(reconnect == 1)			continue;		length += 4; /* account for rfc1002 hdr */			dump_smb(smb_buffer, length);		if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) {			cERROR(1, ("Bad SMB Received "));			continue;		}		task_to_wake = NULL;		spin_lock(&GlobalMid_Lock);		list_for_each(tmp, &server->pending_mid_q) {			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);			if ((mid_entry->mid == smb_buffer->Mid) && 			    (mid_entry->midState == MID_REQUEST_SUBMITTED) &&			    (mid_entry->command == smb_buffer->Command)) {				if(check2ndT2(smb_buffer,server->maxBuf) > 0) {					/* We have a multipart transact2 resp */					isMultiRsp = TRUE;					if(mid_entry->resp_buf) {						/* merge response - fix up 1st*/						if(coalesce_t2(smb_buffer, 							mid_entry->resp_buf)) {							break;						} else {							/* all parts received */							goto multi_t2_fnd; 						}					} else {						if(!isLargeBuf) {							cERROR(1,("1st trans2 resp needs bigbuf"));					/* BB maybe we can fix this up,  switch				   	   to already allocated large buffer? */						} else {							/* Have first buffer */							mid_entry->resp_buf =								 smb_buffer;							mid_entry->largeBuf = 1;							bigbuf = NULL;						}					}					break;				} 				mid_entry->resp_buf = smb_buffer;				if(isLargeBuf)					mid_entry->largeBuf = 1;				else					mid_entry->largeBuf = 0;multi_t2_fnd:				task_to_wake = mid_entry->tsk;				mid_entry->midState = MID_RESPONSE_RECEIVED;				break;			}		}		spin_unlock(&GlobalMid_Lock);		if (task_to_wake) {			/* Was previous buf put in mpx struct for multi-rsp? */			if(!isMultiRsp) {				/* smb buffer will be freed by user thread */				if(isLargeBuf) {					bigbuf = NULL;				} else					smallbuf = NULL;			}			wake_up_process(task_to_wake);		} else if ((is_valid_oplock_break(smb_buffer) == FALSE)		    && (isMultiRsp == FALSE)) {                          			cERROR(1, ("No task to wake, unknown frame rcvd!"));			cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));		}	} /* end while !EXITING */	spin_lock(&GlobalMid_Lock);	server->tcpStatus = CifsExiting;	server->tsk = NULL;	atomic_set(&server->inFlight, 0);	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	that may haven been blocked when more than 50 at time were on the wire	to the same server - they now will see the session is in exit state	and get out of SendReceive.  */	wake_up_all(&server->request_q);	/* give those requests time to exit */	msleep(125);		if(server->ssocket) {		sock_release(csocket);		server->ssocket = NULL;	}	/* buffer usuallly freed in free_mid - need to free it here on exit */	if (bigbuf != NULL)		cifs_buf_release(bigbuf);	if (smallbuf != NULL)		cifs_small_buf_release(smallbuf);	read_lock(&GlobalSMBSeslock);	if (list_empty(&server->pending_mid_q)) {		/* loop through server session structures attached to this and		    mark them dead */		list_for_each(tmp, &GlobalSMBSessionList) {			ses =			    list_entry(tmp, struct cifsSesInfo,				       cifsSessionList);			if (ses->server == server) {				ses->status = CifsExiting;				ses->server = NULL;			}		}		read_unlock(&GlobalSMBSeslock);	} else {		spin_lock(&GlobalMid_Lock);		list_for_each(tmp, &server->pending_mid_q) {		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);			if (mid_entry->midState == MID_REQUEST_SUBMITTED) {				cFYI(1,				  ("Clearing Mid 0x%x - waking up ",mid_entry->mid));				task_to_wake = mid_entry->tsk;				if(task_to_wake) {					wake_up_process(task_to_wake);				}			}		}		spin_unlock(&GlobalMid_Lock);		read_unlock(&GlobalSMBSeslock);		/* 1/8th of sec is more than enough time for them to exit */		msleep(125);	}	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 */		cFYI(1, ("Wait for exit from demultiplex thread"));		msleep(46);		/* 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;	write_unlock(&GlobalSMBSeslock);	if(length  > 0) {		mempool_resize(cifs_req_poolp,			length + cifs_min_rcv,			GFP_KERNEL);	}		msleep(250);	return 0;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/31ca3bc3c569f9fe02aae6974ac3a9126f14902f/connect.c/buggy/fs/cifs/connect.c