aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2011-05-24 11:59:18 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-05-24 11:59:18 -0400
commitbbd2be36910728f485ac78ea36e0f4f5a38e691e (patch)
tree6a45da5a6ef8bafe9614de5fac68cce1fe4e13ec
parent81be12c8179c1c397d3f179cdd9b3f7146cf47f1 (diff)
jbd2: Add function jbd2_trans_will_send_data_barrier()
Provide a function which returns whether a transaction with given tid will send a flush to the filesystem device. The function will be used by ext4 to detect whether fsync needs to send a separate flush or not. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/jbd2/commit.c10
-rw-r--r--fs/jbd2/journal.c41
-rw-r--r--include/linux/jbd2.h4
3 files changed, 53 insertions, 2 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 2d5095ecc25f..5b506e53c70b 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -677,6 +677,10 @@ start_journal_io:
677 err = 0; 677 err = 0;
678 } 678 }
679 679
680 write_lock(&journal->j_state_lock);
681 J_ASSERT(commit_transaction->t_state == T_COMMIT);
682 commit_transaction->t_state = T_COMMIT_DFLUSH;
683 write_unlock(&journal->j_state_lock);
680 /* 684 /*
681 * If the journal is not located on the file system device, 685 * If the journal is not located on the file system device,
682 * then we must flush the file system device before we issue 686 * then we must flush the file system device before we issue
@@ -804,6 +808,10 @@ wait_for_iobuf:
804 jbd2_journal_abort(journal, err); 808 jbd2_journal_abort(journal, err);
805 809
806 jbd_debug(3, "JBD: commit phase 5\n"); 810 jbd_debug(3, "JBD: commit phase 5\n");
811 write_lock(&journal->j_state_lock);
812 J_ASSERT(commit_transaction->t_state == T_COMMIT_DFLUSH);
813 commit_transaction->t_state = T_COMMIT_JFLUSH;
814 write_unlock(&journal->j_state_lock);
807 815
808 if (!JBD2_HAS_INCOMPAT_FEATURE(journal, 816 if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
809 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { 817 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
@@ -959,7 +967,7 @@ restart_loop:
959 967
960 jbd_debug(3, "JBD: commit phase 7\n"); 968 jbd_debug(3, "JBD: commit phase 7\n");
961 969
962 J_ASSERT(commit_transaction->t_state == T_COMMIT); 970 J_ASSERT(commit_transaction->t_state == T_COMMIT_JFLUSH);
963 971
964 commit_transaction->t_start = jiffies; 972 commit_transaction->t_start = jiffies;
965 stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, 973 stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging,
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index cd2d341f602e..9a7826990304 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -588,6 +588,47 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid)
588} 588}
589 589
590/* 590/*
591 * Return 1 if a given transaction has not yet sent barrier request
592 * connected with a transaction commit. If 0 is returned, transaction
593 * may or may not have sent the barrier. Used to avoid sending barrier
594 * twice in common cases.
595 */
596int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid)
597{
598 int ret = 0;
599 transaction_t *commit_trans;
600
601 if (!(journal->j_flags & JBD2_BARRIER))
602 return 0;
603 read_lock(&journal->j_state_lock);
604 /* Transaction already committed? */
605 if (tid_geq(journal->j_commit_sequence, tid))
606 goto out;
607 commit_trans = journal->j_committing_transaction;
608 if (!commit_trans || commit_trans->t_tid != tid) {
609 ret = 1;
610 goto out;
611 }
612 /*
613 * Transaction is being committed and we already proceeded to
614 * submitting a flush to fs partition?
615 */
616 if (journal->j_fs_dev != journal->j_dev) {
617 if (!commit_trans->t_need_data_flush ||
618 commit_trans->t_state >= T_COMMIT_DFLUSH)
619 goto out;
620 } else {
621 if (commit_trans->t_state >= T_COMMIT_JFLUSH)
622 goto out;
623 }
624 ret = 1;
625out:
626 read_unlock(&journal->j_state_lock);
627 return ret;
628}
629EXPORT_SYMBOL(jbd2_trans_will_send_data_barrier);
630
631/*
591 * Wait for a specified commit to complete. 632 * Wait for a specified commit to complete.
592 * The caller may not hold the journal lock. 633 * The caller may not hold the journal lock.
593 */ 634 */
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 4d57955061f4..4ecb7b16b278 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -529,9 +529,10 @@ struct transaction_s
529 enum { 529 enum {
530 T_RUNNING, 530 T_RUNNING,
531 T_LOCKED, 531 T_LOCKED,
532 T_RUNDOWN,
533 T_FLUSH, 532 T_FLUSH,
534 T_COMMIT, 533 T_COMMIT,
534 T_COMMIT_DFLUSH,
535 T_COMMIT_JFLUSH,
535 T_FINISHED 536 T_FINISHED
536 } t_state; 537 } t_state;
537 538
@@ -1230,6 +1231,7 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *tid);
1230int jbd2_journal_force_commit_nested(journal_t *journal); 1231int jbd2_journal_force_commit_nested(journal_t *journal);
1231int jbd2_log_wait_commit(journal_t *journal, tid_t tid); 1232int jbd2_log_wait_commit(journal_t *journal, tid_t tid);
1232int jbd2_log_do_checkpoint(journal_t *journal); 1233int jbd2_log_do_checkpoint(journal_t *journal);
1234int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid);
1233 1235
1234void __jbd2_log_wait_for_space(journal_t *journal); 1236void __jbd2_log_wait_for_space(journal_t *journal);
1235extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *); 1237extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *);