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

diff -urN linux-2.5.70-bk17/Makefile linux-2.5.70-bk18/Makefile
--- linux-2.5.70-bk17/Makefile	2003-06-13 04:47:35.000000000 -0700
+++ linux-2.5.70-bk18/Makefile	2003-06-13 04:47:40.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 70
-EXTRAVERSION = -bk17
+EXTRAVERSION = -bk18
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.70-bk17/fs/dcache.c linux-2.5.70-bk18/fs/dcache.c
--- linux-2.5.70-bk17/fs/dcache.c	2003-06-13 04:47:37.000000000 -0700
+++ linux-2.5.70-bk18/fs/dcache.c	2003-06-13 04:47:43.000000000 -0700
@@ -1221,10 +1221,14 @@
 	}
 
 	/* Move the dentry to the target hash queue, if on different bucket */
+	if (dentry->d_vfs_flags & DCACHE_UNHASHED)
+		goto already_unhashed;
 	if (dentry->d_bucket != target->d_bucket) {
-		dentry->d_bucket = target->d_bucket;
 		hlist_del_rcu(&dentry->d_hash);
+already_unhashed:
+		dentry->d_bucket = target->d_bucket;
 		hlist_add_head_rcu(&dentry->d_hash, target->d_bucket);
+		dentry->d_vfs_flags &= ~DCACHE_UNHASHED;
 	}
 
 	/* Unhash the target: dput() will then get rid of it */
diff -urN linux-2.5.70-bk17/include/linux/dcache.h linux-2.5.70-bk18/include/linux/dcache.h
--- linux-2.5.70-bk17/include/linux/dcache.h	2003-06-13 04:47:37.000000000 -0700
+++ linux-2.5.70-bk18/include/linux/dcache.h	2003-06-13 04:47:44.000000000 -0700
@@ -174,8 +174,10 @@
 
 static inline void __d_drop(struct dentry *dentry)
 {
-	dentry->d_vfs_flags |= DCACHE_UNHASHED;
-	hlist_del_rcu_init(&dentry->d_hash);
+	if (!(dentry->d_vfs_flags & DCACHE_UNHASHED)) {
+		dentry->d_vfs_flags |= DCACHE_UNHASHED;
+		hlist_del_rcu(&dentry->d_hash);
+	}
 }
 
 static inline void d_drop(struct dentry *dentry)
diff -urN linux-2.5.70-bk17/include/linux/list.h linux-2.5.70-bk18/include/linux/list.h
--- linux-2.5.70-bk17/include/linux/list.h	2003-06-13 04:47:37.000000000 -0700
+++ linux-2.5.70-bk18/include/linux/list.h	2003-06-13 04:47:44.000000000 -0700
@@ -152,14 +152,17 @@
 /**
  * list_del_rcu - deletes entry from list without re-initialization
  * @entry: the element to delete from the list.
+ *
  * Note: list_empty on entry does not return true after this, 
  * the entry is in an undefined state. It is useful for RCU based
  * lockfree traversal.
+ *
+ * In particular, it means that we can not poison the forward 
+ * pointers that may still be used for walking the list.
  */
 static inline void list_del_rcu(struct list_head *entry)
 {
 	__list_del(entry->prev, entry->next);
-	entry->next = LIST_POISON1;
 	entry->prev = LIST_POISON2;
 }
 
@@ -431,7 +434,22 @@
 	n->pprev = LIST_POISON2;
 }
 
-#define hlist_del_rcu hlist_del  /* list_del_rcu is identical too? */
+/**
+ * hlist_del_rcu - deletes entry from hash list without re-initialization
+ * @entry: the element to delete from the hash list.
+ *
+ * Note: list_unhashed() on entry does not return true after this, 
+ * the entry is in an undefined state. It is useful for RCU based
+ * lockfree traversal.
+ *
+ * In particular, it means that we can not poison the forward
+ * pointers that may still be used for walking the hash list.
+ */
+static inline void hlist_del_rcu(struct hlist_node *n)
+{
+	__hlist_del(n);
+	n->pprev = LIST_POISON2;
+}
 
 static __inline__ void hlist_del_init(struct hlist_node *n) 
 {
