Commit 03f4d804a1b4748885dc4613a4afe10089a731c8

Authored by Jan Kara
1 parent 311b9549ed

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

... ... @@ -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);
... ... @@ -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  
... ... @@ -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 *);