Commit 03f4d804a1b4748885dc4613a4afe10089a731c8
1 parent
311b9549ed
Exists in
master
and in
4 other branches
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>
Showing 3 changed files with 42 additions and 2 deletions Side-by-side Diff
fs/jbd/commit.c
... | ... | @@ -786,6 +786,12 @@ |
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 | |
... | ... | @@ -923,7 +929,7 @@ |
923 | 929 | |
924 | 930 | jbd_debug(3, "JBD: commit phase 8\n"); |
925 | 931 | |
926 | - J_ASSERT(commit_transaction->t_state == T_COMMIT); | |
932 | + J_ASSERT(commit_transaction->t_state == T_COMMIT_RECORD); | |
927 | 933 | |
928 | 934 | commit_transaction->t_state = T_FINISHED; |
929 | 935 | J_ASSERT(commit_transaction == journal->j_committing_transaction); |
fs/jbd/journal.c
... | ... | @@ -565,6 +565,38 @@ |
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 | |
... | ... | @@ -1157,6 +1189,7 @@ |
1157 | 1189 | { |
1158 | 1190 | int err = 0; |
1159 | 1191 | |
1192 | + | |
1160 | 1193 | /* Wait for the commit thread to wake up and die. */ |
1161 | 1194 | journal_kill_thread(journal); |
1162 | 1195 |
include/linux/jbd.h
... | ... | @@ -427,9 +427,9 @@ |
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,6 +991,7 @@ |
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 *); |