diff options
author | Jan Kara <jack@suse.cz> | 2011-05-24 11:59:18 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-05-24 11:59:18 -0400 |
commit | bbd2be36910728f485ac78ea36e0f4f5a38e691e (patch) | |
tree | 6a45da5a6ef8bafe9614de5fac68cce1fe4e13ec | |
parent | 81be12c8179c1c397d3f179cdd9b3f7146cf47f1 (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.c | 10 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 41 | ||||
-rw-r--r-- | include/linux/jbd2.h | 4 |
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 | */ | ||
596 | int 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; | ||
625 | out: | ||
626 | read_unlock(&journal->j_state_lock); | ||
627 | return ret; | ||
628 | } | ||
629 | EXPORT_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); | |||
1230 | int jbd2_journal_force_commit_nested(journal_t *journal); | 1231 | int jbd2_journal_force_commit_nested(journal_t *journal); |
1231 | int jbd2_log_wait_commit(journal_t *journal, tid_t tid); | 1232 | int jbd2_log_wait_commit(journal_t *journal, tid_t tid); |
1232 | int jbd2_log_do_checkpoint(journal_t *journal); | 1233 | int jbd2_log_do_checkpoint(journal_t *journal); |
1234 | int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid); | ||
1233 | 1235 | ||
1234 | void __jbd2_log_wait_for_space(journal_t *journal); | 1236 | void __jbd2_log_wait_for_space(journal_t *journal); |
1235 | extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *); | 1237 | extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *); |