aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd/checkpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd/checkpoint.c')
-rw-r--r--fs/jbd/checkpoint.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index e4b87bc1fa5..f94fc48ff3a 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -22,6 +22,8 @@
22#include <linux/jbd.h> 22#include <linux/jbd.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/blkdev.h>
26#include <trace/events/jbd.h>
25 27
26/* 28/*
27 * Unlink a buffer from a transaction checkpoint list. 29 * Unlink a buffer from a transaction checkpoint list.
@@ -95,10 +97,14 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
95 97
96 if (jh->b_jlist == BJ_None && !buffer_locked(bh) && 98 if (jh->b_jlist == BJ_None && !buffer_locked(bh) &&
97 !buffer_dirty(bh) && !buffer_write_io_error(bh)) { 99 !buffer_dirty(bh) && !buffer_write_io_error(bh)) {
100 /*
101 * Get our reference so that bh cannot be freed before
102 * we unlock it
103 */
104 get_bh(bh);
98 JBUFFER_TRACE(jh, "remove from checkpoint list"); 105 JBUFFER_TRACE(jh, "remove from checkpoint list");
99 ret = __journal_remove_checkpoint(jh) + 1; 106 ret = __journal_remove_checkpoint(jh) + 1;
100 jbd_unlock_bh_state(bh); 107 jbd_unlock_bh_state(bh);
101 journal_remove_journal_head(bh);
102 BUFFER_TRACE(bh, "release"); 108 BUFFER_TRACE(bh, "release");
103 __brelse(bh); 109 __brelse(bh);
104 } else { 110 } else {
@@ -220,8 +226,8 @@ restart:
220 spin_lock(&journal->j_list_lock); 226 spin_lock(&journal->j_list_lock);
221 goto restart; 227 goto restart;
222 } 228 }
229 get_bh(bh);
223 if (buffer_locked(bh)) { 230 if (buffer_locked(bh)) {
224 get_bh(bh);
225 spin_unlock(&journal->j_list_lock); 231 spin_unlock(&journal->j_list_lock);
226 jbd_unlock_bh_state(bh); 232 jbd_unlock_bh_state(bh);
227 wait_on_buffer(bh); 233 wait_on_buffer(bh);
@@ -240,7 +246,6 @@ restart:
240 */ 246 */
241 released = __journal_remove_checkpoint(jh); 247 released = __journal_remove_checkpoint(jh);
242 jbd_unlock_bh_state(bh); 248 jbd_unlock_bh_state(bh);
243 journal_remove_journal_head(bh);
244 __brelse(bh); 249 __brelse(bh);
245 } 250 }
246 251
@@ -253,9 +258,12 @@ static void
253__flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count) 258__flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
254{ 259{
255 int i; 260 int i;
261 struct blk_plug plug;
256 262
263 blk_start_plug(&plug);
257 for (i = 0; i < *batch_count; i++) 264 for (i = 0; i < *batch_count; i++)
258 write_dirty_buffer(bhs[i], WRITE); 265 write_dirty_buffer(bhs[i], WRITE_SYNC);
266 blk_finish_plug(&plug);
259 267
260 for (i = 0; i < *batch_count; i++) { 268 for (i = 0; i < *batch_count; i++) {
261 struct buffer_head *bh = bhs[i]; 269 struct buffer_head *bh = bhs[i];
@@ -304,12 +312,12 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
304 ret = 1; 312 ret = 1;
305 if (unlikely(buffer_write_io_error(bh))) 313 if (unlikely(buffer_write_io_error(bh)))
306 ret = -EIO; 314 ret = -EIO;
315 get_bh(bh);
307 J_ASSERT_JH(jh, !buffer_jbddirty(bh)); 316 J_ASSERT_JH(jh, !buffer_jbddirty(bh));
308 BUFFER_TRACE(bh, "remove from checkpoint"); 317 BUFFER_TRACE(bh, "remove from checkpoint");
309 __journal_remove_checkpoint(jh); 318 __journal_remove_checkpoint(jh);
310 spin_unlock(&journal->j_list_lock); 319 spin_unlock(&journal->j_list_lock);
311 jbd_unlock_bh_state(bh); 320 jbd_unlock_bh_state(bh);
312 journal_remove_journal_head(bh);
313 __brelse(bh); 321 __brelse(bh);
314 } else { 322 } else {
315 /* 323 /*
@@ -358,6 +366,7 @@ int log_do_checkpoint(journal_t *journal)
358 * journal straight away. 366 * journal straight away.
359 */ 367 */
360 result = cleanup_journal_tail(journal); 368 result = cleanup_journal_tail(journal);
369 trace_jbd_checkpoint(journal, result);
361 jbd_debug(1, "cleanup_journal_tail returned %d\n", result); 370 jbd_debug(1, "cleanup_journal_tail returned %d\n", result);
362 if (result <= 0) 371 if (result <= 0)
363 return result; 372 return result;
@@ -503,6 +512,7 @@ int cleanup_journal_tail(journal_t *journal)
503 if (blocknr < journal->j_tail) 512 if (blocknr < journal->j_tail)
504 freed = freed + journal->j_last - journal->j_first; 513 freed = freed + journal->j_last - journal->j_first;
505 514
515 trace_jbd_cleanup_journal_tail(journal, first_tid, blocknr, freed);
506 jbd_debug(1, 516 jbd_debug(1,
507 "Cleaning journal tail from %d to %d (offset %u), " 517 "Cleaning journal tail from %d to %d (offset %u), "
508 "freeing %u\n", 518 "freeing %u\n",
@@ -523,9 +533,9 @@ int cleanup_journal_tail(journal_t *journal)
523/* 533/*
524 * journal_clean_one_cp_list 534 * journal_clean_one_cp_list
525 * 535 *
526 * Find all the written-back checkpoint buffers in the given list and release them. 536 * Find all the written-back checkpoint buffers in the given list and release
537 * them.
527 * 538 *
528 * Called with the journal locked.
529 * Called with j_list_lock held. 539 * Called with j_list_lock held.
530 * Returns number of bufers reaped (for debug) 540 * Returns number of bufers reaped (for debug)
531 */ 541 */
@@ -632,8 +642,8 @@ out:
632 * checkpoint lists. 642 * checkpoint lists.
633 * 643 *
634 * The function returns 1 if it frees the transaction, 0 otherwise. 644 * The function returns 1 if it frees the transaction, 0 otherwise.
645 * The function can free jh and bh.
635 * 646 *
636 * This function is called with the journal locked.
637 * This function is called with j_list_lock held. 647 * This function is called with j_list_lock held.
638 * This function is called with jbd_lock_bh_state(jh2bh(jh)) 648 * This function is called with jbd_lock_bh_state(jh2bh(jh))
639 */ 649 */
@@ -652,13 +662,14 @@ int __journal_remove_checkpoint(struct journal_head *jh)
652 } 662 }
653 journal = transaction->t_journal; 663 journal = transaction->t_journal;
654 664
665 JBUFFER_TRACE(jh, "removing from transaction");
655 __buffer_unlink(jh); 666 __buffer_unlink(jh);
656 jh->b_cp_transaction = NULL; 667 jh->b_cp_transaction = NULL;
668 journal_put_journal_head(jh);
657 669
658 if (transaction->t_checkpoint_list != NULL || 670 if (transaction->t_checkpoint_list != NULL ||
659 transaction->t_checkpoint_io_list != NULL) 671 transaction->t_checkpoint_io_list != NULL)
660 goto out; 672 goto out;
661 JBUFFER_TRACE(jh, "transaction has no more buffers");
662 673
663 /* 674 /*
664 * There is one special case to worry about: if we have just pulled the 675 * There is one special case to worry about: if we have just pulled the
@@ -669,10 +680,8 @@ int __journal_remove_checkpoint(struct journal_head *jh)
669 * The locking here around t_state is a bit sleazy. 680 * The locking here around t_state is a bit sleazy.
670 * See the comment at the end of journal_commit_transaction(). 681 * See the comment at the end of journal_commit_transaction().
671 */ 682 */
672 if (transaction->t_state != T_FINISHED) { 683 if (transaction->t_state != T_FINISHED)
673 JBUFFER_TRACE(jh, "belongs to running/committing transaction");
674 goto out; 684 goto out;
675 }
676 685
677 /* OK, that was the last buffer for the transaction: we can now 686 /* OK, that was the last buffer for the transaction: we can now
678 safely remove this transaction from the log */ 687 safely remove this transaction from the log */
@@ -684,7 +693,6 @@ int __journal_remove_checkpoint(struct journal_head *jh)
684 wake_up(&journal->j_wait_logspace); 693 wake_up(&journal->j_wait_logspace);
685 ret = 1; 694 ret = 1;
686out: 695out:
687 JBUFFER_TRACE(jh, "exit");
688 return ret; 696 return ret;
689} 697}
690 698
@@ -703,6 +711,8 @@ void __journal_insert_checkpoint(struct journal_head *jh,
703 J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh))); 711 J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh)));
704 J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); 712 J_ASSERT_JH(jh, jh->b_cp_transaction == NULL);
705 713
714 /* Get reference for checkpointing transaction */
715 journal_grab_journal_head(jh2bh(jh));
706 jh->b_cp_transaction = transaction; 716 jh->b_cp_transaction = transaction;
707 717
708 if (!transaction->t_checkpoint_list) { 718 if (!transaction->t_checkpoint_list) {
@@ -752,6 +762,7 @@ void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
752 J_ASSERT(journal->j_committing_transaction != transaction); 762 J_ASSERT(journal->j_committing_transaction != transaction);
753 J_ASSERT(journal->j_running_transaction != transaction); 763 J_ASSERT(journal->j_running_transaction != transaction);
754 764
765 trace_jbd_drop_transaction(journal, transaction);
755 jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid); 766 jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
756 kfree(transaction); 767 kfree(transaction);
757} 768}