From: florin@iucha.net (Florin Iucha)

Trond's patch fixes the problem.  The box has been up an running for three
hours under normal usage (web, mail, nfs share browsing) it even rebooted
without problem.
y


 net/sunrpc/rpc_pipe.c |   33 ++++++++++++++++++++-------------
 1 files changed, 20 insertions(+), 13 deletions(-)

diff -puN net/sunrpc/rpc_pipe.c~rpc-depopulate-fix net/sunrpc/rpc_pipe.c
--- 25/net/sunrpc/rpc_pipe.c~rpc-depopulate-fix	2003-06-14 22:28:13.000000000 -0700
+++ 25-akpm/net/sunrpc/rpc_pipe.c	2003-06-14 22:28:13.000000000 -0700
@@ -472,30 +472,37 @@ static void
 rpc_depopulate(struct dentry *parent)
 {
 	struct inode *dir = parent->d_inode;
-	HLIST_HEAD(head);
 	struct list_head *pos, *next;
-	struct dentry *dentry;
+	struct dentry *dentry, *dvec[10];
+	int n = 0;
 
 	down(&dir->i_sem);
+repeat:
 	spin_lock(&dcache_lock);
 	list_for_each_safe(pos, next, &parent->d_subdirs) {
 		dentry = list_entry(pos, struct dentry, d_child);
+		spin_lock(&dentry->d_lock);
 		if (!d_unhashed(dentry)) {
 			dget_locked(dentry);
 			__d_drop(dentry);
-			hlist_add_head(&dentry->d_hash, &head);
-		}
+			spin_unlock(&dentry->d_lock);
+			dvec[n++] = dentry;
+			if (n == ARRAY_SIZE(dvec))
+				break;
+		} else
+			spin_unlock(&dentry->d_lock);
 	}
 	spin_unlock(&dcache_lock);
-	while (!hlist_empty(&head)) {
-		dentry = list_entry(head.first, struct dentry, d_hash);
-		/* Private list, so no dcache_lock needed and use __d_drop */
-		__d_drop(dentry);
-		if (dentry->d_inode) {
-			rpc_inode_setowner(dentry->d_inode, NULL);
-			simple_unlink(dir, dentry);
-		}
-		dput(dentry);
+	if (n) {
+		do {
+			dentry = dvec[--n];
+			if (dentry->d_inode) {
+				rpc_inode_setowner(dentry->d_inode, NULL);
+				simple_unlink(dir, dentry);
+			}
+			dput(dentry);
+		} while (n);
+		goto repeat;
 	}
 	up(&dir->i_sem);
 }

_