]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/jbd2/journal.c
jbd2: optimize jbd2_journal_force_commit
[karo-tx-linux.git] / fs / jbd2 / journal.c
index b0a8d1e4703e90414b7d4dc810f312f22a756cd3..0e6c13bdcc149f98aad310e5b0c67a500e428f08 100644 (file)
@@ -451,6 +451,7 @@ repeat:
        new_bh->b_size = bh_in->b_size;
        new_bh->b_bdev = journal->j_dev;
        new_bh->b_blocknr = blocknr;
+       new_bh->b_private = bh_in;
        set_buffer_mapped(new_bh);
        set_buffer_dirty(new_bh);
 
@@ -465,6 +466,7 @@ repeat:
        spin_lock(&journal->j_list_lock);
        __jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow);
        spin_unlock(&journal->j_list_lock);
+       set_buffer_shadow(bh_in);
        jbd_unlock_bh_state(bh_in);
 
        return do_escape | (done_copy_out << 1);
@@ -475,35 +477,6 @@ repeat:
  * journal, so that we can begin checkpointing when appropriate.
  */
 
-/*
- * __jbd2_log_space_left: Return the number of free blocks left in the journal.
- *
- * Called with the journal already locked.
- *
- * Called under j_state_lock
- */
-
-int __jbd2_log_space_left(journal_t *journal)
-{
-       int left = journal->j_free;
-
-       /* assert_spin_locked(&journal->j_state_lock); */
-
-       /*
-        * Be pessimistic here about the number of those free blocks which
-        * might be required for log descriptor control blocks.
-        */
-
-#define MIN_LOG_RESERVED_BLOCKS 32 /* Allow for rounding errors */
-
-       left -= MIN_LOG_RESERVED_BLOCKS;
-
-       if (left <= 0)
-               return 0;
-       left -= (left >> 3);
-       return left;
-}
-
 /*
  * Called with j_state_lock locked for writing.
  * Returns true if a transaction commit was started.
@@ -556,20 +529,17 @@ int jbd2_log_start_commit(journal_t *journal, tid_t tid)
 }
 
 /*
- * Force and wait upon a commit if the calling process is not within
- * transaction.  This is used for forcing out undo-protected data which contains
- * bitmaps, when the fs is running out of space.
- *
- * We can only force the running transaction if we don't have an active handle;
- * otherwise, we will deadlock.
- *
- * Returns true if a transaction was started.
+ * Force and wait any uncommitted transactions.  We can only force the running
+ * transaction if we don't have an active handle, otherwise, we will deadlock.
+ * Returns: <0 in case of error,
+ *           0 if nothing to commit,
+ *           1 if transaction was successfully committed.
  */
-int jbd2_journal_force_commit_nested(journal_t *journal)
+static int __jbd2_journal_force_commit(journal_t *journal)
 {
        transaction_t *transaction = NULL;
        tid_t tid;
-       int need_to_start = 0;
+       int need_to_start = 0, ret = 0;
 
        read_lock(&journal->j_state_lock);
        if (journal->j_running_transaction && !current->journal_info) {
@@ -580,16 +550,53 @@ int jbd2_journal_force_commit_nested(journal_t *journal)
                transaction = journal->j_committing_transaction;
 
        if (!transaction) {
+               /* Nothing to commit */
                read_unlock(&journal->j_state_lock);
-               return 0;       /* Nothing to retry */
+               return 0;
        }
-
        tid = transaction->t_tid;
        read_unlock(&journal->j_state_lock);
        if (need_to_start)
                jbd2_log_start_commit(journal, tid);
-       jbd2_log_wait_commit(journal, tid);
-       return 1;
+       ret = jbd2_log_wait_commit(journal, tid);
+       if (!ret)
+               ret = 1;
+
+       return ret;
+}
+
+/**
+ * Force and wait upon a commit if the calling process is not within
+ * transaction.  This is used for forcing out undo-protected data which contains
+ * bitmaps, when the fs is running out of space.
+ *
+ * @journal: journal to force
+ * Returns true if progress was made.
+ */
+int jbd2_journal_force_commit_nested(journal_t *journal)
+{
+       int ret;
+
+       ret = __jbd2_journal_force_commit(journal);
+       return ret > 0;
+}
+
+/**
+ * int journal_force_commit() - force any uncommitted transactions
+ * @journal: journal to force
+ *
+ * Caller want unconditional commit. We can only force the running transaction
+ * if we don't have an active handle, otherwise, we will deadlock.
+ */
+int jbd2_journal_force_commit(journal_t *journal)
+{
+       int ret;
+
+       J_ASSERT(!current->journal_info);
+       ret = __jbd2_journal_force_commit(journal);
+       if (ret > 0)
+               ret = 0;
+       return ret;
 }
 
 /*
@@ -1054,11 +1061,10 @@ static journal_t * journal_init_common (void)
                return NULL;
 
        init_waitqueue_head(&journal->j_wait_transaction_locked);
-       init_waitqueue_head(&journal->j_wait_logspace);
        init_waitqueue_head(&journal->j_wait_done_commit);
-       init_waitqueue_head(&journal->j_wait_checkpoint);
        init_waitqueue_head(&journal->j_wait_commit);
        init_waitqueue_head(&journal->j_wait_updates);
+       init_waitqueue_head(&journal->j_wait_reserved);
        mutex_init(&journal->j_barrier);
        mutex_init(&journal->j_checkpoint_mutex);
        spin_lock_init(&journal->j_revoke_lock);
@@ -1068,6 +1074,7 @@ static journal_t * journal_init_common (void)
        journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE);
        journal->j_min_batch_time = 0;
        journal->j_max_batch_time = 15000; /* 15ms */
+       atomic_set(&journal->j_reserved_credits, 0);
 
        /* The journal is marked for error until we succeed with recovery! */
        journal->j_flags = JBD2_ABORT;