1 jbd2: add transaction to checkpoint list earlier
3 We don't otherwise need j_list_lock during the rest of commit phase
4 #7, so add the transaction to the checkpoint list at the very end of
5 commit phase #6. This allows us to drop j_list_lock earlier, which is
6 a good thing since it is a super hot lock.
8 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
10 fs/jbd2/commit.c | 39 ++++++++++++++++++++-------------------
11 1 file changed, 20 insertions(+), 19 deletions(-)
13 diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
14 index af36252..5f26139 100644
15 --- a/fs/jbd2/commit.c
16 +++ b/fs/jbd2/commit.c
17 @@ -1065,6 +1065,25 @@ restart_loop:
21 + /* Add the transaction to the checkpoint list
22 + * __journal_remove_checkpoint() can not destroy transaction
23 + * under us because it is not marked as T_FINISHED yet */
24 + if (journal->j_checkpoint_transactions == NULL) {
25 + journal->j_checkpoint_transactions = commit_transaction;
26 + commit_transaction->t_cpnext = commit_transaction;
27 + commit_transaction->t_cpprev = commit_transaction;
29 + commit_transaction->t_cpnext =
30 + journal->j_checkpoint_transactions;
31 + commit_transaction->t_cpprev =
32 + commit_transaction->t_cpnext->t_cpprev;
33 + commit_transaction->t_cpnext->t_cpprev =
35 + commit_transaction->t_cpprev->t_cpnext =
38 + spin_unlock(&journal->j_list_lock);
40 /* Done with this transaction! */
42 jbd_debug(3, "JBD2: commit phase 7\n");
43 @@ -1103,24 +1122,6 @@ restart_loop:
45 write_unlock(&journal->j_state_lock);
47 - if (journal->j_checkpoint_transactions == NULL) {
48 - journal->j_checkpoint_transactions = commit_transaction;
49 - commit_transaction->t_cpnext = commit_transaction;
50 - commit_transaction->t_cpprev = commit_transaction;
52 - commit_transaction->t_cpnext =
53 - journal->j_checkpoint_transactions;
54 - commit_transaction->t_cpprev =
55 - commit_transaction->t_cpnext->t_cpprev;
56 - commit_transaction->t_cpnext->t_cpprev =
58 - commit_transaction->t_cpprev->t_cpnext =
61 - spin_unlock(&journal->j_list_lock);
62 - /* Drop all spin_locks because commit_callback may be block.
63 - * __journal_remove_checkpoint() can not destroy transaction
64 - * under us because it is not marked as T_FINISHED yet */
65 if (journal->j_commit_callback)
66 journal->j_commit_callback(journal, commit_transaction);
68 @@ -1131,7 +1132,7 @@ restart_loop:
69 write_lock(&journal->j_state_lock);
70 spin_lock(&journal->j_list_lock);
71 commit_transaction->t_state = T_FINISHED;
72 - /* Recheck checkpoint lists after j_list_lock was dropped */
73 + /* Check if the transaction can be dropped now that we are finished */
74 if (commit_transaction->t_checkpoint_list == NULL &&
75 commit_transaction->t_checkpoint_io_list == NULL) {
76 __jbd2_journal_drop_transaction(journal, commit_transaction);