From: Nickolai Zeldovich <kolya@MIT.EDU>

When an ext3 partition is mounted and then quickly unmounted, the journal
thread never gets around to checking the JFS_UNMOUNT flag (it immediately
goes into a loop waiting for a new sequence number), causing the umount
process to hang in journal_kill_thread().

The problem can be easily reproduced by roughly the following steps:

	dd if=/dev/zero of=/tmp/qf bs=1024k count=10
	yes | mke2fs -j /tmp/qf
	losetup /dev/loop0 /tmp/qf
	mkdir /mnt/qf
	mount -t ext3 /dev/loop0 /mnt/qf ; umount /mnt/qf

The patch below moves the check for JFS_UNMOUNT to the beginning of the
journal thread loop, thereby preventing this race condition.

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

 25-akpm/fs/jbd/journal.c |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff -puN fs/jbd/journal.c~ext3-umount-hang fs/jbd/journal.c
--- 25/fs/jbd/journal.c~ext3-umount-hang	Tue Nov  9 15:47:25 2004
+++ 25-akpm/fs/jbd/journal.c	Tue Nov  9 15:47:26 2004
@@ -151,6 +151,9 @@ int kjournald(void *arg)
 	spin_lock(&journal->j_state_lock);
 
 loop:
+	if (journal->j_flags & JFS_UNMOUNT)
+		goto end_loop;
+
 	jbd_debug(1, "commit_sequence=%d, commit_request=%d\n",
 		journal->j_commit_sequence, journal->j_commit_request);
 
@@ -160,7 +163,7 @@ loop:
 		del_timer_sync(journal->j_commit_timer);
 		journal_commit_transaction(journal);
 		spin_lock(&journal->j_state_lock);
-		goto end_loop;
+		goto loop;
 	}
 
 	wake_up(&journal->j_wait_done_commit);
@@ -208,10 +211,9 @@ loop:
 		journal->j_commit_request = transaction->t_tid;
 		jbd_debug(1, "woke because of timeout\n");
 	}
-end_loop:
-	if (!(journal->j_flags & JFS_UNMOUNT))
-		goto loop;
+	goto loop;
 
+end_loop:
 	spin_unlock(&journal->j_state_lock);
 	del_timer_sync(journal->j_commit_timer);
 	journal->j_task = NULL;
_