## Automatically generated incremental diff
## From:   linux-2.0.39-pre6
## To:     linux-2.0.39-pre7
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.0.39-pre6/Documentation/modules.txt linux-2.0.39-pre7/Documentation/modules.txt
--- linux-2.0.39-pre6/Documentation/modules.txt	1998-12-29 11:58:25.000000000 -0800
+++ linux-2.0.39-pre7/Documentation/modules.txt	2003-08-15 15:05:02.000000000 -0700
@@ -121,7 +121,7 @@
 
 To use modprobe successfully, you generally place the following
 command in your /etc/rc.d/rc.S script.  (Read more about this in the
-"rc.hints" file in the module utilities package, "modules-x.y.z.tar.gz".)
+"rc.hints" file in the module utilities package, "modutils-x.y.z.tar.gz".)
 
 	/sbin/depmod -a
 
diff -urN linux-2.0.39-pre6/net/unix/af_unix.c linux-2.0.39-pre7/net/unix/af_unix.c
--- linux-2.0.39-pre6/net/unix/af_unix.c	1998-06-03 15:17:50.000000000 -0700
+++ linux-2.0.39-pre7/net/unix/af_unix.c	2003-08-15 15:05:02.000000000 -0700
@@ -29,20 +29,29 @@
  *		Alan Cox	:	Started proper garbage collector
  *		Heiko EiBfeldt	:	Missing verify_area check
  *		Alan Cox	:	Shutdown() bug
+ *	Michael Deutschmann	:	release was writing to the socket
+ *					structure after  freeing it.
  *
  * Known differences from reference BSD that was tested:
  *
  *	[TO FIX]
- *	ECONNREFUSED is not returned from one end of a connected() socket to the
- *		other the moment one end closes.
- *	fstat() doesn't return st_dev=NODEV, and give the blksize as high water mark
- *		and a fake inode identifier (nor the BSD first socket fstat twice bug).
+ *	ECONNREFUSED is not returned from one end of a connected() socket
+ *	to the other the moment one end closes.
+ *
+ *	fstat() doesn't return st_dev=NODEV, and give the blksize as
+ *	high water mark and a fake inode identifier (nor the BSD first socket
+ *	fstat twice bug).
+ *
  *	[NOT TO FIX]
  *	accept() returns a path name even if the connecting socket has closed
- *		in the meantime (BSD loses the path and gives up).
- *	accept() returns 0 length path for an unbound connector. BSD returns 16
- *		and a null first byte in the path (but not for gethost/peername - BSD bug ??)
+ *	in the meantime (BSD loses the path and gives up).
+ *
+ *	accept() returns 0 length path for an unbound connector. BSD returns
+ *	16 and a null first byte in the path (but not for gethost/peername
+ *	- BSD bug ??)
+ *
  *	socketpair(...SOCK_RAW..) doesn't panic the kernel.
+ *
  *	BSD af_unix apparently has connect forgetting to block properly.
  */
 
@@ -79,7 +88,7 @@
 /*
  *	Make sure the unix name is null-terminated.
  */
- 
+
 static inline void unix_mkname(struct sockaddr_un * sunaddr, unsigned long len)
 {
 	if (len >= sizeof(*sunaddr))
@@ -92,11 +101,11 @@
  *	handler using this technique. They can be added although we do not
  *	use this facility.
  */
- 
+
 static void unix_remove_socket(unix_socket *sk)
 {
 	unix_socket **s;
-	
+
 	cli();
 	s=&unix_socket_list;
 
@@ -153,16 +162,16 @@
 		sk_free(sk);
 		return;
 	}
-	
+
 	/*
 	 *	Retry;
 	 */
-	 
+
 	sk->timer.expires=jiffies+10*HZ;	/* No real hurry try it every 10 seconds or so */
 	add_timer(&sk->timer);
 }
-	 
-	 
+
+
 static void unix_delayed_delete(unix_socket *sk)
 {
 	sk->timer.data=(unsigned long)sk;
@@ -170,13 +179,15 @@
 	sk->timer.function=unix_destroy_timer;
 	add_timer(&sk->timer);
 }
-	
+
 static void unix_destroy_socket(unix_socket *sk)
 {
 	struct sk_buff *skb;
 
 	unix_remove_socket(sk);
-	
+
+	sk->socket = NULL;
+
 	while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
 	{
 		if(sk->state==TCP_LISTEN)
@@ -185,7 +196,7 @@
 			osk->state=TCP_CLOSE;
 			kfree_skb(skb, FREE_WRITE);	/* Now surplus - free the skb first before the socket */
 			osk->state_change(osk);		/* So the connect wakes and cleans up (if any) */
-			/* osk will be destroyed when it gets to close or the timer fires */			
+			/* osk will be destroyed when it gets to close or the timer fires */
 		}
 		else
 		{
@@ -193,13 +204,13 @@
 			kfree_skb(skb,FREE_WRITE);
 		}
 	}
-	
+
 	if(sk->protinfo.af_unix.inode!=NULL)
 	{
 		iput(sk->protinfo.af_unix.inode);
 		sk->protinfo.af_unix.inode=NULL;
 	}
-	
+
 	if(--sk->protinfo.af_unix.locks==0 && sk->wmem_alloc==0)
 	{
 		if(sk->protinfo.af_unix.name)
@@ -216,7 +227,7 @@
 /*
  *	Fixme: We need async I/O on AF_UNIX doing next.
  */
- 
+
 static int unix_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	return -EINVAL;
@@ -225,13 +236,13 @@
 /*
  *	Yes socket options work with the new unix domain socketry!!!!!!!
  */
- 
+
 static int unix_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
 {
 	unix_socket *sk=sock->data;
 	if(level!=SOL_SOCKET)
 		return -EOPNOTSUPP;
-	return sock_setsockopt(sk,level,optname,optval,optlen);	
+	return sock_setsockopt(sk,level,optname,optval,optlen);
 }
 
 static int unix_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
@@ -337,12 +348,12 @@
 {
 	unix_socket *sk=sock->data;
 	unix_socket *skpair;
-	
+
 	/* May not have data attached */
-	
+
 	if(sk==NULL)
 		return 0;
-		
+
 	sk->state_change(sk);
 	sk->dead=1;
 	skpair=(unix_socket *)sk->protinfo.af_unix.other;	/* Person we send to (default) */
@@ -355,16 +366,16 @@
 		skpair->protinfo.af_unix.locks--;	/* It may now die */
 	sk->protinfo.af_unix.other=NULL;		/* No pair */
 	unix_destroy_socket(sk);			/* Try to flush out this socket. Throw out buffers at least */
-	unix_gc();					/* Garbage collect fds */	
+	unix_gc();					/* Garbage collect fds */
 
 	/*
-	 *	FIXME: BSD difference: In BSD all sockets connected to use get ECONNRESET and we die on the spot. In
-	 *	Linux we behave like files and pipes do and wait for the last dereference.
+	 * FIXME: BSD difference: In BSD all sockets connected to use get
+	 * ECONNRESET and we die on the spot. In Linux we behave like files
+	 * and pipes do and wait for the last dereference.
 	 */
-	 
+
 	sock->data = NULL;
-	sk->socket = NULL;
-	
+
 	return 0;
 }
 
@@ -375,7 +386,7 @@
 	int err;
 	struct inode *inode;
 	unix_socket *u;
-	
+
 	old_fs=get_fs();
 	set_fs(get_ds());
 	err = open_namei(path, 2, S_IFSOCK, &inode, NULL);
@@ -402,10 +413,10 @@
 	unix_socket *sk=sock->data;
 	int old_fs;
 	int err;
-	
+
 	if(sk->protinfo.af_unix.name)
 		return -EINVAL;		/* Already bound */
-	
+
 	if(addr_len>sizeof(struct sockaddr_un) || addr_len<3 || sunaddr->sun_family!=AF_UNIX)
 		return -EINVAL;
 	unix_mkname(sunaddr, addr_len);
@@ -414,21 +425,21 @@
 	 */
 	if(sk->protinfo.af_unix.inode!=NULL)
 		return -EINVAL;
-	
+
 	sk->protinfo.af_unix.name=kmalloc(addr_len+1, GFP_KERNEL);
 	if(sk->protinfo.af_unix.name==NULL)
 		return -ENOMEM;
 	memcpy(sk->protinfo.af_unix.name, sunaddr->sun_path, addr_len+1);
-	
+
 	old_fs=get_fs();
 	set_fs(get_ds());
-	
+
 	err=do_mknod(sk->protinfo.af_unix.name,S_IFSOCK|S_IRWXUGO,0);
 	if(err==0)
 		err=open_namei(sk->protinfo.af_unix.name, 2, S_IFSOCK, &sk->protinfo.af_unix.inode, NULL);
-	
+
 	set_fs(old_fs);
-	
+
 	if(err<0)
 	{
 		kfree_s(sk->protinfo.af_unix.name,addr_len+1);
@@ -438,9 +449,9 @@
 		else
 			return err;
 	}
-	
+
 	return 0;
-	
+
 }
 
 static int unix_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
@@ -471,12 +482,12 @@
 		 *	Drop through the connect up logic to the wait.
 		 */
 	}
-	
+
 	if(addr_len < sizeof(sunaddr->sun_family)+1 || sunaddr->sun_family!=AF_UNIX)
 		return -EINVAL;
-		
+
 	unix_mkname(sunaddr, addr_len);
-		
+
 	if(sk->type==SOCK_DGRAM)
 	{
 		if(sk->protinfo.af_unix.other)
@@ -496,14 +507,14 @@
 		sk->state=TCP_ESTABLISHED;
 		return 0;			/* Done */
 	}
-	
+
 
 	if(sock->state==SS_UNCONNECTED)
 	{
 		/*
 		 *	Now ready to connect
 		 */
-	 
+
 		skb=sock_alloc_send_skb(sk, 0, 0, 0, &err); /* Marker object */
 		if(skb==NULL)
 			return err;
@@ -530,12 +541,12 @@
 		sk->state=TCP_SYN_SENT;
 		sock->state=SS_CONNECTING;
 		sti();
-		other->data_ready(other,0);		/* Wake up ! */		
+		other->data_ready(other,0);		/* Wake up ! */
 	}
-			
-	
+
+
 	/* Wait for an accept */
-	
+
 	cli();
 	while(sk->state==TCP_SYN_SENT)
 	{
@@ -551,11 +562,11 @@
 			return -ERESTARTSYS;
 		}
 	}
-	
+
 	/*
 	 *	Has the other end closed on us ?
 	 */
-	 
+
 	if(sk->state==TCP_CLOSE)
 	{
 		sk->protinfo.af_unix.other->protinfo.af_unix.locks--;
@@ -564,21 +575,21 @@
 		sti();
 		return -ECONNREFUSED;
 	}
-	
+
 	/*
 	 *	Amazingly it has worked
 	 */
-	 
+
 	sock->state=SS_CONNECTED;
 	sti();
 	return 0;
-	
+
 }
 
 static int unix_socketpair(struct socket *a, struct socket *b)
 {
-	unix_socket *ska,*skb;	
-	
+	unix_socket *ska,*skb;
+
 	ska=a->data;
 	skb=b->data;
 
@@ -597,7 +608,7 @@
 	unix_socket *sk=sock->data;
 	unix_socket *newsk, *tsk;
 	struct sk_buff *skb;
-	
+
 	if(sk->type!=SOCK_STREAM)
 	{
 		return -EOPNOTSUPP;
@@ -606,7 +617,7 @@
 	{
 		return -EINVAL;
 	}
-		
+
 	newsk=newsock->data;
 	if(sk->protinfo.af_unix.name!=NULL)
 	{
@@ -615,7 +626,7 @@
 			return -ENOMEM;
 		strcpy(newsk->protinfo.af_unix.name, sk->protinfo.af_unix.name);
 	}
-		
+
 	do
 	{
 		cli();
@@ -657,7 +668,7 @@
 {
 	unix_socket *sk=sock->data;
 	struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
-	
+
 	if(peer)
 	{
 		if(sk->protinfo.af_unix.other==NULL)
@@ -679,7 +690,7 @@
 /*
  *	Support routines for struct cmsghdr handling
  */
- 
+
 static struct cmsghdr *unix_copyrights(void *userp, int len) /* AT&T ? */
 {
 	struct cmsghdr *cm;
@@ -694,7 +705,7 @@
 /*
  *	Return a header block
  */
- 
+
 static void unix_returnrights(void *userp, int len, struct cmsghdr *cm)
 {
 	memcpy_tofs(userp, cm, len);
@@ -705,7 +716,7 @@
  *	Copy file descriptors into system space.
  *	Return number copied or negative error code
  */
- 
+
 static int unix_fd_copy(struct sock *sk, struct cmsghdr *cmsg, struct file **fp)
 {
 	int num=cmsg->cmsg_len-sizeof(struct cmsghdr);
@@ -715,22 +726,22 @@
 	num /= sizeof(int);	/* Odd bytes are forgotten in BSD not errored */
 	if (num >= UNIX_MAX_FD)
 		return -EINVAL;
-	
+
 	/*
 	 *	Verify the descriptors.
 	 */
-	 
+
 	for(i=0; i< num; i++)
 	{
 		int fd;
-		
-		fd = fdp[i];	
+
+		fd = fdp[i];
 		if (fd < 0 || fd >= NR_OPEN)
 			return -EBADF;
 		if (current->files->fd[fd]==NULL)
 			return -EBADF;
 	}
-	
+
         /* add another reference to these files */
 	for(i=0; i< num; i++)
 	{
@@ -738,7 +749,7 @@
 		fp[i]->f_count++;
 		unix_inflight(fp[i]);
 	}
-	
+
 	return num;
 }
 
@@ -778,7 +789,7 @@
 		cmnum = (cmsg->cmsg_len-sizeof(struct cmsghdr)) / sizeof(int);
 		cmfptr = (int *)&cmsg->cmsg_data;
 	}
-	
+
 	fdnum = *(int *)skb->h.filp;
 	fp = (struct file **)(skb->h.filp+sizeof(long));
 
@@ -816,7 +827,7 @@
 {
 	unix_detach_fds(skb,NULL);
 }
-	
+
 /*
  *	Attach the file descriptor array to an sk_buff
  */
@@ -835,7 +846,7 @@
 /*
  *	Send AF_UNIX data.
  */
-		
+
 static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
 {
 	unix_socket *sk=sock->data;
@@ -856,17 +867,17 @@
 
 	if(flags&MSG_OOB)
 		return -EOPNOTSUPP;
-			
+
 	if(flags)	/* For now */ {
 		return -EINVAL;
 	}
-		
+
 	if(sk->shutdown&SEND_SHUTDOWN)
 	{
 		send_sig(SIGPIPE,current,0);
 		return -EPIPE;
 	}
-	
+
 	if(sunaddr!=NULL)
 	{
 		if(sock->type==SOCK_STREAM)
@@ -887,9 +898,9 @@
 	/*
 	 *	A control message has been attached.
 	 */
-	if(msg->msg_control) 
+	if(msg->msg_control)
 	{
-		struct cmsghdr *cm=unix_copyrights(msg->msg_control, 
+		struct cmsghdr *cm=unix_copyrights(msg->msg_control,
 						msg->msg_controllen);
 		if(cm==NULL || msg->msg_controllen<sizeof(struct cmsghdr) ||
 		   cm->cmsg_type!=SCM_RIGHTS ||
@@ -897,7 +908,7 @@
 		   msg->msg_controllen!=cm->cmsg_len)
 		{
 			kfree(cm);
-		   	return -EINVAL;
+			return -EINVAL;
 		}
 		fpnum=unix_fd_copy(sk,cm,fp);
 		kfree(cm);
@@ -909,10 +920,10 @@
 	while(sent < len)
 	{
 		/*
-		 *	Optimisation for the fact that under 0.01% of X messages typically
-		 *	need breaking up.
+		 * Optimisation for the fact that under 0.01% of X messages
+		 * typically need breaking up.
 		 */
-		 
+
 		size=len-sent;
 
 		if(size>(sk->sndbuf-sizeof(struct sk_buff))/2)	/* Keep two messages in the pipe so it schedules better */
@@ -938,9 +949,9 @@
 		/*
 		 *	Grab a buffer
 		 */
-		 
+
 		skb=sock_alloc_send_skb(sk,size,limit,nonblock, &err);
-		
+
 		if(skb==NULL)
 		{
 			unix_fd_free(sk,fp,fpnum);
@@ -955,7 +966,7 @@
 
 		skb->sk=sk;
 		skb->free=1;
-		
+
 		if(fpnum)
 		{
 			unix_attach_fds(fpnum,fp,skb);
@@ -1026,7 +1037,7 @@
 /*
  *	Sleep until data has arrive. But check for races..
  */
- 
+
 static void unix_data_wait(unix_socket * sk)
 {
 	cli();
@@ -1053,19 +1064,19 @@
 
 	if(flags&MSG_OOB)
 		return -EOPNOTSUPP;
-		
+
 	if(addr_len)
 		*addr_len=0;
-		
+
 	if(sk->err)
 		return sock_error(sk);
 
-	if(msg->msg_control) 
+	if(msg->msg_control)
 	{
-		cm=unix_copyrights(msg->msg_control, 
+		cm=unix_copyrights(msg->msg_control,
 			msg->msg_controllen);
 		if(msg->msg_controllen<sizeof(struct cmsghdr)
-#if 0 
+#if 0
 /*		investigate this further -- Stevens example doesn't seem to care */
 		||
 		   cm->cmsg_type!=SCM_RIGHTS ||
@@ -1076,10 +1087,10 @@
 		{
 			kfree(cm);
 /*			printk("recvmsg: Bad msg_control\n");*/
-		   	return -EINVAL;
+			return -EINVAL;
 		}
 	}
-	
+
 	down(&sk->protinfo.af_unix.readsem);		/* Lock the socket */
 	while(ct--)
 	{
@@ -1087,7 +1098,7 @@
 		sp=iov->iov_base;
 		len=iov->iov_len;
 		iov++;
-		
+
 		while(done<len)
 		{
 			if (copied && (flags & MSG_PEEK))
@@ -1156,9 +1167,9 @@
 {
 	unix_socket *sk=(unix_socket *)sock->data;
 	unix_socket *other=sk->protinfo.af_unix.other;
-	
+
 	mode++;
-	
+
 	if(mode&SEND_SHUTDOWN)
 	{
 		sk->shutdown|=SEND_SHUTDOWN;
@@ -1183,7 +1194,7 @@
 	return 0;
 }
 
-		
+
 static int unix_select(struct socket *sock,  int sel_type, select_table *wait)
 {
 	return datagram_select(sock->data,sel_type,wait);
@@ -1194,10 +1205,10 @@
 	unix_socket *sk=sock->data;
 	int err;
 	long amount=0;
-			
+
 	switch(cmd)
 	{
-	
+
 		case TIOCOUTQ:
 			err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
 			if(err)
@@ -1236,10 +1247,10 @@
 	off_t begin=0;
 	int len=0;
 	unix_socket *s=unix_socket_list;
-	
+
 	len+= sprintf(buffer,"Num       RefCount Protocol Flags    Type St "
 	    "Inode Path\n");
-	
+
 	while(s!=NULL)
 	{
 		len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X %5ld",
@@ -1254,7 +1265,7 @@
 			len+=sprintf(buffer+len, " %s\n", s->protinfo.af_unix.name);
 		else
 			buffer[len++]='\n';
-		
+
 		pos=begin+len;
 		if(pos<offset)
 		{
@@ -1275,7 +1286,7 @@
 
 struct proto_ops unix_proto_ops = {
 	AF_UNIX,
-	
+
 	unix_create,
 	unix_dup,
 	unix_release,
