summaryrefslogtreecommitdiffstats
path: root/fs/jbd2/commit.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r--fs/jbd2/commit.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 750c70148eff..0f53946f13c1 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -382,7 +382,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
382 int space_left = 0; 382 int space_left = 0;
383 int first_tag = 0; 383 int first_tag = 0;
384 int tag_flag; 384 int tag_flag;
385 int i, to_free = 0; 385 int i;
386 int tag_bytes = journal_tag_bytes(journal); 386 int tag_bytes = journal_tag_bytes(journal);
387 struct buffer_head *cbh = NULL; /* For transactional checksums */ 387 struct buffer_head *cbh = NULL; /* For transactional checksums */
388 __u32 crc32_sum = ~0; 388 __u32 crc32_sum = ~0;
@@ -1134,7 +1134,7 @@ restart_loop:
1134 journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged; 1134 journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged;
1135 spin_unlock(&journal->j_history_lock); 1135 spin_unlock(&journal->j_history_lock);
1136 1136
1137 commit_transaction->t_state = T_FINISHED; 1137 commit_transaction->t_state = T_COMMIT_CALLBACK;
1138 J_ASSERT(commit_transaction == journal->j_committing_transaction); 1138 J_ASSERT(commit_transaction == journal->j_committing_transaction);
1139 journal->j_commit_sequence = commit_transaction->t_tid; 1139 journal->j_commit_sequence = commit_transaction->t_tid;
1140 journal->j_committing_transaction = NULL; 1140 journal->j_committing_transaction = NULL;
@@ -1149,38 +1149,44 @@ restart_loop:
1149 journal->j_average_commit_time*3) / 4; 1149 journal->j_average_commit_time*3) / 4;
1150 else 1150 else
1151 journal->j_average_commit_time = commit_time; 1151 journal->j_average_commit_time = commit_time;
1152
1152 write_unlock(&journal->j_state_lock); 1153 write_unlock(&journal->j_state_lock);
1153 1154
1154 if (commit_transaction->t_checkpoint_list == NULL && 1155 if (journal->j_checkpoint_transactions == NULL) {
1155 commit_transaction->t_checkpoint_io_list == NULL) { 1156 journal->j_checkpoint_transactions = commit_transaction;
1156 __jbd2_journal_drop_transaction(journal, commit_transaction); 1157 commit_transaction->t_cpnext = commit_transaction;
1157 to_free = 1; 1158 commit_transaction->t_cpprev = commit_transaction;
1158 } else { 1159 } else {
1159 if (journal->j_checkpoint_transactions == NULL) { 1160 commit_transaction->t_cpnext =
1160 journal->j_checkpoint_transactions = commit_transaction; 1161 journal->j_checkpoint_transactions;
1161 commit_transaction->t_cpnext = commit_transaction; 1162 commit_transaction->t_cpprev =
1162 commit_transaction->t_cpprev = commit_transaction; 1163 commit_transaction->t_cpnext->t_cpprev;
1163 } else { 1164 commit_transaction->t_cpnext->t_cpprev =
1164 commit_transaction->t_cpnext = 1165 commit_transaction;
1165 journal->j_checkpoint_transactions; 1166 commit_transaction->t_cpprev->t_cpnext =
1166 commit_transaction->t_cpprev =
1167 commit_transaction->t_cpnext->t_cpprev;
1168 commit_transaction->t_cpnext->t_cpprev =
1169 commit_transaction;
1170 commit_transaction->t_cpprev->t_cpnext =
1171 commit_transaction; 1167 commit_transaction;
1172 }
1173 } 1168 }
1174 spin_unlock(&journal->j_list_lock); 1169 spin_unlock(&journal->j_list_lock);
1175 1170 /* Drop all spin_locks because commit_callback may be block.
1171 * __journal_remove_checkpoint() can not destroy transaction
1172 * under us because it is not marked as T_FINISHED yet */
1176 if (journal->j_commit_callback) 1173 if (journal->j_commit_callback)
1177 journal->j_commit_callback(journal, commit_transaction); 1174 journal->j_commit_callback(journal, commit_transaction);
1178 1175
1179 trace_jbd2_end_commit(journal, commit_transaction); 1176 trace_jbd2_end_commit(journal, commit_transaction);
1180 jbd_debug(1, "JBD2: commit %d complete, head %d\n", 1177 jbd_debug(1, "JBD2: commit %d complete, head %d\n",
1181 journal->j_commit_sequence, journal->j_tail_sequence); 1178 journal->j_commit_sequence, journal->j_tail_sequence);
1182 if (to_free)
1183 jbd2_journal_free_transaction(commit_transaction);
1184 1179
1180 write_lock(&journal->j_state_lock);
1181 spin_lock(&journal->j_list_lock);
1182 commit_transaction->t_state = T_FINISHED;
1183 /* Recheck checkpoint lists after j_list_lock was dropped */
1184 if (commit_transaction->t_checkpoint_list == NULL &&
1185 commit_transaction->t_checkpoint_io_list == NULL) {
1186 __jbd2_journal_drop_transaction(journal, commit_transaction);
1187 jbd2_journal_free_transaction(commit_transaction);
1188 }
1189 spin_unlock(&journal->j_list_lock);
1190 write_unlock(&journal->j_state_lock);
1185 wake_up(&journal->j_wait_done_commit); 1191 wake_up(&journal->j_wait_done_commit);
1186} 1192}