Reduce the locking coverage of the oft-used j_list_lock: the per-bh jbd_lock_bh_state() gives us sufficient locking of buffer_head and journal_head internals. --- 25-akpm/fs/jbd/transaction.c | 13 +++---------- 1 files changed, 3 insertions(+), 10 deletions(-) diff -puN fs/jbd/transaction.c~jbd-journal_dirty_metadata-locking-speedup fs/jbd/transaction.c --- 25/fs/jbd/transaction.c~jbd-journal_dirty_metadata-locking-speedup Thu Apr 8 14:43:29 2004 +++ 25-akpm/fs/jbd/transaction.c Thu Apr 8 14:45:28 2004 @@ -1088,26 +1088,21 @@ int journal_dirty_metadata(handle_t *han * I _think_ we're OK here with SMP barriers - a mistaken decision will * result in this test being false, so we go in and take the locks. */ - if (jh->b_transaction == handle->h_transaction && - jh->b_jlist == BJ_Metadata) { + if (jh->b_transaction == transaction && jh->b_jlist == BJ_Metadata) { JBUFFER_TRACE(jh, "fastpath"); J_ASSERT_JH(jh, jh->b_transaction == journal->j_running_transaction); goto out_unlock_bh; } - spin_lock(&journal->j_list_lock); set_buffer_jbddirty(bh); - J_ASSERT_JH(jh, jh->b_transaction != NULL); - /* * Metadata already on the current transaction list doesn't * need to be filed. Metadata on another transaction's list must * be committing, and will be refiled once the commit completes: * leave it alone for now. */ - if (jh->b_transaction != transaction) { JBUFFER_TRACE(jh, "already on other transaction"); J_ASSERT_JH(jh, jh->b_transaction == @@ -1115,17 +1110,15 @@ int journal_dirty_metadata(handle_t *han J_ASSERT_JH(jh, jh->b_next_transaction == transaction); /* And this case is illegal: we can't reuse another * transaction's data buffer, ever. */ - /* FIXME: writepage() should be journalled */ - goto out_unlock_list; + goto out_unlock_bh; } /* That test should have eliminated the following case: */ J_ASSERT_JH(jh, jh->b_frozen_data == 0); JBUFFER_TRACE(jh, "file as BJ_Metadata"); + spin_lock(&journal->j_list_lock); __journal_file_buffer(jh, handle->h_transaction, BJ_Metadata); - -out_unlock_list: spin_unlock(&journal->j_list_lock); out_unlock_bh: jbd_unlock_bh_state(bh); _