ext4/jbd2: don't wait (forever) for stale tid caused by wraparound
[firefly-linux-kernel-4.4.55.git] / fs / jbd2 / journal.c
index ed10991ab0060c5fac4ed580301591f6996965ca..886ec2faa9b419a28f8f657dec3a56ccc26a07f8 100644 (file)
@@ -709,6 +709,37 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid)
        return err;
 }
 
+/*
+ * When this function returns the transaction corresponding to tid
+ * will be completed.  If the transaction has currently running, start
+ * committing that transaction before waiting for it to complete.  If
+ * the transaction id is stale, it is by definition already completed,
+ * so just return SUCCESS.
+ */
+int jbd2_complete_transaction(journal_t *journal, tid_t tid)
+{
+       int     need_to_wait = 1;
+
+       read_lock(&journal->j_state_lock);
+       if (journal->j_running_transaction &&
+           journal->j_running_transaction->t_tid == tid) {
+               if (journal->j_commit_request != tid) {
+                       /* transaction not yet started, so request it */
+                       read_unlock(&journal->j_state_lock);
+                       jbd2_log_start_commit(journal, tid);
+                       goto wait_commit;
+               }
+       } else if (!(journal->j_committing_transaction &&
+                    journal->j_committing_transaction->t_tid == tid))
+               need_to_wait = 0;
+       read_unlock(&journal->j_state_lock);
+       if (!need_to_wait)
+               return 0;
+wait_commit:
+       return jbd2_log_wait_commit(journal, tid);
+}
+EXPORT_SYMBOL(jbd2_complete_transaction);
+
 /*
  * Log buffer allocation routines:
  */