diff options
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index b89ef84786a7..1dfcb207ea69 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -331,6 +331,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
331 | struct buffer_head *cbh = NULL; /* For transactional checksums */ | 331 | struct buffer_head *cbh = NULL; /* For transactional checksums */ |
332 | __u32 crc32_sum = ~0; | 332 | __u32 crc32_sum = ~0; |
333 | struct blk_plug plug; | 333 | struct blk_plug plug; |
334 | /* Tail of the journal */ | ||
335 | unsigned long first_block; | ||
336 | tid_t first_tid; | ||
337 | int update_tail; | ||
334 | 338 | ||
335 | /* | 339 | /* |
336 | * First job: lock down the current transaction and wait for | 340 | * First job: lock down the current transaction and wait for |
@@ -688,10 +692,30 @@ start_journal_io: | |||
688 | err = 0; | 692 | err = 0; |
689 | } | 693 | } |
690 | 694 | ||
695 | /* | ||
696 | * Get current oldest transaction in the log before we issue flush | ||
697 | * to the filesystem device. After the flush we can be sure that | ||
698 | * blocks of all older transactions are checkpointed to persistent | ||
699 | * storage and we will be safe to update journal start in the | ||
700 | * superblock with the numbers we get here. | ||
701 | */ | ||
702 | update_tail = | ||
703 | jbd2_journal_get_log_tail(journal, &first_tid, &first_block); | ||
704 | |||
691 | write_lock(&journal->j_state_lock); | 705 | write_lock(&journal->j_state_lock); |
706 | if (update_tail) { | ||
707 | long freed = first_block - journal->j_tail; | ||
708 | |||
709 | if (first_block < journal->j_tail) | ||
710 | freed += journal->j_last - journal->j_first; | ||
711 | /* Update tail only if we free significant amount of space */ | ||
712 | if (freed < journal->j_maxlen / 4) | ||
713 | update_tail = 0; | ||
714 | } | ||
692 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | 715 | J_ASSERT(commit_transaction->t_state == T_COMMIT); |
693 | commit_transaction->t_state = T_COMMIT_DFLUSH; | 716 | commit_transaction->t_state = T_COMMIT_DFLUSH; |
694 | write_unlock(&journal->j_state_lock); | 717 | write_unlock(&journal->j_state_lock); |
718 | |||
695 | /* | 719 | /* |
696 | * If the journal is not located on the file system device, | 720 | * If the journal is not located on the file system device, |
697 | * then we must flush the file system device before we issue | 721 | * then we must flush the file system device before we issue |
@@ -842,6 +866,14 @@ wait_for_iobuf: | |||
842 | if (err) | 866 | if (err) |
843 | jbd2_journal_abort(journal, err); | 867 | jbd2_journal_abort(journal, err); |
844 | 868 | ||
869 | /* | ||
870 | * Now disk caches for filesystem device are flushed so we are safe to | ||
871 | * erase checkpointed transactions from the log by updating journal | ||
872 | * superblock. | ||
873 | */ | ||
874 | if (update_tail) | ||
875 | jbd2_update_log_tail(journal, first_tid, first_block); | ||
876 | |||
845 | /* End of a transaction! Finally, we can do checkpoint | 877 | /* End of a transaction! Finally, we can do checkpoint |
846 | processing: any buffers committed as a result of this | 878 | processing: any buffers committed as a result of this |
847 | transaction can be removed from any checkpoint list it was on | 879 | transaction can be removed from any checkpoint list it was on |