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.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index d4cfd6d2779e..1bc74b6f26d2 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