aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-03-13 22:45:38 -0400
committerTheodore Ts'o <tytso@mit.edu>2012-03-13 22:45:38 -0400
commit3339578f05787259917788f461f4196b7349c2a4 (patch)
tree8e05b11eecd98e49076057940fc161f5b867b55c
parent932bb305ba2a01cd62809644d569f004e77a4355 (diff)
jbd2: cleanup journal tail after transaction commit
Normally, we have to issue a cache flush before we can update journal tail in journal superblock, effectively wiping out old transactions from the journal. So use the fact that during transaction commit we issue cache flush anyway and opportunistically push journal tail as far as we can. Since update of journal superblock is still costly (we have to use WRITE_FUA), we update log tail only if we can free significant amount of space. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/jbd2/commit.c32
-rw-r--r--fs/jbd2/journal.c13
-rw-r--r--include/linux/jbd2.h1
3 files changed, 46 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
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index c5ff177400ff..bda564f63864 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -821,6 +821,19 @@ void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block)
821 write_unlock(&journal->j_state_lock); 821 write_unlock(&journal->j_state_lock);
822} 822}
823 823
824/*
825 * This is a variaon of __jbd2_update_log_tail which checks for validity of
826 * provided log tail and locks j_checkpoint_mutex. So it is safe against races
827 * with other threads updating log tail.
828 */
829void jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block)
830{
831 mutex_lock(&journal->j_checkpoint_mutex);
832 if (tid_gt(tid, journal->j_tail_sequence))
833 __jbd2_update_log_tail(journal, tid, block);
834 mutex_unlock(&journal->j_checkpoint_mutex);
835}
836
824struct jbd2_stats_proc_session { 837struct jbd2_stats_proc_session {
825 journal_t *journal; 838 journal_t *journal;
826 struct transaction_stats_s *stats; 839 struct transaction_stats_s *stats;
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 876a7d87192b..912c30a8ddb1 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -974,6 +974,7 @@ int jbd2_journal_next_log_block(journal_t *, unsigned long long *);
974int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid, 974int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid,
975 unsigned long *block); 975 unsigned long *block);
976void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block); 976void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block);
977void jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block);
977 978
978/* Commit management */ 979/* Commit management */
979extern void jbd2_journal_commit_transaction(journal_t *); 980extern void jbd2_journal_commit_transaction(journal_t *);