aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2/commit.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r--fs/jbd2/commit.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 6a10238d2c63..671da7fb7ffd 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -259,6 +259,7 @@ static int journal_submit_data_buffers(journal_t *journal,
259 ret = err; 259 ret = err;
260 spin_lock(&journal->j_list_lock); 260 spin_lock(&journal->j_list_lock);
261 J_ASSERT(jinode->i_transaction == commit_transaction); 261 J_ASSERT(jinode->i_transaction == commit_transaction);
262 commit_transaction->t_flushed_data_blocks = 1;
262 jinode->i_flags &= ~JI_COMMIT_RUNNING; 263 jinode->i_flags &= ~JI_COMMIT_RUNNING;
263 wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); 264 wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING);
264 } 265 }
@@ -708,8 +709,17 @@ start_journal_io:
708 } 709 }
709 } 710 }
710 711
711 /* Done it all: now write the commit record asynchronously. */ 712 /*
713 * If the journal is not located on the file system device,
714 * then we must flush the file system device before we issue
715 * the commit record
716 */
717 if (commit_transaction->t_flushed_data_blocks &&
718 (journal->j_fs_dev != journal->j_dev) &&
719 (journal->j_flags & JBD2_BARRIER))
720 blkdev_issue_flush(journal->j_fs_dev, NULL);
712 721
722 /* Done it all: now write the commit record asynchronously. */
713 if (JBD2_HAS_INCOMPAT_FEATURE(journal, 723 if (JBD2_HAS_INCOMPAT_FEATURE(journal,
714 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { 724 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
715 err = journal_submit_commit_record(journal, commit_transaction, 725 err = journal_submit_commit_record(journal, commit_transaction,
@@ -720,13 +730,6 @@ start_journal_io:
720 blkdev_issue_flush(journal->j_dev, NULL); 730 blkdev_issue_flush(journal->j_dev, NULL);
721 } 731 }
722 732
723 /*
724 * This is the right place to wait for data buffers both for ASYNC
725 * and !ASYNC commit. If commit is ASYNC, we need to wait only after
726 * the commit block went to disk (which happens above). If commit is
727 * SYNC, we need to wait for data buffers before we start writing
728 * commit block, which happens below in such setting.
729 */
730 err = journal_finish_inode_data_buffers(journal, commit_transaction); 733 err = journal_finish_inode_data_buffers(journal, commit_transaction);
731 if (err) { 734 if (err) {
732 printk(KERN_WARNING 735 printk(KERN_WARNING
@@ -880,8 +883,7 @@ restart_loop:
880 spin_unlock(&journal->j_list_lock); 883 spin_unlock(&journal->j_list_lock);
881 bh = jh2bh(jh); 884 bh = jh2bh(jh);
882 jbd_lock_bh_state(bh); 885 jbd_lock_bh_state(bh);
883 J_ASSERT_JH(jh, jh->b_transaction == commit_transaction || 886 J_ASSERT_JH(jh, jh->b_transaction == commit_transaction);
884 jh->b_transaction == journal->j_running_transaction);
885 887
886 /* 888 /*
887 * If there is undo-protected committed data against 889 * If there is undo-protected committed data against
@@ -927,12 +929,12 @@ restart_loop:
927 /* A buffer which has been freed while still being 929 /* A buffer which has been freed while still being
928 * journaled by a previous transaction may end up still 930 * journaled by a previous transaction may end up still
929 * being dirty here, but we want to avoid writing back 931 * being dirty here, but we want to avoid writing back
930 * that buffer in the future now that the last use has 932 * that buffer in the future after the "add to orphan"
931 * been committed. That's not only a performance gain, 933 * operation been committed, That's not only a performance
932 * it also stops aliasing problems if the buffer is left 934 * gain, it also stops aliasing problems if the buffer is
933 * behind for writeback and gets reallocated for another 935 * left behind for writeback and gets reallocated for another
934 * use in a different page. */ 936 * use in a different page. */
935 if (buffer_freed(bh)) { 937 if (buffer_freed(bh) && !jh->b_next_transaction) {
936 clear_buffer_freed(bh); 938 clear_buffer_freed(bh);
937 clear_buffer_jbddirty(bh); 939 clear_buffer_jbddirty(bh);
938 } 940 }