Implement the designed locking for t_outstanding_credits


 fs/jbd/transaction.c |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

diff -puN fs/jbd/transaction.c~jbd-130-t_outstanding_credits-locking fs/jbd/transaction.c
--- 25/fs/jbd/transaction.c~jbd-130-t_outstanding_credits-locking	2003-05-28 13:02:38.000000000 -0700
+++ 25-akpm/fs/jbd/transaction.c	2003-05-28 13:02:38.000000000 -0700
@@ -136,11 +136,12 @@ repeat_locked:
 		goto repeat;
 	}
 	
-	/* If there is not enough space left in the log to write all
-	 * potential buffers requested by this operation, we need to
-	 * stall pending a log checkpoint to free some more log
-	 * space. */
-
+	/*
+	 * If there is not enough space left in the log to write all potential
+	 * buffers requested by this operation, we need to stall pending a log
+	 * checkpoint to free some more log space.
+	 */
+	spin_lock(&transaction->t_handle_lock);
 	needed = transaction->t_outstanding_credits + nblocks;
 
 	if (needed > journal->j_max_transaction_buffers) {
@@ -148,6 +149,7 @@ repeat_locked:
 		 * start to commit it: we can then go back and attach
 		 * this handle to a new transaction. */
 		
+		spin_unlock(&transaction->t_handle_lock);
 		jbd_debug(2, "Handle %p starting new commit...\n", handle);
 		log_start_commit(journal, transaction);
 		unlock_journal(journal);
@@ -188,6 +190,7 @@ repeat_locked:
 	
 	if (log_space_left(journal) < needed) {
 		jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle);
+		spin_unlock(&transaction->t_handle_lock);
 		log_wait_for_space(journal, needed);
 		goto repeat_locked;
 	}
@@ -196,14 +199,13 @@ repeat_locked:
 	 * use and add the handle to the running transaction. */
 
 	handle->h_transaction = transaction;
-	spin_lock(&transaction->t_handle_lock);
 	transaction->t_outstanding_credits += nblocks;
 	transaction->t_updates++;
 	transaction->t_handle_count++;
-	spin_unlock(&transaction->t_handle_lock);
 	jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n",
 		  handle, nblocks, transaction->t_outstanding_credits,
 		  log_space_left(journal));
+	spin_unlock(&transaction->t_handle_lock);
 
 	unlock_journal(journal);
 	
@@ -289,7 +291,7 @@ handle_t *journal_start(journal_t *journ
  * return code < 0 implies an error
  * return code > 0 implies normal transaction-full status.
  */
-int journal_extend (handle_t *handle, int nblocks)
+int journal_extend(handle_t *handle, int nblocks)
 {
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
@@ -311,7 +313,8 @@ int journal_extend (handle_t *handle, in
 		goto error_out;
 	}
 
-	lock_kernel();	
+	lock_kernel();
+	spin_lock(&transaction->t_handle_lock);
 	wanted = transaction->t_outstanding_credits + nblocks;
 	
 	if (wanted > journal->j_max_transaction_buffers) {
@@ -332,6 +335,7 @@ int journal_extend (handle_t *handle, in
 
 	jbd_debug(3, "extended handle %p by %d\n", handle, nblocks);
 unlock:
+	spin_unlock(&transaction->t_handle_lock);
 	unlock_kernel();
 error_out:
 	unlock_journal (journal);
@@ -1351,7 +1355,6 @@ int journal_stop(handle_t *handle)
 		if (journal->j_barrier_count)
 			wake_up(&journal->j_wait_transaction_locked);
 	}
-	spin_unlock(&transaction->t_handle_lock);
 
 	/* Move callbacks from the handle to the transaction. */
 	list_splice(&handle->h_jcb, &transaction->t_jcb);
@@ -1371,6 +1374,7 @@ int journal_stop(handle_t *handle)
 		 * anything to disk. */
 		tid_t tid = transaction->t_tid;
 		
+		spin_unlock(&transaction->t_handle_lock);
 		jbd_debug(2, "transaction too old, requesting commit for "
 					"handle %p\n", handle);
 		/* This is non-blocking */
@@ -1382,7 +1386,10 @@ int journal_stop(handle_t *handle)
 		 */
 		if (handle->h_sync && !(current->flags & PF_MEMALLOC))
 			err = log_wait_commit(journal, tid);
+	} else {
+		spin_unlock(&transaction->t_handle_lock);
 	}
+
 	unlock_kernel();
 	jbd_free_handle(handle);
 	return err;

_