lkml.org 
[lkml]   [2005]   [Mar]   [16]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
DateWed, 16 Mar 2005 10:53:59 +0100
FromIngo Molnar <>
Subject[patch 2/3] j_list_lock -> j_list_sem
this patch turns the j_list_lock spinlock into a mutex.
Builds/boots/works fine on x86.

Signed-off-by: Ingo Molnar <mingo@elte.hu>

--- linux/fs/jbd/checkpoint.c.orig
+++ linux/fs/jbd/checkpoint.c
@@ -26,7 +26,7 @@
 /*
  * Unlink a buffer from a transaction. 
  *
- * Called with j_list_lock held.
+ * Called with j_list_sem held.
  */
 
 static inline void __buffer_unlink(struct journal_head *jh)
@@ -47,7 +47,7 @@ static inline void __buffer_unlink(struc
 /*
  * Try to release a checkpointed buffer from its transaction.
  * Returns 1 if we released it.
- * Requires j_list_lock
+ * Requires j_list_sem
  * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
 static int __try_to_free_cp_buf(struct journal_head *jh)
@@ -102,14 +102,14 @@ void __log_wait_for_space(journal_t *jou
 }
 
 /*
- * We were unable to perform jbd_trylock_bh_state() inside j_list_lock.
+ * We were unable to perform jbd_trylock_bh_state() inside j_list_sem.
  * The caller must restart a list walk.  Wait for someone else to run
  * jbd_unlock_bh_state().
  */
 static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh)
 {
 	get_bh(bh);
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	jbd_lock_bh_state(bh);
 	jbd_unlock_bh_state(bh);
 	put_bh(bh);
@@ -125,7 +125,7 @@ static void jbd_sync_bh(journal_t *journ
  * checkpoint.  (journal_remove_checkpoint() deletes the transaction when
  * the last checkpoint buffer is cleansed)
  *
- * Called with j_list_lock held.
+ * Called with j_list_sem held.
  */
 static int __cleanup_transaction(journal_t *journal, transaction_t *transaction)
 {
@@ -133,7 +133,6 @@ static int __cleanup_transaction(journal
 	struct buffer_head *bh;
 	int ret = 0;
 
-	assert_spin_locked(&journal->j_list_lock);
 	jh = transaction->t_checkpoint_list;
 	if (!jh)
 		return 0;
@@ -145,7 +144,7 @@ static int __cleanup_transaction(journal
 		bh = jh2bh(jh);
 		if (buffer_locked(bh)) {
 			atomic_inc(&bh->b_count);
-			spin_unlock(&journal->j_list_lock);
+			up(&journal->j_list_sem);
 			wait_on_buffer(bh);
 			/* the journal_head may have gone by now */
 			BUFFER_TRACE(bh, "brelse");
@@ -165,7 +164,7 @@ static int __cleanup_transaction(journal
 			transaction_t *t = jh->b_transaction;
 			tid_t tid = t->t_tid;
 
-			spin_unlock(&journal->j_list_lock);
+			up(&journal->j_list_sem);
 			jbd_unlock_bh_state(bh);
 			log_start_commit(journal, tid);
 			log_wait_commit(journal, tid);
@@ -192,7 +191,7 @@ static int __cleanup_transaction(journal
 
 	return ret;
 out_return_1:
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	return 1;
 }
 
@@ -203,9 +202,9 @@ __flush_batch(journal_t *journal, struct
 {
 	int i;
 
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	ll_rw_block(WRITE, *batch_count, bhs);
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	for (i = 0; i < *batch_count; i++) {
 		struct buffer_head *bh = bhs[i];
 		clear_buffer_jwrite(bh);
@@ -221,7 +220,7 @@ __flush_batch(journal_t *journal, struct
  * Return 1 if something happened which requires us to abort the current
  * scan of the checkpoint list.  
  *
- * Called with j_list_lock held.
+ * Called with j_list_sem held.
  * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
 static int __flush_buffer(journal_t *journal, struct journal_head *jh,
@@ -306,7 +305,7 @@ int log_do_checkpoint(journal_t *journal
 	 * AKPM: check this code.  I had a feeling a while back that it
 	 * degenerates into a busy loop at unmount time.
 	 */
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	while (journal->j_checkpoint_transactions) {
 		transaction_t *transaction;
 		struct journal_head *jh, *last_jh, *next_jh;
@@ -327,15 +326,11 @@ int log_do_checkpoint(journal_t *journal
 			bh = jh2bh(jh);
 			if (!jbd_trylock_bh_state(bh)) {
 				jbd_sync_bh(journal, bh);
-				spin_lock(&journal->j_list_lock);
+				down(&journal->j_list_sem);
 				retry = 1;
 				break;
 			}
 			retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);
-			if (cond_resched_lock(&journal->j_list_lock)) {
-				retry = 1;
-				break;
-			}
 		} while (jh != last_jh && !retry);
 
 		if (batch_count)
@@ -365,7 +360,7 @@ int log_do_checkpoint(journal_t *journal
 		if (journal->j_checkpoint_transactions != transaction)
 			break;
 	}
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	result = cleanup_journal_tail(journal);
 	if (result < 0)
 		return result;
@@ -404,7 +399,7 @@ int cleanup_journal_tail(journal_t *jour
 	 * start. */
 
 	down(&journal->j_state_sem);
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	transaction = journal->j_checkpoint_transactions;
 	if (transaction) {
 		first_tid = transaction->t_tid;
@@ -419,7 +414,7 @@ int cleanup_journal_tail(journal_t *jour
 		first_tid = journal->j_transaction_sequence;
 		blocknr = journal->j_head;
 	}
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	J_ASSERT(blocknr != 0);
 
 	/* If the oldest pinned transaction is at the tail of the log
@@ -459,7 +454,7 @@ int cleanup_journal_tail(journal_t *jour
  * Find all the written-back checkpoint buffers in the journal and release them.
  *
  * Called with the journal locked.
- * Called with j_list_lock held.
+ * Called with j_list_sem held.
  * Returns number of bufers reaped (for debug)
  */
 
@@ -519,7 +514,7 @@ out:
  * checkpoint list.  
  *
  * This function is called with the journal locked.
- * This function is called with j_list_lock held.
+ * This function is called with j_list_sem held.
  */
 
 void __journal_remove_checkpoint(struct journal_head *jh)
@@ -573,7 +568,7 @@ out:
  * the log.
  *
  * Called with the journal locked.
- * Called with j_list_lock held.
+ * Called with j_list_sem held.
  */
 void __journal_insert_checkpoint(struct journal_head *jh, 
 			       transaction_t *transaction)
@@ -602,12 +597,11 @@ void __journal_insert_checkpoint(struct 
  * point.
  *
  * Called with the journal locked.
- * Called with j_list_lock held.
+ * Called with j_list_sem held.
  */
 
 void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
 {
-	assert_spin_locked(&journal->j_list_lock);
 	if (transaction->t_cpnext) {
 		transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
 		transaction->t_cpprev->t_cpnext = transaction->t_cpnext;
--- linux/fs/jbd/transaction.c.orig
+++ linux/fs/jbd/transaction.c
@@ -485,7 +485,7 @@ void journal_unlock_updates (journal_t *
  * continuing as gracefully as possible.  #
  *
  * The caller should already hold the journal lock and
- * j_list_lock spinlock: most callers will need those anyway
+ * j_list_sem mutex: most callers will need those anyway
  * in order to probe the buffer's journaling state safely.
  */
 static void jbd_unexpected_dirty_buffer(struct journal_head *jh)
@@ -694,9 +694,9 @@ repeat:
 		J_ASSERT_JH(jh, !jh->b_next_transaction);
 		jh->b_transaction = transaction;
 		JBUFFER_TRACE(jh, "file as BJ_Reserved");
-		spin_lock(&journal->j_list_lock);
+		down(&journal->j_list_sem);
 		__journal_file_buffer(jh, transaction, BJ_Reserved);
-		spin_unlock(&journal->j_list_lock);
+		up(&journal->j_list_sem);
 	}
 
 done:
@@ -796,7 +796,7 @@ int journal_get_create_access(handle_t *
 	 * reused here.
 	 */
 	jbd_lock_bh_state(bh);
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	J_ASSERT_JH(jh, (jh->b_transaction == transaction ||
 		jh->b_transaction == NULL ||
 		(jh->b_transaction == journal->j_committing_transaction &&
@@ -813,7 +813,7 @@ int journal_get_create_access(handle_t *
 		JBUFFER_TRACE(jh, "set next transaction");
 		jh->b_next_transaction = transaction;
 	}
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	jbd_unlock_bh_state(bh);
 
 	/*
@@ -962,7 +962,7 @@ int journal_dirty_data(handle_t *handle,
 	 * about it in this layer.
 	 */
 	jbd_lock_bh_state(bh);
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	if (jh->b_transaction) {
 		JBUFFER_TRACE(jh, "has transaction");
 		if (jh->b_transaction != handle->h_transaction) {
@@ -1018,12 +1018,12 @@ int journal_dirty_data(handle_t *handle,
 			 */
 			if (buffer_dirty(bh)) {
 				get_bh(bh);
-				spin_unlock(&journal->j_list_lock);
+				up(&journal->j_list_sem);
 				jbd_unlock_bh_state(bh);
 				need_brelse = 1;
 				sync_dirty_buffer(bh);
 				jbd_lock_bh_state(bh);
-				spin_lock(&journal->j_list_lock);
+				down(&journal->j_list_sem);
 				/* The buffer may become locked again at any
 				   time if it is redirtied */
 			}
@@ -1055,7 +1055,7 @@ int journal_dirty_data(handle_t *handle,
 		__journal_file_buffer(jh, handle->h_transaction, BJ_SyncData);
 	}
 no_journal:
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	jbd_unlock_bh_state(bh);
 	if (need_brelse) {
 		BUFFER_TRACE(bh, "brelse");
@@ -1145,9 +1145,9 @@ int journal_dirty_metadata(handle_t *han
 	J_ASSERT_JH(jh, jh->b_frozen_data == 0);
 
 	JBUFFER_TRACE(jh, "file as BJ_Metadata");
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	__journal_file_buffer(jh, handle->h_transaction, BJ_Metadata);
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 out_unlock_bh:
 	jbd_unlock_bh_state(bh);
 out:
@@ -1194,7 +1194,7 @@ int journal_forget (handle_t *handle, st
 	BUFFER_TRACE(bh, "entry");
 
 	jbd_lock_bh_state(bh);
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 
 	if (!buffer_jbd(bh))
 		goto not_jbd;
@@ -1246,7 +1246,7 @@ int journal_forget (handle_t *handle, st
 			journal_remove_journal_head(bh);
 			__brelse(bh);
 			if (!buffer_jbd(bh)) {
-				spin_unlock(&journal->j_list_lock);
+				up(&journal->j_list_sem);
 				jbd_unlock_bh_state(bh);
 				__bforget(bh);
 				goto drop;
@@ -1269,7 +1269,7 @@ int journal_forget (handle_t *handle, st
 	}
 
 not_jbd:
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	jbd_unlock_bh_state(bh);
 	__brelse(bh);
 drop:
@@ -1416,7 +1416,7 @@ int journal_force_commit(journal_t *jour
  * Append a buffer to a transaction list, given the transaction's list head
  * pointer.
  *
- * j_list_lock is held.
+ * j_list_sem is held.
  *
  * jbd_lock_bh_state(jh2bh(jh)) is held.
  */
@@ -1440,7 +1440,7 @@ __blist_add_buffer(struct journal_head *
  * Remove a buffer from a transaction list, given the transaction's list
  * head pointer.
  *
- * Called with j_list_lock held, and the journal may not be locked.
+ * Called with j_list_sem held, and the journal may not be locked.
  *
  * jbd_lock_bh_state(jh2bh(jh)) is held.
  */
@@ -1466,7 +1466,7 @@ __blist_del_buffer(struct journal_head *
  * is holding onto a copy of one of thee pointers, it could go bad.
  * Generally the caller needs to re-read the pointer from the transaction_t.
  *
- * Called under j_list_lock.  The journal may not be locked.
+ * Called under j_list_sem.  The journal may not be locked.
  */
 void __journal_unfile_buffer(struct journal_head *jh)
 {
@@ -1476,8 +1476,6 @@ void __journal_unfile_buffer(struct jour
 
 	J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
 	transaction = jh->b_transaction;
-	if (transaction)
-		assert_spin_locked(&transaction->t_journal->j_list_lock);
 
 	J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
 	if (jh->b_jlist != BJ_None)
@@ -1525,9 +1523,9 @@ out:
 void journal_unfile_buffer(journal_t *journal, struct journal_head *jh)
 {
 	jbd_lock_bh_state(jh2bh(jh));
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	__journal_unfile_buffer(jh);
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	jbd_unlock_bh_state(jh2bh(jh));
 }
 
@@ -1549,7 +1547,7 @@ __journal_try_to_free_buffer(journal_t *
 	if (jh->b_next_transaction != 0)
 		goto out;
 
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) {
 		if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) {
 			/* A written-back ordered data buffer */
@@ -1567,7 +1565,7 @@ __journal_try_to_free_buffer(journal_t *
 			__brelse(bh);
 		}
 	}
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 out:
 	return;
 }
@@ -1650,7 +1648,7 @@ busy:
  * release it.
  * Returns non-zero if JBD no longer has an interest in the buffer.
  *
- * Called under j_list_lock.
+ * Called under j_list_sem.
  *
  * Called under jbd_lock_bh_state(bh).
  */
@@ -1731,7 +1729,7 @@ static int journal_unmap_buffer(journal_
 	BUFFER_TRACE(bh, "entry");
 
 	/*
-	 * It is safe to proceed here without the j_list_lock because the
+	 * It is safe to proceed here without the j_list_sem because the
 	 * buffers cannot be stolen by try_to_free_buffers as long as we are
 	 * holding the page lock. --sct
 	 */
@@ -1741,7 +1739,7 @@ static int journal_unmap_buffer(journal_
 
 	down(&journal->j_state_sem);
 	jbd_lock_bh_state(bh);
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 
 	jh = journal_grab_journal_head(bh);
 	if (!jh)
@@ -1774,7 +1772,7 @@ static int journal_unmap_buffer(journal_
 			JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget");
 			ret = __dispose_buffer(jh,
 					journal->j_running_transaction);
-			spin_unlock(&journal->j_list_lock);
+			up(&journal->j_list_sem);
 			jbd_unlock_bh_state(bh);
 			up(&journal->j_state_sem);
 			journal_put_journal_head(jh);
@@ -1788,7 +1786,7 @@ static int journal_unmap_buffer(journal_
 				JBUFFER_TRACE(jh, "give to committing trans");
 				ret = __dispose_buffer(jh,
 					journal->j_committing_transaction);
-				spin_unlock(&journal->j_list_lock);
+				up(&journal->j_list_sem);
 				jbd_unlock_bh_state(bh);
 				up(&journal->j_state_sem);
 				journal_put_journal_head(jh);
@@ -1812,7 +1810,7 @@ static int journal_unmap_buffer(journal_
 					journal->j_running_transaction);
 			jh->b_next_transaction = NULL;
 		}
-		spin_unlock(&journal->j_list_lock);
+		up(&journal->j_list_sem);
 		jbd_unlock_bh_state(bh);
 		up(&journal->j_state_sem);
 		journal_put_journal_head(jh);
@@ -1831,7 +1829,7 @@ static int journal_unmap_buffer(journal_
 zap_buffer:
 	journal_put_journal_head(jh);
 zap_buffer_no_jh:
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	jbd_unlock_bh_state(bh);
 	up(&journal->j_state_sem);
 zap_buffer_unlocked:
@@ -1907,8 +1905,6 @@ void __journal_file_buffer(struct journa
 	struct buffer_head *bh = jh2bh(jh);
 
 	J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
-	assert_spin_locked(&transaction->t_journal->j_list_lock);
-
 	J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
 	J_ASSERT_JH(jh, jh->b_transaction == transaction ||
 				jh->b_transaction == 0);
@@ -1974,9 +1970,9 @@ void journal_file_buffer(struct journal_
 				transaction_t *transaction, int jlist)
 {
 	jbd_lock_bh_state(jh2bh(jh));
-	spin_lock(&transaction->t_journal->j_list_lock);
+	down(&transaction->t_journal->j_list_sem);
 	__journal_file_buffer(jh, transaction, jlist);
-	spin_unlock(&transaction->t_journal->j_list_lock);
+	up(&transaction->t_journal->j_list_sem);
 	jbd_unlock_bh_state(jh2bh(jh));
 }
 
@@ -1986,7 +1982,7 @@ void journal_file_buffer(struct journal_
  * already started to be used by a subsequent transaction, refile the
  * buffer on that transaction's metadata list.
  *
- * Called under journal->j_list_lock
+ * Called under journal->j_list_sem
  *
  * Called under jbd_lock_bh_state(jh2bh(jh))
  */
@@ -1996,8 +1992,6 @@ void __journal_refile_buffer(struct jour
 	struct buffer_head *bh = jh2bh(jh);
 
 	J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
-	if (jh->b_transaction)
-		assert_spin_locked(&jh->b_transaction->t_journal->j_list_lock);
 
 	/* If the buffer is now unused, just drop it. */
 	if (jh->b_next_transaction == NULL) {
@@ -2040,12 +2034,12 @@ void journal_refile_buffer(journal_t *jo
 	struct buffer_head *bh = jh2bh(jh);
 
 	jbd_lock_bh_state(bh);
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 
 	__journal_refile_buffer(jh);
 	jbd_unlock_bh_state(bh);
 	journal_remove_journal_head(bh);
 
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	__brelse(bh);
 }
--- linux/fs/jbd/commit.c.orig
+++ linux/fs/jbd/commit.c
@@ -79,14 +79,14 @@ nope:
 }
 
 /*
- * Try to acquire jbd_lock_bh_state() against the buffer, when j_list_lock is
+ * Try to acquire jbd_lock_bh_state() against the buffer, when j_list_sem is
  * held.  For ranking reasons we must trylock.  If we lose, schedule away and
- * return 0.  j_list_lock is dropped in this case.
+ * return 0.  j_list_sem is dropped in this case.
  */
 static int inverted_lock(journal_t *journal, struct buffer_head *bh)
 {
 	if (!jbd_trylock_bh_state(bh)) {
-		spin_unlock(&journal->j_list_lock);
+		up(&journal->j_list_sem);
 		schedule();
 		return 0;
 	}
@@ -189,9 +189,9 @@ void journal_commit_transaction(journal_
 	 */
 
 #ifdef COMMIT_STATS
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	summarise_journal_usage(journal);
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 #endif
 
 	/* Do we need to erase the effects of a prior journal_flush? */
@@ -275,9 +275,9 @@ void journal_commit_transaction(journal_
 	 * checkpoint lists.  We do this *before* commit because it potentially
 	 * frees some memory
 	 */
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	__journal_clean_checkpoint_list(journal);
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 
 	jbd_debug (3, "JBD: commit phase 1\n");
 
@@ -299,7 +299,7 @@ void journal_commit_transaction(journal_
 	 * First, drop modified flag: all accesses to the buffers
 	 * will be tracked for a new trasaction only -bzzz
 	 */
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	if (commit_transaction->t_buffers) {
 		new_jh = jh = commit_transaction->t_buffers->b_tnext;
 		do {
@@ -309,7 +309,7 @@ void journal_commit_transaction(journal_
 			new_jh = new_jh->b_tnext;
 		} while (new_jh != jh);
 	}
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 
 	/*
 	 * Now start flushing things to disk, in the order they appear
@@ -329,7 +329,7 @@ void journal_commit_transaction(journal_
 	 */
 write_out_data:
 	cond_resched();
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 
 	while (commit_transaction->t_sync_datalist) {
 		struct buffer_head *bh;
@@ -345,10 +345,6 @@ write_out_data:
 			__journal_file_buffer(jh, commit_transaction,
 						BJ_Locked);
 			jbd_unlock_bh_state(bh);
-			if (lock_need_resched(&journal->j_list_lock)) {
-				spin_unlock(&journal->j_list_lock);
-				goto write_out_data;
-			}
 		} else {
 			if (buffer_dirty(bh)) {
 				BUFFER_TRACE(bh, "start journal writeout");
@@ -357,7 +353,7 @@ write_out_data:
 				if (bufs == journal->j_wbufsize) {
 					jbd_debug(2, "submit %d writes\n",
 							bufs);
-					spin_unlock(&journal->j_list_lock);
+					up(&journal->j_list_sem);
 					ll_rw_block(WRITE, bufs, wbuf);
 					journal_brelse_array(wbuf, bufs);
 					bufs = 0;
@@ -371,19 +367,15 @@ write_out_data:
 				jbd_unlock_bh_state(bh);
 				journal_remove_journal_head(bh);
 				put_bh(bh);
-				if (lock_need_resched(&journal->j_list_lock)) {
-					spin_unlock(&journal->j_list_lock);
-					goto write_out_data;
-				}
 			}
 		}
 	}
 
 	if (bufs) {
-		spin_unlock(&journal->j_list_lock);
+		up(&journal->j_list_sem);
 		ll_rw_block(WRITE, bufs, wbuf);
 		journal_brelse_array(wbuf, bufs);
-		spin_lock(&journal->j_list_lock);
+		down(&journal->j_list_sem);
 	}
 
 	/*
@@ -396,15 +388,15 @@ write_out_data:
 		bh = jh2bh(jh);
 		get_bh(bh);
 		if (buffer_locked(bh)) {
-			spin_unlock(&journal->j_list_lock);
+			up(&journal->j_list_sem);
 			wait_on_buffer(bh);
 			if (unlikely(!buffer_uptodate(bh)))
 				err = -EIO;
-			spin_lock(&journal->j_list_lock);
+			down(&journal->j_list_sem);
 		}
 		if (!inverted_lock(journal, bh)) {
 			put_bh(bh);
-			spin_lock(&journal->j_list_lock);
+			down(&journal->j_list_sem);
 			continue;
 		}
 		if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) {
@@ -416,9 +408,8 @@ write_out_data:
 			jbd_unlock_bh_state(bh);
 		}
 		put_bh(bh);
-		cond_resched_lock(&journal->j_list_lock);
 	}
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 
 	if (err)
 		__journal_abort_hard(journal);
@@ -614,7 +605,7 @@ start_journal_io:
 	jbd_debug(3, "JBD: commit phase 4\n");
 
 	/*
-	 * akpm: these are BJ_IO, and j_list_lock is not needed.
+	 * akpm: these are BJ_IO, and j_list_sem is not needed.
 	 * See __journal_try_to_free_buffer.
 	 */
 wait_for_iobuf:
@@ -752,7 +743,7 @@ restart_loop:
 			jh->b_frozen_data = NULL;
 		}
 
-		spin_lock(&journal->j_list_lock);
+		down(&journal->j_list_sem);
 		cp_transaction = jh->b_cp_transaction;
 		if (cp_transaction) {
 			JBUFFER_TRACE(jh, "remove from old cp transaction");
@@ -792,7 +783,7 @@ restart_loop:
 			journal_remove_journal_head(bh);  /* needs a brelse */
 			release_buffer_page(bh);
 		}
-		spin_unlock(&journal->j_list_lock);
+		up(&journal->j_list_sem);
 		if (cond_resched())
 			goto restart_loop;
 	}
@@ -804,13 +795,13 @@ restart_loop:
 	J_ASSERT(commit_transaction->t_state == T_COMMIT);
 
 	/*
-	 * This is a bit sleazy.  We borrow j_list_lock to protect
+	 * This is a bit sleazy.  We borrow j_list_sem to protect
 	 * journal->j_committing_transaction in __journal_remove_checkpoint.
 	 * Really, __jornal_remove_checkpoint should be using j_state_sem but
 	 * it's a bit hassle to hold that across __journal_remove_checkpoint
 	 */
 	down(&journal->j_state_sem);
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	commit_transaction->t_state = T_FINISHED;
 	J_ASSERT(commit_transaction == journal->j_committing_transaction);
 	journal->j_commit_sequence = commit_transaction->t_tid;
@@ -835,7 +826,7 @@ restart_loop:
 				commit_transaction;
 		}
 	}
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 
 	jbd_debug(1, "JBD: commit %d complete, head %d\n",
 		  journal->j_commit_sequence, journal->j_tail_sequence);
--- linux/fs/jbd/journal.c.orig
+++ linux/fs/jbd/journal.c
@@ -672,7 +672,7 @@ static journal_t * journal_init_common (
 	init_MUTEX(&journal->j_barrier);
 	init_MUTEX(&journal->j_checkpoint_sem);
 	spin_lock_init(&journal->j_revoke_lock);
-	spin_lock_init(&journal->j_list_lock);
+	init_MUTEX(&journal->j_list_sem);
 	init_MUTEX(&journal->j_state_sem);
 
 	journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE);
@@ -1139,17 +1139,17 @@ void journal_destroy(journal_t *journal)
 	/* Force any old transactions to disk */
 
 	/* Totally anal locking here... */
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	while (journal->j_checkpoint_transactions != NULL) {
-		spin_unlock(&journal->j_list_lock);
+		up(&journal->j_list_sem);
 		log_do_checkpoint(journal);
-		spin_lock(&journal->j_list_lock);
+		down(&journal->j_list_sem);
 	}
 
 	J_ASSERT(journal->j_running_transaction == NULL);
 	J_ASSERT(journal->j_committing_transaction == NULL);
 	J_ASSERT(journal->j_checkpoint_transactions == NULL);
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 
 	/* We can now mark the journal as empty. */
 	journal->j_tail = 0;
@@ -1361,13 +1361,13 @@ int journal_flush(journal_t *journal)
 	}
 
 	/* ...and flush everything in the log out to disk. */
-	spin_lock(&journal->j_list_lock);
+	down(&journal->j_list_sem);
 	while (!err && journal->j_checkpoint_transactions != NULL) {
-		spin_unlock(&journal->j_list_lock);
+		up(&journal->j_list_sem);
 		err = log_do_checkpoint(journal);
-		spin_lock(&journal->j_list_lock);
+		down(&journal->j_list_sem);
 	}
-	spin_unlock(&journal->j_list_lock);
+	up(&journal->j_list_sem);
 	cleanup_journal_tail(journal);
 
 	/* Finally, mark the journal as really needing no recovery.
--- linux/include/linux/jbd.h.orig
+++ linux/include/linux/jbd.h
@@ -413,20 +413,20 @@ struct handle_s 
 /*
  * Lock ranking:
  *
- *    j_list_lock
+ *    j_list_sem
  *      ->jbd_lock_bh_journal_head()	(This is "innermost")
  *
  *    j_state_sem
  *    ->jbd_lock_bh_state()
  *
  *    jbd_lock_bh_state()
- *    ->j_list_lock
+ *    ->j_list_sem
  *
  *    j_state_sem
  *    ->t_handle_lock
  *
  *    j_state_sem
- *    ->j_list_lock			(journal_unmap_buffer)
+ *    ->j_list_sem			(journal_unmap_buffer)
  *
  */
 
@@ -458,62 +458,62 @@ struct transaction_s 
 	 */
 	unsigned long		t_log_start;
 
-	/* Number of buffers on the t_buffers list [j_list_lock] */
+	/* Number of buffers on the t_buffers list [j_list_sem] */
 	int			t_nr_buffers;
 
 	/*
 	 * Doubly-linked circular list of all buffers reserved but not yet
-	 * modified by this transaction [j_list_lock]
+	 * modified by this transaction [j_list_sem]
 	 */
 	struct journal_head	*t_reserved_list;
 
 	/*
 	 * Doubly-linked circular list of all buffers under writeout during
-	 * commit [j_list_lock]
+	 * commit [j_list_sem]
 	 */
 	struct journal_head	*t_locked_list;
 
 	/*
 	 * Doubly-linked circular list of all metadata buffers owned by this
-	 * transaction [j_list_lock]
+	 * transaction [j_list_sem]
 	 */
 	struct journal_head	*t_buffers;
 
 	/*
 	 * Doubly-linked circular list of all data buffers still to be
-	 * flushed before this transaction can be committed [j_list_lock]
+	 * flushed before this transaction can be committed [j_list_sem]
 	 */
 	struct journal_head	*t_sync_datalist;
 
 	/*
 	 * Doubly-linked circular list of all forget buffers (superseded
 	 * buffers which we can un-checkpoint once this transaction commits)
-	 * [j_list_lock]
+	 * [j_list_sem]
 	 */
 	struct journal_head	*t_forget;
 
 	/*
 	 * Doubly-linked circular list of all buffers still to be flushed before
-	 * this transaction can be checkpointed. [j_list_lock]
+	 * this transaction can be checkpointed. [j_list_sem]
 	 */
 	struct journal_head	*t_checkpoint_list;
 
 	/*
 	 * Doubly-linked circular list of temporary buffers currently undergoing
-	 * IO in the log [j_list_lock]
+	 * IO in the log [j_list_sem]
 	 */
 	struct journal_head	*t_iobuf_list;
 
 	/*
 	 * Doubly-linked circular list of metadata buffers being shadowed by log
 	 * IO.  The IO buffers on the iobuf list and the shadow buffers on this
-	 * list match each other one for one at all times. [j_list_lock]
+	 * list match each other one for one at all times. [j_list_sem]
 	 */
 	struct journal_head	*t_shadow_list;
 
 	/*
 	 * Doubly-linked circular list of control buffers being written to the
-	 * log. [j_list_lock]
+	 * log. [j_list_sem]
 	 */
 	struct journal_head	*t_log_list;
 
@@ -536,7 +536,7 @@ struct transaction_s 
 
 	/*
 	 * Forward and backward links for the circular list of all transactions
-	 * awaiting checkpoint. [j_list_lock]
+	 * awaiting checkpoint. [j_list_sem]
 	 */
 	transaction_t		*t_cpnext, *t_cpprev;
 
@@ -590,7 +590,7 @@ struct transaction_s 
  * @j_fs_dev: Device which holds the client fs.  For internal journal this will
  *     be equal to j_dev
  * @j_maxlen: Total maximum capacity of the journal region on disk.
- * @j_list_lock: Protects the buffer lists and internal buffer state.
+ * @j_list_sem: Protects the buffer lists and internal buffer state.
  * @j_inode: Optional inode where we store the journal.  If present, all journal
  *     block numbers are mapped into this inode via bmap().
  * @j_tail_sequence:  Sequence number of the oldest transaction in the log 
@@ -658,7 +658,7 @@ struct journal_s
 
 	/*
 	 * ... and a linked circular list of all transactions waiting for
-	 * checkpointing. [j_list_lock]
+	 * checkpointing. [j_list_sem]
 	 */
 	transaction_t		*j_checkpoint_transactions;
 
@@ -731,7 +731,7 @@ struct journal_s
 	/*
 	 * Protects the buffer lists and internal buffer state.
 	 */
-	spinlock_t		j_list_lock;
+	struct semaphore	j_list_sem;
 
 	/* Optional inode where we store the journal.  If present, all */
 	/* journal block numbers are mapped into this inode via */
--- linux/include/linux/journal-head.h.orig
+++ linux/include/linux/journal-head.h
@@ -56,7 +56,7 @@ struct journal_head {
 	 * metadata: either the running transaction or the committing
 	 * transaction (if there is one).  Only applies to buffers on a
 	 * transaction's data or metadata journaling list.
-	 * [j_list_lock] [jbd_lock_bh_state()]
+	 * [j_list_sem] [jbd_lock_bh_state()]
 	 */
 	transaction_t *b_transaction;
 
@@ -77,14 +77,14 @@ struct journal_head {
 	/*
 	 * Pointer to the compound transaction against which this buffer
 	 * is checkpointed.  Only dirty buffers can be checkpointed.
-	 * [j_list_lock]
+	 * [j_list_sem]
 	 */
 	transaction_t *b_cp_transaction;
 
 	/*
 	 * Doubly-linked list of buffers still remaining to be flushed
 	 * before an old transaction can be checkpointed.
-	 * [j_list_lock]
+	 * [j_list_sem]
 	 */
 	struct journal_head *b_cpnext, *b_cpprev;
 };
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 14:11    [from the cache]
©2003-2008