From: Andrew Morton <akpm@osdl.org>

Cc: Kirill Korotaev <dev@sw.ru>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 fs/dcache.c            |   13 ++++++-------
 include/linux/dcache.h |    2 +-
 2 files changed, 7 insertions(+), 8 deletions(-)

diff -puN fs/dcache.c~fix-of-dcache-race-leading-to-busy-inodes-on-umount-tidy fs/dcache.c
--- 25/fs/dcache.c~fix-of-dcache-race-leading-to-busy-inodes-on-umount-tidy	2005-05-11 19:34:53.000000000 -0700
+++ 25-akpm/fs/dcache.c	2005-05-11 19:34:53.000000000 -0700
@@ -116,7 +116,7 @@ struct dcache_shrinker {
 	struct dentry *dentry;
 };
 
-DECLARE_WAIT_QUEUE_HEAD(dcache_shrinker_wq);
+static DECLARE_WAIT_QUEUE_HEAD(dcache_shrinker_wq);
 
 /* called under dcache_lock */
 static void dcache_shrinker_add(struct dcache_shrinker *ds,
@@ -128,8 +128,9 @@ static void dcache_shrinker_add(struct d
 		sb = parent->d_sb;
 		ds->dentry = parent;
 		list_add(&ds->list, &sb->s_dshrinkers);
-	} else
+	} else {
 		INIT_LIST_HEAD(&ds->list);
+	}
 }
 
 /* called under dcache_lock */
@@ -145,15 +146,13 @@ static void dcache_shrinker_del(struct d
 /* called under dcache_lock, drops inside */
 static void dcache_shrinker_wait(struct super_block *sb)
 {
-	DECLARE_WAITQUEUE(wq, current);
+	DEFINE_WAIT(wait);
 
-	__set_current_state(TASK_UNINTERRUPTIBLE);
-	add_wait_queue(&dcache_shrinker_wq, &wq);
+	prepare_to_wait(&dcache_shrinker_wq, &wait, TASK_UNINTERRUPTIBLE);
 	spin_unlock(&dcache_lock);
 
 	schedule();
-	remove_wait_queue(&dcache_shrinker_wq, &wq);
-	__set_current_state(TASK_RUNNING);
+	finish_wait(&dcache_shrinker_wq, &wait);
 }
 
 void dcache_shrinker_wait_sb(struct super_block *sb)
diff -puN include/linux/dcache.h~fix-of-dcache-race-leading-to-busy-inodes-on-umount-tidy include/linux/dcache.h
--- 25/include/linux/dcache.h~fix-of-dcache-race-leading-to-busy-inodes-on-umount-tidy	2005-05-11 19:34:53.000000000 -0700
+++ 25-akpm/include/linux/dcache.h	2005-05-11 19:34:53.000000000 -0700
@@ -209,7 +209,7 @@ extern struct dentry * d_alloc_anon(stru
 extern struct dentry * d_splice_alias(struct inode *, struct dentry *);
 extern void shrink_dcache_sb(struct super_block *);
 extern void shrink_dcache_parent(struct dentry *);
-extern void shrink_dcache_anon(struct super_block *);
+extern void shrink_dcache_anon(struct super_block *sb);
 extern void dcache_shrinker_wait_sb(struct super_block *sb);
 extern int d_invalidate(struct dentry *);
 
_