From 2e89f6eb3aa4110f49d6fd85970fd96a348cda2f Mon Sep 17 00:00:00 2001
From: Andrew Morton <akpm@digeo.com>
Date: Tue, 17 Jun 2003 18:29:30 -0700
Subject: [PATCH] [PATCH] JBD: implement journal->j_tail locking

Implement the designed locking around journal->j_tail.
---
 fs/jbd/checkpoint.c |  8 +++++---
 fs/jbd/journal.c    | 11 ++++++++---
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 1daf16f91693..f80d94f9568c 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -416,13 +416,14 @@ int cleanup_journal_tail(journal_t *journal)
 		blocknr = journal->j_head;
 	}
 	spin_unlock(&journal->j_list_lock);
-	spin_unlock(&journal->j_state_lock);
-	J_ASSERT (blocknr != 0);
+	J_ASSERT(blocknr != 0);
 
 	/* If the oldest pinned transaction is at the tail of the log
            already then there's not much we can do right now. */
-	if (journal->j_tail_sequence == first_tid)
+	if (journal->j_tail_sequence == first_tid) {
+		spin_unlock(&journal->j_state_lock);
 		return 1;
+	}
 
 	/* OK, update the superblock to recover the freed space.
 	 * Physical blocks come first: have we wrapped beyond the end of
@@ -439,6 +440,7 @@ int cleanup_journal_tail(journal_t *journal)
 	journal->j_free += freed;
 	journal->j_tail_sequence = first_tid;
 	journal->j_tail = blocknr;
+	spin_unlock(&journal->j_state_lock);
 	if (!(journal->j_flags & JFS_ABORT))
 		journal_update_superblock(journal, 1);
 	return 0;
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 43aef54cbaca..d162146b559f 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -850,12 +850,14 @@ void journal_update_superblock(journal_t *journal, int wait)
 	journal_superblock_t *sb = journal->j_superblock;
 	struct buffer_head *bh = journal->j_sb_buffer;
 
+	spin_lock(&journal->j_state_lock);
 	jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n",
 		  journal->j_tail, journal->j_tail_sequence, journal->j_errno);
 
 	sb->s_sequence = htonl(journal->j_tail_sequence);
 	sb->s_start    = htonl(journal->j_tail);
 	sb->s_errno    = htonl(journal->j_errno);
+	spin_unlock(&journal->j_state_lock);
 
 	BUFFER_TRACE(bh, "marking dirty");
 	mark_buffer_dirty(bh);
@@ -1260,18 +1262,21 @@ int journal_flush(journal_t *journal)
 	 * the magic code for a fully-recovered superblock.  Any future
 	 * commits of data to the journal will restore the current
 	 * s_start value. */
+	spin_lock(&journal->j_state_lock);
 	old_tail = journal->j_tail;
 	journal->j_tail = 0;
+	spin_unlock(&journal->j_state_lock);
 	journal_update_superblock(journal, 1);
+	spin_lock(&journal->j_state_lock);
 	journal->j_tail = old_tail;
 
-	unlock_journal(journal);
-
 	J_ASSERT(!journal->j_running_transaction);
 	J_ASSERT(!journal->j_committing_transaction);
 	J_ASSERT(!journal->j_checkpoint_transactions);
 	J_ASSERT(journal->j_head == journal->j_tail);
 	J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence);
+	spin_unlock(&journal->j_state_lock);
+	unlock_journal(journal);
 	
 	return err;
 }
@@ -1289,7 +1294,7 @@ int journal_flush(journal_t *journal)
  * we merely suppress recovery.
  */
 
-int journal_wipe (journal_t *journal, int write)
+int journal_wipe(journal_t *journal, int write)
 {
 	journal_superblock_t *sb;
 	int err = 0;
-- 
2.30.9