
From: Chris Mason <mason@suse.com>

There's a small window where the filesystem can be unmounted during
writeback_inodes.  The end result is the iput done by sync_sb_inodes could
be done after the FS put_super and and the super has been removed from all
lists.

The fix is to hold the s_umount sem during sync_sb_inodes to make sure
the FS doesn't get unmounted.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/fs-writeback.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletion(-)

diff -puN fs/fs-writeback.c~writeback_inodes-can-race-with-unmount fs/fs-writeback.c
--- 25/fs/fs-writeback.c~writeback_inodes-can-race-with-unmount	2004-06-08 22:36:31.816781144 -0700
+++ 25-akpm/fs/fs-writeback.c	2004-06-08 22:37:12.651573312 -0700
@@ -396,9 +396,19 @@ restart:
 	sb = sb_entry(super_blocks.prev);
 	for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
 		if (!list_empty(&sb->s_dirty) || !list_empty(&sb->s_io)) {
+			/* we're making our own get_super here */
 			sb->s_count++;
 			spin_unlock(&sb_lock);
-			sync_sb_inodes(sb, wbc);
+			/*
+			 * If we can't get the readlock, there's no sense in
+			 * waiting around, most of the time the FS is going to
+			 * be unmounted by the time it is released.
+			 */
+			if (down_read_trylock(&sb->s_umount)) {
+				if (sb->s_root)
+					sync_sb_inodes(sb, wbc);
+				up_read(&sb->s_umount);
+			}
 			spin_lock(&sb_lock);
 			if (__put_super(sb))
 				goto restart;
_
