put_bh(bh);
}
- if (lock_need_resched(&journal->j_list_lock)) {
+ if (need_resched() || spin_needbreak(&journal->j_list_lock)) {
spin_unlock(&journal->j_list_lock);
goto write_out_data;
}
struct buffer_head *bh = jh2bh(jh);
jbd_lock_bh_state(bh);
- jbd_slab_free(jh->b_committed_data, bh->b_size);
+ jbd_free(jh->b_committed_data, bh->b_size);
jh->b_committed_data = NULL;
jbd_unlock_bh_state(bh);
}
spin_unlock(&journal->j_list_lock);
if (err)
- __journal_abort_hard(journal);
+ journal_abort(journal, err);
journal_write_revoke_records(journal, commit_transaction);
descriptor = journal_get_descriptor_buffer(journal);
if (!descriptor) {
- __journal_abort_hard(journal);
+ journal_abort(journal, -EIO);
continue;
}
and repeat this loop: we'll fall into the
refile-on-abort condition above. */
if (err) {
- __journal_abort_hard(journal);
+ journal_abort(journal, err);
continue;
}
err = -EIO;
if (err)
- __journal_abort_hard(journal);
+ journal_abort(journal, err);
/* End of a transaction! Finally, we can do checkpoint
processing: any buffers committed as a result of this
* Otherwise, we can just throw away the frozen data now.
*/
if (jh->b_committed_data) {
- jbd_slab_free(jh->b_committed_data, bh->b_size);
+ jbd_free(jh->b_committed_data, bh->b_size);
jh->b_committed_data = NULL;
if (jh->b_frozen_data) {
jh->b_committed_data = jh->b_frozen_data;
jh->b_frozen_data = NULL;
}
} else if (jh->b_frozen_data) {
- jbd_slab_free(jh->b_frozen_data, bh->b_size);
+ jbd_free(jh->b_frozen_data, bh->b_size);
jh->b_frozen_data = NULL;
}
}
spin_unlock(&journal->j_list_lock);
/*
- * This is a bit sleazy. We borrow j_list_lock to protect
- * journal->j_committing_transaction in __journal_remove_checkpoint.
- * Really, __journal_remove_checkpoint should be using j_state_lock but
- * it's a bit hassle to hold that across __journal_remove_checkpoint
+ * This is a bit sleazy. We use j_list_lock to protect transition
+ * of a transaction into T_FINISHED state and calling
+ * __journal_drop_transaction(). Otherwise we could race with
+ * other checkpointing code processing the transaction...
*/
spin_lock(&journal->j_state_lock);
spin_lock(&journal->j_list_lock);
journal->j_committing_transaction = NULL;
spin_unlock(&journal->j_state_lock);
- if (commit_transaction->t_checkpoint_list == NULL) {
+ if (commit_transaction->t_checkpoint_list == NULL &&
+ commit_transaction->t_checkpoint_io_list == NULL) {
__journal_drop_transaction(journal, commit_transaction);
} else {
if (journal->j_checkpoint_transactions == NULL) {