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.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index d4cfd6d2779e..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 }
@@ -286,7 +287,7 @@ static int journal_finish_inode_data_buffers(journal_t *journal,
286 if (err) { 287 if (err) {
287 /* 288 /*
288 * Because AS_EIO is cleared by 289 * Because AS_EIO is cleared by
289 * wait_on_page_writeback_range(), set it again so 290 * filemap_fdatawait_range(), set it again so
290 * that user process can get -EIO from fsync(). 291 * that user process can get -EIO from fsync().
291 */ 292 */
292 set_bit(AS_EIO, 293 set_bit(AS_EIO,
@@ -636,6 +637,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
636 JBUFFER_TRACE(jh, "ph3: write metadata"); 637 JBUFFER_TRACE(jh, "ph3: write metadata");
637 flags = jbd2_journal_write_metadata_buffer(commit_transaction, 638 flags = jbd2_journal_write_metadata_buffer(commit_transaction,
638 jh, &new_jh, blocknr); 639 jh, &new_jh, blocknr);
640 if (flags < 0) {
641 jbd2_journal_abort(journal, flags);
642 continue;
643 }
639 set_bit(BH_JWrite, &jh2bh(new_jh)->b_state); 644 set_bit(BH_JWrite, &jh2bh(new_jh)->b_state);
640 wbuf[bufs++] = jh2bh(new_jh); 645 wbuf[bufs++] = jh2bh(new_jh);
641 646
@@ -704,8 +709,17 @@ start_journal_io:
704 } 709 }
705 } 710 }
706 711
707 /* 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);
708 721
722 /* Done it all: now write the commit record asynchronously. */
709 if (JBD2_HAS_INCOMPAT_FEATURE(journal, 723 if (JBD2_HAS_INCOMPAT_FEATURE(journal,
710 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { 724 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
711 err = journal_submit_commit_record(journal, commit_transaction, 725 err = journal_submit_commit_record(journal, commit_transaction,
@@ -716,13 +730,6 @@ start_journal_io:
716 blkdev_issue_flush(journal->j_dev, NULL); 730 blkdev_issue_flush(journal->j_dev, NULL);
717 } 731 }
718 732
719 /*
720 * This is the right place to wait for data buffers both for ASYNC
721 * and !ASYNC commit. If commit is ASYNC, we need to wait only after
722 * the commit block went to disk (which happens above). If commit is
723 * SYNC, we need to wait for data buffers before we start writing
724 * commit block, which happens below in such setting.
725 */
726 err = journal_finish_inode_data_buffers(journal, commit_transaction); 733 err = journal_finish_inode_data_buffers(journal, commit_transaction);
727 if (err) { 734 if (err) {
728 printk(KERN_WARNING 735 printk(KERN_WARNING
@@ -876,8 +883,7 @@ restart_loop:
876 spin_unlock(&journal->j_list_lock); 883 spin_unlock(&journal->j_list_lock);
877 bh = jh2bh(jh); 884 bh = jh2bh(jh);
878 jbd_lock_bh_state(bh); 885 jbd_lock_bh_state(bh);
879 J_ASSERT_JH(jh, jh->b_transaction == commit_transaction || 886 J_ASSERT_JH(jh, jh->b_transaction == commit_transaction);
880 jh->b_transaction == journal->j_running_transaction);
881 887
882 /* 888 /*
883 * If there is undo-protected committed data against 889 * If there is undo-protected committed data against
@@ -923,12 +929,12 @@ restart_loop:
923 /* A buffer which has been freed while still being 929 /* A buffer which has been freed while still being
924 * journaled by a previous transaction may end up still 930 * journaled by a previous transaction may end up still
925 * being dirty here, but we want to avoid writing back 931 * being dirty here, but we want to avoid writing back
926 * that buffer in the future now that the last use has 932 * that buffer in the future after the "add to orphan"
927 * been committed. That's not only a performance gain, 933 * operation been committed, That's not only a performance
928 * it also stops aliasing problems if the buffer is left 934 * gain, it also stops aliasing problems if the buffer is
929 * behind for writeback and gets reallocated for another 935 * left behind for writeback and gets reallocated for another
930 * use in a different page. */ 936 * use in a different page. */
931 if (buffer_freed(bh)) { 937 if (buffer_freed(bh) && !jh->b_next_transaction) {
932 clear_buffer_freed(bh); 938 clear_buffer_freed(bh);
933 clear_buffer_jbddirty(bh); 939 clear_buffer_jbddirty(bh);
934 } 940 }