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

jbd: Provide function to check whether transaction will issue data barrier

Provide a function which returns whether a transaction with given tid
will send a barrier to the filesystem device. The function will be used
by ext3 to detect whether fsync needs to send a separate barrier or not.

Signed-off-by: Jan Kara <jack@suse.cz>

Jan Kara 03f4d804 311b9549

+42 -2
+7 -1
fs/jbd/commit.c
··· 786 786 787 787 jbd_debug(3, "JBD: commit phase 6\n"); 788 788 789 + /* All metadata is written, now write commit record and do cleanup */ 790 + spin_lock(&journal->j_state_lock); 791 + J_ASSERT(commit_transaction->t_state == T_COMMIT); 792 + commit_transaction->t_state = T_COMMIT_RECORD; 793 + spin_unlock(&journal->j_state_lock); 794 + 789 795 if (journal_write_commit_record(journal, commit_transaction)) 790 796 err = -EIO; 791 797 ··· 929 923 930 924 jbd_debug(3, "JBD: commit phase 8\n"); 931 925 932 - J_ASSERT(commit_transaction->t_state == T_COMMIT); 926 + J_ASSERT(commit_transaction->t_state == T_COMMIT_RECORD); 933 927 934 928 commit_transaction->t_state = T_FINISHED; 935 929 J_ASSERT(commit_transaction == journal->j_committing_transaction);
+33
fs/jbd/journal.c
··· 565 565 } 566 566 567 567 /* 568 + * Return 1 if a given transaction has not yet sent barrier request 569 + * connected with a transaction commit. If 0 is returned, transaction 570 + * may or may not have sent the barrier. Used to avoid sending barrier 571 + * twice in common cases. 572 + */ 573 + int journal_trans_will_send_data_barrier(journal_t *journal, tid_t tid) 574 + { 575 + int ret = 0; 576 + transaction_t *commit_trans; 577 + 578 + if (!(journal->j_flags & JFS_BARRIER)) 579 + return 0; 580 + spin_lock(&journal->j_state_lock); 581 + /* Transaction already committed? */ 582 + if (tid_geq(journal->j_commit_sequence, tid)) 583 + goto out; 584 + /* 585 + * Transaction is being committed and we already proceeded to 586 + * writing commit record? 587 + */ 588 + commit_trans = journal->j_committing_transaction; 589 + if (commit_trans && commit_trans->t_tid == tid && 590 + commit_trans->t_state >= T_COMMIT_RECORD) 591 + goto out; 592 + ret = 1; 593 + out: 594 + spin_unlock(&journal->j_state_lock); 595 + return ret; 596 + } 597 + EXPORT_SYMBOL(journal_commit_will_send_barrier); 598 + 599 + /* 568 600 * Log buffer allocation routines: 569 601 */ 570 602 ··· 1189 1157 { 1190 1158 int err = 0; 1191 1159 1160 + 1192 1161 /* Wait for the commit thread to wake up and die. */ 1193 1162 journal_kill_thread(journal); 1194 1163
+2 -1
include/linux/jbd.h
··· 427 427 enum { 428 428 T_RUNNING, 429 429 T_LOCKED, 430 - T_RUNDOWN, 431 430 T_FLUSH, 432 431 T_COMMIT, 432 + T_COMMIT_RECORD, 433 433 T_FINISHED 434 434 } t_state; 435 435 ··· 991 991 int journal_force_commit_nested(journal_t *journal); 992 992 int log_wait_commit(journal_t *journal, tid_t tid); 993 993 int log_do_checkpoint(journal_t *journal); 994 + int journal_trans_will_send_data_barrier(journal_t *journal, tid_t tid); 994 995 995 996 void __log_wait_for_space(journal_t *journal); 996 997 extern void __journal_drop_transaction(journal_t *, transaction_t *);