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

diff -urN linux-2.4.22-bk55/Makefile linux-2.4.22-bk56/Makefile
--- linux-2.4.22-bk55/Makefile	2003-11-18 02:59:22.000000000 -0800
+++ linux-2.4.22-bk56/Makefile	2003-11-18 02:59:50.000000000 -0800
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 22
-EXTRAVERSION = -bk55
+EXTRAVERSION = -bk56
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.22-bk55/drivers/net/tulip/tulip_core.c linux-2.4.22-bk56/drivers/net/tulip/tulip_core.c
--- linux-2.4.22-bk55/drivers/net/tulip/tulip_core.c	2003-11-18 02:59:38.000000000 -0800
+++ linux-2.4.22-bk56/drivers/net/tulip/tulip_core.c	2003-11-18 02:59:57.000000000 -0800
@@ -1073,12 +1073,12 @@
 
 		set_bit_le(index, hash_table);
 
-		for (i = 0; i < 32; i++) {
-			*setup_frm++ = hash_table[i];
-			*setup_frm++ = hash_table[i];
-		}
-		setup_frm = &tp->setup_frame[13*6];
 	}
+	for (i = 0; i < 32; i++) {
+		*setup_frm++ = hash_table[i];
+		*setup_frm++ = hash_table[i];
+	}
+	setup_frm = &tp->setup_frame[13*6];
 
 	/* Fill the final entry with our physical address. */
 	eaddrs = (u16 *)dev->dev_addr;
@@ -1178,11 +1178,13 @@
 		}
 	} else {
 		unsigned long flags;
+		u32 tx_flags = 0x08000000 | 192;
 
 		/* Note that only the low-address shortword of setup_frame is valid!
 		   The values are doubled for big-endian architectures. */
 		if (dev->mc_count > 14) { /* Must use a multicast hash table. */
 			build_setup_frame_hash(tp->setup_frame, dev);
+			tx_flags = 0x08400000 | 192;
 		} else {
 			build_setup_frame_perfect(tp->setup_frame, dev);
 		}
@@ -1192,7 +1194,6 @@
 		if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) {
 			/* Same setup recently queued, we need not add it. */
 		} else {
-			u32 tx_flags = 0x08000000 | 192;
 			unsigned int entry;
 			int dummy = -1;
 
diff -urN linux-2.4.22-bk55/fs/inode.c linux-2.4.22-bk56/fs/inode.c
--- linux-2.4.22-bk55/fs/inode.c	2003-11-18 02:59:48.000000000 -0800
+++ linux-2.4.22-bk56/fs/inode.c	2003-11-18 03:00:06.000000000 -0800
@@ -206,7 +206,8 @@
 	if ((inode->i_state & flags) != flags) {
 		inode->i_state |= flags;
 		/* Only add valid (ie hashed) inodes to the dirty list */
-		if (!(inode->i_state & I_LOCK) && !list_empty(&inode->i_hash)) {
+		if (!(inode->i_state & (I_LOCK|I_FREEING|I_CLEAR)) &&
+		    !list_empty(&inode->i_hash)) {
 			list_del(&inode->i_list);
 			list_add(&inode->i_list, &sb->s_dirty);
 		}
@@ -235,6 +236,30 @@
 		__wait_on_inode(inode);
 }
 
+/*
+ * If we try to find an inode in the inode hash while it is being deleted, we
+ * have to wait until the filesystem completes its deletion before reporting
+ * that it isn't found.  This is because iget will immediately call
+ * ->read_inode, and we want to be sure that evidence of the deletion is found
+ * by ->read_inode.
+ *
+ * This call might return early if an inode which shares the waitq is woken up.
+ * This is most easily handled by the caller which will loop around again
+ * looking for the inode.
+ *
+ * This is called with inode_lock held.
+ */
+static void __wait_on_freeing_inode(struct inode *inode)
+{
+        DECLARE_WAITQUEUE(wait, current);
+
+        add_wait_queue(&inode->i_wait, &wait);
+        set_current_state(TASK_UNINTERRUPTIBLE);
+        spin_unlock(&inode_lock);
+        schedule();
+        remove_wait_queue(&inode->i_wait, &wait);
+        spin_lock(&inode_lock);
+}
 
 static inline void write_inode(struct inode *inode, int sync)
 {
@@ -596,6 +621,11 @@
 		if (inode->i_data.nrpages)
 			truncate_inode_pages(&inode->i_data, 0);
 		clear_inode(inode);
+		spin_lock(&inode_lock);
+		list_del(&inode->i_hash);
+		INIT_LIST_HEAD(&inode->i_hash);
+		spin_unlock(&inode_lock);
+		wake_up(&inode->i_wait);
 		destroy_inode(inode);
 		nr_disposed++;
 	}
@@ -707,6 +737,14 @@
  *
  * We don't expect to have to call this very often.
  *
+ * We leave the inode in the inode hash table until *after* 
+ * the filesystem's ->delete_inode (in dispose_list) completes.
+ * This ensures that an iget (such as nfsd might instigate) will 
+ * always find up-to-date information either in the hash or on disk.
+ *
+ * I_FREEING is set so that no-one will take a new reference
+ * to the inode while it is being deleted.
+ *
  * N.B. The spinlock is released during the call to
  *      dispose_list.
  */
@@ -739,8 +777,6 @@
 		if (atomic_read(&inode->i_count))
 			continue;
 		list_del(tmp);
-		list_del(&inode->i_hash);
-		INIT_LIST_HEAD(&inode->i_hash);
 		list_add(tmp, freeable);
 		inode->i_state |= I_FREEING;
 		count++;
@@ -793,6 +829,7 @@
 	struct list_head *tmp;
 	struct inode * inode;
 
+repeat:
 	tmp = head;
 	for (;;) {
 		tmp = tmp->next;
@@ -806,6 +843,10 @@
 			continue;
 		if (find_actor && !find_actor(inode, ino, opaque))
 			continue;
+		if (inode->i_state & (I_FREEING|I_CLEAR)) {
+			__wait_on_freeing_inode(inode);
+			goto repeat;
+		}
 		break;
 	}
 	return inode;
@@ -1076,8 +1117,6 @@
 			return;
 
 		if (!inode->i_nlink) {
-			list_del(&inode->i_hash);
-			INIT_LIST_HEAD(&inode->i_hash);
 			list_del(&inode->i_list);
 			INIT_LIST_HEAD(&inode->i_list);
 			inode->i_state|=I_FREEING;
@@ -1095,6 +1134,11 @@
 				delete(inode);
 			} else
 				clear_inode(inode);
+			spin_lock(&inode_lock);
+			list_del(&inode->i_hash);
+			INIT_LIST_HEAD(&inode->i_hash);
+			spin_unlock(&inode_lock);
+			wake_up(&inode->i_wait);
 			if (inode->i_state != I_CLEAR)
 				BUG();
 		} else {
diff -urN linux-2.4.22-bk55/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.4.22-bk56/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- linux-2.4.22-bk55/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-11-18 02:59:48.000000000 -0800
+++ linux-2.4.22-bk56/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-11-18 03:00:07.000000000 -0800
@@ -53,7 +53,7 @@
 unsigned long ip_ct_tcp_timeout_syn_recv =     60 SECS;
 unsigned long ip_ct_tcp_timeout_established =   5 DAYS;
 unsigned long ip_ct_tcp_timeout_fin_wait =      2 MINS;
-unsigned long ip_ct_tcp_timeout_close_wait =    3 DAYS;
+unsigned long ip_ct_tcp_timeout_close_wait =   60 SECS;
 unsigned long ip_ct_tcp_timeout_last_ack =     30 SECS;
 unsigned long ip_ct_tcp_timeout_time_wait =     2 MINS;
 unsigned long ip_ct_tcp_timeout_close =        10 SECS;
