Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jan Kara and committed by
Theodore Ts'o
bbd2be36 81be12c8

+53 -2
+9 -1
fs/jbd2/commit.c
··· 677 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 685 * If the journal is not located on the file system device, 682 686 * then we must flush the file system device before we issue ··· 808 804 jbd2_journal_abort(journal, err); 809 805 810 806 jbd_debug(3, "JBD: commit phase 5\n"); 807 + write_lock(&journal->j_state_lock); 808 + J_ASSERT(commit_transaction->t_state == T_COMMIT_DFLUSH); 809 + commit_transaction->t_state = T_COMMIT_JFLUSH; 810 + write_unlock(&journal->j_state_lock); 811 811 812 812 if (!JBD2_HAS_INCOMPAT_FEATURE(journal, 813 813 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { ··· 967 959 968 960 jbd_debug(3, "JBD: commit phase 7\n"); 969 961 970 - J_ASSERT(commit_transaction->t_state == T_COMMIT); 962 + J_ASSERT(commit_transaction->t_state == T_COMMIT_JFLUSH); 971 963 972 964 commit_transaction->t_start = jiffies; 973 965 stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging,
+41
fs/jbd2/journal.c
··· 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 632 * Wait for a specified commit to complete. 592 633 * The caller may not hold the journal lock. 593 634 */
+3 -1
include/linux/jbd2.h
··· 529 529 enum { 530 530 T_RUNNING, 531 531 T_LOCKED, 532 - T_RUNDOWN, 533 532 T_FLUSH, 534 533 T_COMMIT, 534 + T_COMMIT_DFLUSH, 535 + T_COMMIT_JFLUSH, 535 536 T_FINISHED 536 537 } t_state; 537 538 ··· 1231 1230 int jbd2_journal_force_commit_nested(journal_t *journal); 1232 1231 int jbd2_log_wait_commit(journal_t *journal, tid_t tid); 1233 1232 int jbd2_log_do_checkpoint(journal_t *journal); 1233 + int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid); 1234 1234 1235 1235 void __jbd2_log_wait_for_space(journal_t *journal); 1236 1236 extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *);