Provide the designed locking around the transaction's t_jcb callback list. It turns out that this is wholly redundant at present. 25-akpm/fs/jbd/commit.c | 9 ++++++++- 25-akpm/fs/jbd/transaction.c | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff -puN fs/jbd/commit.c~jbd-140-t_jcb-locking fs/jbd/commit.c --- 25/fs/jbd/commit.c~jbd-140-t_jcb-locking Thu Jun 5 15:14:23 2003 +++ 25-akpm/fs/jbd/commit.c Thu Jun 5 15:14:23 2003 @@ -607,10 +607,14 @@ skip_commit: /* The journal should be un unlock_journal(journal); } - /* Call any callbacks that had been registered for handles in this + /* + * Call any callbacks that had been registered for handles in this * transaction. It is up to the callback to free any allocated * memory. + * + * The spinlocking (t_jcb_lock) here is surely unnecessary... */ + spin_lock(&commit_transaction->t_jcb_lock); if (!list_empty(&commit_transaction->t_jcb)) { struct list_head *p, *n; int error = is_journal_aborted(journal); @@ -620,9 +624,12 @@ skip_commit: /* The journal should be un jcb = list_entry(p, struct journal_callback, jcb_list); list_del(p); + spin_unlock(&commit_transaction->t_jcb_lock); jcb->jcb_func(jcb, error); + spin_lock(&commit_transaction->t_jcb_lock); } } + spin_unlock(&commit_transaction->t_jcb_lock); lock_journal(journal); diff -puN fs/jbd/transaction.c~jbd-140-t_jcb-locking fs/jbd/transaction.c --- 25/fs/jbd/transaction.c~jbd-140-t_jcb-locking Thu Jun 5 15:14:23 2003 +++ 25-akpm/fs/jbd/transaction.c Thu Jun 5 15:14:23 2003 @@ -41,15 +41,15 @@ * processes trying to touch the journal while it is in transition. */ -static transaction_t * get_transaction (journal_t * journal, int is_try) +static transaction_t *get_transaction(journal_t *journal) { transaction_t * transaction; - transaction = jbd_kmalloc (sizeof (transaction_t), GFP_NOFS); + transaction = jbd_kmalloc(sizeof(*transaction), GFP_NOFS); if (!transaction) return NULL; - memset (transaction, 0, sizeof (transaction_t)); + memset(transaction, 0, sizeof(*transaction)); transaction->t_journal = journal; transaction->t_state = T_RUNNING; @@ -120,7 +120,7 @@ repeat: repeat_locked: if (!journal->j_running_transaction) - get_transaction(journal, 0); + get_transaction(journal); /* @@@ Error? */ J_ASSERT(journal->j_running_transaction); @@ -1277,16 +1277,15 @@ not_jbd: * and has the caller-specific data afterwards. */ void journal_callback_set(handle_t *handle, - void (*func)(struct journal_callback *jcb, int error), - struct journal_callback *jcb) + void (*func)(struct journal_callback *jcb, int error), + struct journal_callback *jcb) { - lock_kernel(); + spin_lock(&handle->h_transaction->t_jcb_lock); list_add_tail(&jcb->jcb_list, &handle->h_jcb); + spin_unlock(&handle->h_transaction->t_jcb_lock); jcb->jcb_func = func; - unlock_kernel(); } - /** * int journal_stop() - complete a transaction * @handle: tranaction to complete. @@ -1357,7 +1356,9 @@ int journal_stop(handle_t *handle) } /* Move callbacks from the handle to the transaction. */ + spin_lock(&transaction->t_jcb_lock); list_splice(&handle->h_jcb, &transaction->t_jcb); + spin_unlock(&transaction->t_jcb_lock); /* * If the handle is marked SYNC, we need to set another commit _