20 #include <linux/time.h>
23 #include <linux/errno.h>
24 #include <linux/slab.h>
33 static inline void __buffer_unlink_first(
struct journal_head *jh)
39 if (transaction->t_checkpoint_list == jh) {
40 transaction->t_checkpoint_list = jh->
b_cpnext;
41 if (transaction->t_checkpoint_list == jh)
42 transaction->t_checkpoint_list =
NULL;
51 static inline void __buffer_unlink(
struct journal_head *jh)
55 __buffer_unlink_first(jh);
56 if (transaction->t_checkpoint_io_list == jh) {
57 transaction->t_checkpoint_io_list = jh->
b_cpnext;
58 if (transaction->t_checkpoint_io_list == jh)
59 transaction->t_checkpoint_io_list =
NULL;
68 static inline void __buffer_relink_io(
struct journal_head *jh)
72 __buffer_unlink_first(jh);
74 if (!transaction->t_checkpoint_io_list) {
77 jh->
b_cpnext = transaction->t_checkpoint_io_list;
78 jh->
b_cpprev = transaction->t_checkpoint_io_list->b_cpprev;
82 transaction->t_checkpoint_io_list = jh;
96 struct buffer_head *bh = jh2bh(jh);
99 !buffer_dirty(bh) && !buffer_write_io_error(bh)) {
105 JBUFFER_TRACE(jh,
"remove from checkpoint list");
107 jbd_unlock_bh_state(bh);
108 BUFFER_TRACE(bh,
"release");
111 jbd_unlock_bh_state(bh);
124 int nblocks, space_left;
127 nblocks = jbd_space_needed(journal);
129 if (journal->j_flags & JFS_ABORT)
131 spin_unlock(&journal->j_state_lock);
145 spin_lock(&journal->j_state_lock);
146 spin_lock(&journal->j_list_lock);
147 nblocks = jbd_space_needed(journal);
149 if (space_left < nblocks) {
150 int chkpt = journal->j_checkpoint_transactions !=
NULL;
153 if (journal->j_committing_transaction)
154 tid = journal->j_committing_transaction->t_tid;
155 spin_unlock(&journal->j_list_lock);
156 spin_unlock(&journal->j_state_lock);
166 "only had %d space available\n",
167 __func__, nblocks, space_left);
169 "journal space\n", __func__);
173 spin_lock(&journal->j_state_lock);
175 spin_unlock(&journal->j_list_lock);
186 static void jbd_sync_bh(journal_t *journal,
struct buffer_head *bh)
190 spin_unlock(&journal->j_list_lock);
191 jbd_lock_bh_state(bh);
192 jbd_unlock_bh_state(bh);
207 static int __wait_cp_io(journal_t *journal,
transaction_t *transaction)
210 struct buffer_head *bh;
215 this_tid = transaction->t_tid;
218 if (journal->j_checkpoint_transactions != transaction ||
219 transaction->t_tid != this_tid)
221 while (!released && transaction->t_checkpoint_io_list) {
222 jh = transaction->t_checkpoint_io_list;
224 if (!jbd_trylock_bh_state(bh)) {
225 jbd_sync_bh(journal, bh);
226 spin_lock(&journal->j_list_lock);
230 if (buffer_locked(bh)) {
231 spin_unlock(&journal->j_list_lock);
232 jbd_unlock_bh_state(bh);
235 BUFFER_TRACE(bh,
"brelse");
237 spin_lock(&journal->j_list_lock);
240 if (
unlikely(buffer_write_io_error(bh)))
248 jbd_unlock_bh_state(bh);
258 __flush_batch(journal_t *journal,
struct buffer_head **bhs,
int *batch_count)
264 for (i = 0; i < *batch_count; i++)
268 for (i = 0; i < *batch_count; i++) {
269 struct buffer_head *bh = bhs[
i];
270 clear_buffer_jwrite(bh);
271 BUFFER_TRACE(bh,
"brelse");
287 static int __process_buffer(journal_t *journal,
struct journal_head *jh,
288 struct buffer_head **bhs,
int *batch_count)
290 struct buffer_head *bh = jh2bh(jh);
293 if (buffer_locked(bh)) {
295 spin_unlock(&journal->j_list_lock);
296 jbd_unlock_bh_state(bh);
299 BUFFER_TRACE(bh,
"brelse");
306 spin_unlock(&journal->j_list_lock);
307 jbd_unlock_bh_state(bh);
311 }
else if (!buffer_dirty(bh)) {
313 if (
unlikely(buffer_write_io_error(bh)))
316 J_ASSERT_JH(jh, !buffer_jbddirty(bh));
317 BUFFER_TRACE(bh,
"remove from checkpoint");
319 spin_unlock(&journal->j_list_lock);
320 jbd_unlock_bh_state(bh);
330 BUFFER_TRACE(bh,
"queue");
332 J_ASSERT_BH(bh, !buffer_jwrite(bh));
333 set_buffer_jwrite(bh);
334 bhs[*batch_count] = bh;
335 __buffer_relink_io(jh);
336 jbd_unlock_bh_state(bh);
339 spin_unlock(&journal->j_list_lock);
340 __flush_batch(journal, bhs, batch_count);
369 trace_jbd_checkpoint(journal, result);
370 jbd_debug(1,
"cleanup_journal_tail returned %d\n", result);
379 spin_lock(&journal->j_list_lock);
380 if (!journal->j_checkpoint_transactions)
382 transaction = journal->j_checkpoint_transactions;
383 this_tid = transaction->t_tid;
390 if (journal->j_checkpoint_transactions == transaction &&
391 transaction->t_tid == this_tid) {
397 while (!retry && transaction->t_checkpoint_list) {
398 struct buffer_head *bh;
400 jh = transaction->t_checkpoint_list;
402 if (!jbd_trylock_bh_state(bh)) {
403 jbd_sync_bh(journal, bh);
407 retry = __process_buffer(journal, jh, bhs,&batch_count);
408 if (retry < 0 && !result)
410 if (!retry && (need_resched() ||
411 spin_needbreak(&journal->j_list_lock))) {
412 spin_unlock(&journal->j_list_lock);
420 spin_unlock(&journal->j_list_lock);
423 __flush_batch(journal, bhs, &batch_count);
427 spin_lock(&journal->j_list_lock);
434 err = __wait_cp_io(journal, transaction);
439 spin_unlock(&journal->j_list_lock);
445 return (result < 0) ? result : 0;
470 if (is_journal_aborted(journal))
481 spin_lock(&journal->j_state_lock);
482 spin_lock(&journal->j_list_lock);
483 transaction = journal->j_checkpoint_transactions;
485 first_tid = transaction->t_tid;
486 blocknr = transaction->t_log_start;
487 }
else if ((transaction = journal->j_committing_transaction) !=
NULL) {
488 first_tid = transaction->t_tid;
489 blocknr = transaction->t_log_start;
490 }
else if ((transaction = journal->j_running_transaction) !=
NULL) {
491 first_tid = transaction->t_tid;
492 blocknr = journal->j_head;
494 first_tid = journal->j_transaction_sequence;
495 blocknr = journal->j_head;
497 spin_unlock(&journal->j_list_lock);
498 J_ASSERT(blocknr != 0);
502 if (journal->j_tail_sequence == first_tid) {
503 spin_unlock(&journal->j_state_lock);
506 spin_unlock(&journal->j_state_lock);
523 spin_lock(&journal->j_state_lock);
527 freed = blocknr - journal->j_tail;
528 if (blocknr < journal->j_tail)
529 freed = freed + journal->j_last - journal->j_first;
531 trace_jbd_cleanup_journal_tail(journal, first_tid, blocknr, freed);
533 "Cleaning journal tail from %d to %d (offset %u), "
535 journal->j_tail_sequence, first_tid, blocknr, freed);
537 journal->j_free += freed;
538 journal->j_tail_sequence = first_tid;
540 spin_unlock(&journal->j_state_lock);
557 static int journal_clean_one_cp_list(
struct journal_head *jh,
int *released)
572 if (jbd_trylock_bh_state(jh2bh(jh))) {
573 ret = __try_to_free_cp_buf(jh);
590 }
while (jh != last_jh);
611 transaction = journal->j_checkpoint_transactions;
615 last_transaction = transaction->t_cpprev;
618 transaction = next_transaction;
619 next_transaction = transaction->t_cpnext;
620 ret += journal_clean_one_cp_list(transaction->
621 t_checkpoint_list, &released);
636 ret += journal_clean_one_cp_list(transaction->
637 t_checkpoint_io_list, &released);
640 }
while (transaction != last_transaction);
671 JBUFFER_TRACE(jh,
"entry");
674 JBUFFER_TRACE(jh,
"not on transaction");
677 journal = transaction->t_journal;
679 JBUFFER_TRACE(jh,
"removing from transaction");
684 if (transaction->t_checkpoint_list !=
NULL ||
685 transaction->t_checkpoint_io_list !=
NULL)
697 if (transaction->t_state != T_FINISHED)
707 wake_up(&journal->j_wait_logspace);
724 JBUFFER_TRACE(jh,
"entry");
725 J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh)));
732 if (!transaction->t_checkpoint_list) {
735 jh->
b_cpnext = transaction->t_checkpoint_list;
736 jh->
b_cpprev = transaction->t_checkpoint_list->b_cpprev;
740 transaction->t_checkpoint_list = jh;
756 if (transaction->t_cpnext) {
757 transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
758 transaction->t_cpprev->t_cpnext = transaction->t_cpnext;
759 if (journal->j_checkpoint_transactions == transaction)
760 journal->j_checkpoint_transactions =
761 transaction->t_cpnext;
762 if (journal->j_checkpoint_transactions == transaction)
763 journal->j_checkpoint_transactions =
NULL;
766 J_ASSERT(transaction->t_state == T_FINISHED);
767 J_ASSERT(transaction->t_buffers ==
NULL);
768 J_ASSERT(transaction->t_sync_datalist ==
NULL);
769 J_ASSERT(transaction->t_forget ==
NULL);
770 J_ASSERT(transaction->t_iobuf_list ==
NULL);
771 J_ASSERT(transaction->t_shadow_list ==
NULL);
772 J_ASSERT(transaction->t_log_list ==
NULL);
773 J_ASSERT(transaction->t_checkpoint_list ==
NULL);
774 J_ASSERT(transaction->t_checkpoint_io_list ==
NULL);
775 J_ASSERT(transaction->t_updates == 0);
776 J_ASSERT(journal->j_committing_transaction != transaction);
777 J_ASSERT(journal->j_running_transaction != transaction);
779 trace_jbd_drop_transaction(journal, transaction);
780 jbd_debug(1,
"Dropping transaction %d, all done\n", transaction->t_tid);