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.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index dea7503b47e8..61655a37c731 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -96,10 +96,14 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
96 96
97 if (jh->b_jlist == BJ_None && !buffer_locked(bh) && 97 if (jh->b_jlist == BJ_None && !buffer_locked(bh) &&
98 !buffer_dirty(bh) && !buffer_write_io_error(bh)) { 98 !buffer_dirty(bh) && !buffer_write_io_error(bh)) {
99 /*
100 * Get our reference so that bh cannot be freed before
101 * we unlock it
102 */
103 get_bh(bh);
99 JBUFFER_TRACE(jh, "remove from checkpoint list"); 104 JBUFFER_TRACE(jh, "remove from checkpoint list");
100 ret = __journal_remove_checkpoint(jh) + 1; 105 ret = __journal_remove_checkpoint(jh) + 1;
101 jbd_unlock_bh_state(bh); 106 jbd_unlock_bh_state(bh);
102 journal_remove_journal_head(bh);
103 BUFFER_TRACE(bh, "release"); 107 BUFFER_TRACE(bh, "release");
104 __brelse(bh); 108 __brelse(bh);
105 } else { 109 } else {
@@ -221,8 +225,8 @@ restart:
221 spin_lock(&journal->j_list_lock); 225 spin_lock(&journal->j_list_lock);
222 goto restart; 226 goto restart;
223 } 227 }
228 get_bh(bh);
224 if (buffer_locked(bh)) { 229 if (buffer_locked(bh)) {
225 get_bh(bh);
226 spin_unlock(&journal->j_list_lock); 230 spin_unlock(&journal->j_list_lock);
227 jbd_unlock_bh_state(bh); 231 jbd_unlock_bh_state(bh);
228 wait_on_buffer(bh); 232 wait_on_buffer(bh);
@@ -241,7 +245,6 @@ restart:
241 */ 245 */
242 released = __journal_remove_checkpoint(jh); 246 released = __journal_remove_checkpoint(jh);
243 jbd_unlock_bh_state(bh); 247 jbd_unlock_bh_state(bh);
244 journal_remove_journal_head(bh);
245 __brelse(bh); 248 __brelse(bh);
246 } 249 }
247 250
@@ -305,12 +308,12 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh,
305 ret = 1; 308 ret = 1;
306 if (unlikely(buffer_write_io_error(bh))) 309 if (unlikely(buffer_write_io_error(bh)))
307 ret = -EIO; 310 ret = -EIO;
311 get_bh(bh);
308 J_ASSERT_JH(jh, !buffer_jbddirty(bh)); 312 J_ASSERT_JH(jh, !buffer_jbddirty(bh));
309 BUFFER_TRACE(bh, "remove from checkpoint"); 313 BUFFER_TRACE(bh, "remove from checkpoint");
310 __journal_remove_checkpoint(jh); 314 __journal_remove_checkpoint(jh);
311 spin_unlock(&journal->j_list_lock); 315 spin_unlock(&journal->j_list_lock);
312 jbd_unlock_bh_state(bh); 316 jbd_unlock_bh_state(bh);
313 journal_remove_journal_head(bh);
314 __brelse(bh); 317 __brelse(bh);
315 } else { 318 } else {
316 /* 319 /*
@@ -526,9 +529,9 @@ int cleanup_journal_tail(journal_t *journal)
526/* 529/*
527 * journal_clean_one_cp_list 530 * journal_clean_one_cp_list
528 * 531 *
529 * Find all the written-back checkpoint buffers in the given list and release them. 532 * Find all the written-back checkpoint buffers in the given list and release
533 * them.
530 * 534 *
531 * Called with the journal locked.
532 * Called with j_list_lock held. 535 * Called with j_list_lock held.
533 * Returns number of bufers reaped (for debug) 536 * Returns number of bufers reaped (for debug)
534 */ 537 */
@@ -635,8 +638,8 @@ out:
635 * checkpoint lists. 638 * checkpoint lists.
636 * 639 *
637 * The function returns 1 if it frees the transaction, 0 otherwise. 640 * The function returns 1 if it frees the transaction, 0 otherwise.
641 * The function can free jh and bh.
638 * 642 *
639 * This function is called with the journal locked.
640 * This function is called with j_list_lock held. 643 * This function is called with j_list_lock held.
641 * This function is called with jbd_lock_bh_state(jh2bh(jh)) 644 * This function is called with jbd_lock_bh_state(jh2bh(jh))
642 */ 645 */
@@ -655,13 +658,14 @@ int __journal_remove_checkpoint(struct journal_head *jh)
655 } 658 }
656 journal = transaction->t_journal; 659 journal = transaction->t_journal;
657 660
661 JBUFFER_TRACE(jh, "removing from transaction");
658 __buffer_unlink(jh); 662 __buffer_unlink(jh);
659 jh->b_cp_transaction = NULL; 663 jh->b_cp_transaction = NULL;
664 journal_put_journal_head(jh);
660 665
661 if (transaction->t_checkpoint_list != NULL || 666 if (transaction->t_checkpoint_list != NULL ||
662 transaction->t_checkpoint_io_list != NULL) 667 transaction->t_checkpoint_io_list != NULL)
663 goto out; 668 goto out;
664 JBUFFER_TRACE(jh, "transaction has no more buffers");
665 669
666 /* 670 /*
667 * There is one special case to worry about: if we have just pulled the 671 * There is one special case to worry about: if we have just pulled the
@@ -672,10 +676,8 @@ int __journal_remove_checkpoint(struct journal_head *jh)
672 * The locking here around t_state is a bit sleazy. 676 * The locking here around t_state is a bit sleazy.
673 * See the comment at the end of journal_commit_transaction(). 677 * See the comment at the end of journal_commit_transaction().
674 */ 678 */
675 if (transaction->t_state != T_FINISHED) { 679 if (transaction->t_state != T_FINISHED)
676 JBUFFER_TRACE(jh, "belongs to running/committing transaction");
677 goto out; 680 goto out;
678 }
679 681
680 /* OK, that was the last buffer for the transaction: we can now 682 /* OK, that was the last buffer for the transaction: we can now
681 safely remove this transaction from the log */ 683 safely remove this transaction from the log */
@@ -687,7 +689,6 @@ int __journal_remove_checkpoint(struct journal_head *jh)
687 wake_up(&journal->j_wait_logspace); 689 wake_up(&journal->j_wait_logspace);
688 ret = 1; 690 ret = 1;
689out: 691out:
690 JBUFFER_TRACE(jh, "exit");
691 return ret; 692 return ret;
692} 693}
693 694
@@ -706,6 +707,8 @@ void __journal_insert_checkpoint(struct journal_head *jh,
706 J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh))); 707 J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh)));
707 J_ASSERT_JH(jh, jh->b_cp_transaction == NULL); 708 J_ASSERT_JH(jh, jh->b_cp_transaction == NULL);
708 709
710 /* Get reference for checkpointing transaction */
711 journal_grab_journal_head(jh2bh(jh));
709 jh->b_cp_transaction = transaction; 712 jh->b_cp_transaction = transaction;
710 713
711 if (!transaction->t_checkpoint_list) { 714 if (!transaction->t_checkpoint_list) {