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.c97
1 files changed, 50 insertions, 47 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 26d991ddc1e6..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,
@@ -410,10 +411,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
410 if (commit_transaction->t_synchronous_commit) 411 if (commit_transaction->t_synchronous_commit)
411 write_op = WRITE_SYNC_PLUG; 412 write_op = WRITE_SYNC_PLUG;
412 trace_jbd2_commit_locking(journal, commit_transaction); 413 trace_jbd2_commit_locking(journal, commit_transaction);
413 stats.u.run.rs_wait = commit_transaction->t_max_wait; 414 stats.run.rs_wait = commit_transaction->t_max_wait;
414 stats.u.run.rs_locked = jiffies; 415 stats.run.rs_locked = jiffies;
415 stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start, 416 stats.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
416 stats.u.run.rs_locked); 417 stats.run.rs_locked);
417 418
418 spin_lock(&commit_transaction->t_handle_lock); 419 spin_lock(&commit_transaction->t_handle_lock);
419 while (commit_transaction->t_updates) { 420 while (commit_transaction->t_updates) {
@@ -486,9 +487,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
486 jbd2_journal_switch_revoke_table(journal); 487 jbd2_journal_switch_revoke_table(journal);
487 488
488 trace_jbd2_commit_flushing(journal, commit_transaction); 489 trace_jbd2_commit_flushing(journal, commit_transaction);
489 stats.u.run.rs_flushing = jiffies; 490 stats.run.rs_flushing = jiffies;
490 stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked, 491 stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked,
491 stats.u.run.rs_flushing); 492 stats.run.rs_flushing);
492 493
493 commit_transaction->t_state = T_FLUSH; 494 commit_transaction->t_state = T_FLUSH;
494 journal->j_committing_transaction = commit_transaction; 495 journal->j_committing_transaction = commit_transaction;
@@ -523,11 +524,11 @@ void jbd2_journal_commit_transaction(journal_t *journal)
523 spin_unlock(&journal->j_state_lock); 524 spin_unlock(&journal->j_state_lock);
524 525
525 trace_jbd2_commit_logging(journal, commit_transaction); 526 trace_jbd2_commit_logging(journal, commit_transaction);
526 stats.u.run.rs_logging = jiffies; 527 stats.run.rs_logging = jiffies;
527 stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, 528 stats.run.rs_flushing = jbd2_time_diff(stats.run.rs_flushing,
528 stats.u.run.rs_logging); 529 stats.run.rs_logging);
529 stats.u.run.rs_blocks = commit_transaction->t_outstanding_credits; 530 stats.run.rs_blocks = commit_transaction->t_outstanding_credits;
530 stats.u.run.rs_blocks_logged = 0; 531 stats.run.rs_blocks_logged = 0;
531 532
532 J_ASSERT(commit_transaction->t_nr_buffers <= 533 J_ASSERT(commit_transaction->t_nr_buffers <=
533 commit_transaction->t_outstanding_credits); 534 commit_transaction->t_outstanding_credits);
@@ -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
@@ -695,7 +700,7 @@ start_journal_io:
695 submit_bh(write_op, bh); 700 submit_bh(write_op, bh);
696 } 701 }
697 cond_resched(); 702 cond_resched();
698 stats.u.run.rs_blocks_logged += bufs; 703 stats.run.rs_blocks_logged += bufs;
699 704
700 /* Force a new descriptor to be generated next 705 /* Force a new descriptor to be generated next
701 time round the loop. */ 706 time round the loop. */
@@ -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 }
@@ -988,33 +994,30 @@ restart_loop:
988 J_ASSERT(commit_transaction->t_state == T_COMMIT); 994 J_ASSERT(commit_transaction->t_state == T_COMMIT);
989 995
990 commit_transaction->t_start = jiffies; 996 commit_transaction->t_start = jiffies;
991 stats.u.run.rs_logging = jbd2_time_diff(stats.u.run.rs_logging, 997 stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging,
992 commit_transaction->t_start); 998 commit_transaction->t_start);
993 999
994 /* 1000 /*
995 * File the transaction for history 1001 * File the transaction statistics
996 */ 1002 */
997 stats.ts_type = JBD2_STATS_RUN;
998 stats.ts_tid = commit_transaction->t_tid; 1003 stats.ts_tid = commit_transaction->t_tid;
999 stats.u.run.rs_handle_count = commit_transaction->t_handle_count; 1004 stats.run.rs_handle_count = commit_transaction->t_handle_count;
1000 spin_lock(&journal->j_history_lock); 1005 trace_jbd2_run_stats(journal->j_fs_dev->bd_dev,
1001 memcpy(journal->j_history + journal->j_history_cur, &stats, 1006 commit_transaction->t_tid, &stats.run);
1002 sizeof(stats));
1003 if (++journal->j_history_cur == journal->j_history_max)
1004 journal->j_history_cur = 0;
1005 1007
1006 /* 1008 /*
1007 * Calculate overall stats 1009 * Calculate overall stats
1008 */ 1010 */
1011 spin_lock(&journal->j_history_lock);
1009 journal->j_stats.ts_tid++; 1012 journal->j_stats.ts_tid++;
1010 journal->j_stats.u.run.rs_wait += stats.u.run.rs_wait; 1013 journal->j_stats.run.rs_wait += stats.run.rs_wait;
1011 journal->j_stats.u.run.rs_running += stats.u.run.rs_running; 1014 journal->j_stats.run.rs_running += stats.run.rs_running;
1012 journal->j_stats.u.run.rs_locked += stats.u.run.rs_locked; 1015 journal->j_stats.run.rs_locked += stats.run.rs_locked;
1013 journal->j_stats.u.run.rs_flushing += stats.u.run.rs_flushing; 1016 journal->j_stats.run.rs_flushing += stats.run.rs_flushing;
1014 journal->j_stats.u.run.rs_logging += stats.u.run.rs_logging; 1017 journal->j_stats.run.rs_logging += stats.run.rs_logging;
1015 journal->j_stats.u.run.rs_handle_count += stats.u.run.rs_handle_count; 1018 journal->j_stats.run.rs_handle_count += stats.run.rs_handle_count;
1016 journal->j_stats.u.run.rs_blocks += stats.u.run.rs_blocks; 1019 journal->j_stats.run.rs_blocks += stats.run.rs_blocks;
1017 journal->j_stats.u.run.rs_blocks_logged += stats.u.run.rs_blocks_logged; 1020 journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged;
1018 spin_unlock(&journal->j_history_lock); 1021 spin_unlock(&journal->j_history_lock);
1019 1022
1020 commit_transaction->t_state = T_FINISHED; 1023 commit_transaction->t_state = T_FINISHED;