diff options
Diffstat (limited to 'fs/jbd/checkpoint.c')
-rw-r--r-- | fs/jbd/checkpoint.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 5d1a00a5041b..05f0754f2b46 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c | |||
@@ -453,8 +453,6 @@ out: | |||
453 | * | 453 | * |
454 | * Return <0 on error, 0 on success, 1 if there was nothing to clean up. | 454 | * Return <0 on error, 0 on success, 1 if there was nothing to clean up. |
455 | * | 455 | * |
456 | * Called with the journal lock held. | ||
457 | * | ||
458 | * This is the only part of the journaling code which really needs to be | 456 | * This is the only part of the journaling code which really needs to be |
459 | * aware of transaction aborts. Checkpointing involves writing to the | 457 | * aware of transaction aborts. Checkpointing involves writing to the |
460 | * main filesystem area rather than to the journal, so it can proceed | 458 | * main filesystem area rather than to the journal, so it can proceed |
@@ -472,13 +470,14 @@ int cleanup_journal_tail(journal_t *journal) | |||
472 | if (is_journal_aborted(journal)) | 470 | if (is_journal_aborted(journal)) |
473 | return 1; | 471 | return 1; |
474 | 472 | ||
475 | /* OK, work out the oldest transaction remaining in the log, and | 473 | /* |
474 | * OK, work out the oldest transaction remaining in the log, and | ||
476 | * the log block it starts at. | 475 | * the log block it starts at. |
477 | * | 476 | * |
478 | * If the log is now empty, we need to work out which is the | 477 | * If the log is now empty, we need to work out which is the |
479 | * next transaction ID we will write, and where it will | 478 | * next transaction ID we will write, and where it will |
480 | * start. */ | 479 | * start. |
481 | 480 | */ | |
482 | spin_lock(&journal->j_state_lock); | 481 | spin_lock(&journal->j_state_lock); |
483 | spin_lock(&journal->j_list_lock); | 482 | spin_lock(&journal->j_list_lock); |
484 | transaction = journal->j_checkpoint_transactions; | 483 | transaction = journal->j_checkpoint_transactions; |
@@ -504,7 +503,25 @@ int cleanup_journal_tail(journal_t *journal) | |||
504 | spin_unlock(&journal->j_state_lock); | 503 | spin_unlock(&journal->j_state_lock); |
505 | return 1; | 504 | return 1; |
506 | } | 505 | } |
506 | spin_unlock(&journal->j_state_lock); | ||
507 | |||
508 | /* | ||
509 | * We need to make sure that any blocks that were recently written out | ||
510 | * --- perhaps by log_do_checkpoint() --- are flushed out before we | ||
511 | * drop the transactions from the journal. It's unlikely this will be | ||
512 | * necessary, especially with an appropriately sized journal, but we | ||
513 | * need this to guarantee correctness. Fortunately | ||
514 | * cleanup_journal_tail() doesn't get called all that often. | ||
515 | */ | ||
516 | if (journal->j_flags & JFS_BARRIER) | ||
517 | blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); | ||
507 | 518 | ||
519 | spin_lock(&journal->j_state_lock); | ||
520 | if (!tid_gt(first_tid, journal->j_tail_sequence)) { | ||
521 | spin_unlock(&journal->j_state_lock); | ||
522 | /* Someone else cleaned up journal so return 0 */ | ||
523 | return 0; | ||
524 | } | ||
508 | /* OK, update the superblock to recover the freed space. | 525 | /* OK, update the superblock to recover the freed space. |
509 | * Physical blocks come first: have we wrapped beyond the end of | 526 | * Physical blocks come first: have we wrapped beyond the end of |
510 | * the log? */ | 527 | * the log? */ |