use struct list_head for a linked circular list of all transactions
waiting for checkpointing on a journal control structure.

Signed-off-by: Akinobu Mita <[EMAIL PROTECTED]>

---

 fs/jbd/checkpoint.c  |   48 ++++++++++++++++++++----------------------------
 fs/jbd/commit.c      |   16 ++--------------
 fs/jbd/journal.c     |    9 +++++----
 fs/jbd/transaction.c |    1 +
 include/linux/jbd.h  |    4 ++--
 5 files changed, 30 insertions(+), 48 deletions(-)

diff -X 2.6.13-mm1/Documentation/dontdiff -Nurp 
2.6.13-mm1.old/fs/jbd/checkpoint.c 2.6.13-mm1/fs/jbd/checkpoint.c
--- 2.6.13-mm1.old/fs/jbd/checkpoint.c  2005-09-04 23:31:48.000000000 +0900
+++ 2.6.13-mm1/fs/jbd/checkpoint.c      2005-09-05 00:23:28.000000000 +0900
@@ -180,8 +180,10 @@ static void __wait_cp_io(journal_t *jour
        this_tid = transaction->t_tid;
 restart:
        /* Didn't somebody clean up the transaction in the meanwhile */
-       if (journal->j_checkpoint_transactions != transaction ||
-               transaction->t_tid != this_tid)
+       if (list_empty(&journal->j_checkpoint_transactions) ||
+           list_entry(journal->j_checkpoint_transactions.next, transaction_t,
+                       t_cplist) != transaction ||
+           transaction->t_tid != this_tid)
                return;
        while (!released && transaction->t_checkpoint_io_list) {
                jh = transaction->t_checkpoint_io_list;
@@ -328,9 +330,10 @@ int log_do_checkpoint(journal_t *journal
         * and write it.
         */
        spin_lock(&journal->j_list_lock);
-       if (!journal->j_checkpoint_transactions)
+       if (list_empty(&journal->j_checkpoint_transactions))
                goto out;
-       transaction = journal->j_checkpoint_transactions;
+       transaction = list_entry(journal->j_checkpoint_transactions.next,
+                                transaction_t, t_cplist);
        this_tid = transaction->t_tid;
 restart:
        /*
@@ -338,8 +341,10 @@ restart:
         * done (maybe it's a new transaction, but it fell at the same
         * address).
         */
-       if (journal->j_checkpoint_transactions == transaction ||
-                       transaction->t_tid == this_tid) {
+       if ((!list_empty(&journal->j_checkpoint_transactions) &&
+            list_entry(journal->j_checkpoint_transactions.next,
+                       transaction_t, t_cplist) == transaction) ||
+             transaction->t_tid == this_tid) {
                int batch_count = 0;
                struct buffer_head *bhs[NR_BATCH];
                struct journal_head *jh;
@@ -410,7 +415,7 @@ out:
 
 int cleanup_journal_tail(journal_t *journal)
 {
-       transaction_t * transaction;
+       transaction_t * transaction = NULL;
        tid_t           first_tid;
        unsigned long   blocknr, freed;
 
@@ -423,7 +428,9 @@ int cleanup_journal_tail(journal_t *jour
 
        spin_lock(&journal->j_state_lock);
        spin_lock(&journal->j_list_lock);
-       transaction = journal->j_checkpoint_transactions;
+       if (!list_empty(&journal->j_checkpoint_transactions))
+               transaction = 
list_entry(journal->j_checkpoint_transactions.next,
+                                        transaction_t, t_cplist);
        if (transaction) {
                first_tid = transaction->t_tid;
                blocknr = transaction->t_log_start;
@@ -530,18 +537,11 @@ static int journal_clean_one_cp_list(str
 
 int __journal_clean_checkpoint_list(journal_t *journal)
 {
-       transaction_t *transaction, *last_transaction, *next_transaction;
+       transaction_t *transaction, *next_transaction;
        int ret = 0, released;
 
-       transaction = journal->j_checkpoint_transactions;
-       if (!transaction)
-               goto out;
-
-       last_transaction = transaction->t_cpprev;
-       next_transaction = transaction;
-       do {
-               transaction = next_transaction;
-               next_transaction = transaction->t_cpnext;
+       list_for_each_entry_safe(transaction, next_transaction,
+                               &journal->j_checkpoint_transactions, t_cplist) {
                ret += journal_clean_one_cp_list(transaction->
                                t_checkpoint_list, &released);
                if (need_resched())
@@ -557,7 +557,7 @@ int __journal_clean_checkpoint_list(jour
                                t_checkpoint_io_list, &released);
                if (need_resched())
                        goto out;
-       } while (transaction != last_transaction);
+       }
 out:
        return ret;
 }
@@ -673,15 +673,7 @@ void __journal_insert_checkpoint(struct 
 void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
 {
        assert_spin_locked(&journal->j_list_lock);
-       if (transaction->t_cpnext) {
-               transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
-               transaction->t_cpprev->t_cpnext = transaction->t_cpnext;
-               if (journal->j_checkpoint_transactions == transaction)
-                       journal->j_checkpoint_transactions =
-                               transaction->t_cpnext;
-               if (journal->j_checkpoint_transactions == transaction)
-                       journal->j_checkpoint_transactions = NULL;
-       }
+       list_del(&transaction->t_cplist);
 
        J_ASSERT(transaction->t_state == T_FINISHED);
        J_ASSERT(list_empty(&transaction->t_metadata_list));
diff -X 2.6.13-mm1/Documentation/dontdiff -Nurp 2.6.13-mm1.old/fs/jbd/commit.c 
2.6.13-mm1/fs/jbd/commit.c
--- 2.6.13-mm1.old/fs/jbd/commit.c      2005-09-04 23:31:48.000000000 +0900
+++ 2.6.13-mm1/fs/jbd/commit.c  2005-09-04 23:41:01.000000000 +0900
@@ -835,20 +835,8 @@ restart_loop:
        if (commit_transaction->t_checkpoint_list == NULL) {
                __journal_drop_transaction(journal, commit_transaction);
        } else {
-               if (journal->j_checkpoint_transactions == NULL) {
-                       journal->j_checkpoint_transactions = commit_transaction;
-                       commit_transaction->t_cpnext = commit_transaction;
-                       commit_transaction->t_cpprev = commit_transaction;
-               } else {
-                       commit_transaction->t_cpnext =
-                               journal->j_checkpoint_transactions;
-                       commit_transaction->t_cpprev =
-                               commit_transaction->t_cpnext->t_cpprev;
-                       commit_transaction->t_cpnext->t_cpprev =
-                               commit_transaction;
-                       commit_transaction->t_cpprev->t_cpnext =
-                               commit_transaction;
-               }
+               list_add_tail(&commit_transaction->t_cplist,
+                        &journal->j_checkpoint_transactions);
        }
        spin_unlock(&journal->j_list_lock);
 
diff -X 2.6.13-mm1/Documentation/dontdiff -Nurp 2.6.13-mm1.old/fs/jbd/journal.c 
2.6.13-mm1/fs/jbd/journal.c
--- 2.6.13-mm1.old/fs/jbd/journal.c     2005-09-04 23:31:48.000000000 +0900
+++ 2.6.13-mm1/fs/jbd/journal.c 2005-09-04 23:33:19.000000000 +0900
@@ -653,6 +653,7 @@ static journal_t * journal_init_common (
                goto fail;
        memset(journal, 0, sizeof(*journal));
 
+       INIT_LIST_HEAD(&journal->j_checkpoint_transactions);
        init_waitqueue_head(&journal->j_wait_transaction_locked);
        init_waitqueue_head(&journal->j_wait_logspace);
        init_waitqueue_head(&journal->j_wait_done_commit);
@@ -1130,7 +1131,7 @@ void journal_destroy(journal_t *journal)
 
        /* Totally anal locking here... */
        spin_lock(&journal->j_list_lock);
-       while (journal->j_checkpoint_transactions != NULL) {
+       while (!list_empty(&journal->j_checkpoint_transactions)) {
                spin_unlock(&journal->j_list_lock);
                log_do_checkpoint(journal);
                spin_lock(&journal->j_list_lock);
@@ -1138,7 +1139,7 @@ void journal_destroy(journal_t *journal)
 
        J_ASSERT(journal->j_running_transaction == NULL);
        J_ASSERT(journal->j_committing_transaction == NULL);
-       J_ASSERT(journal->j_checkpoint_transactions == NULL);
+       J_ASSERT(list_empty(&journal->j_checkpoint_transactions));
        spin_unlock(&journal->j_list_lock);
 
        /* We can now mark the journal as empty. */
@@ -1352,7 +1353,7 @@ int journal_flush(journal_t *journal)
 
        /* ...and flush everything in the log out to disk. */
        spin_lock(&journal->j_list_lock);
-       while (!err && journal->j_checkpoint_transactions != NULL) {
+       while (!err && !list_empty(&journal->j_checkpoint_transactions)) {
                spin_unlock(&journal->j_list_lock);
                err = log_do_checkpoint(journal);
                spin_lock(&journal->j_list_lock);
@@ -1375,7 +1376,7 @@ int journal_flush(journal_t *journal)
 
        J_ASSERT(!journal->j_running_transaction);
        J_ASSERT(!journal->j_committing_transaction);
-       J_ASSERT(!journal->j_checkpoint_transactions);
+       J_ASSERT(list_empty(&journal->j_checkpoint_transactions));
        J_ASSERT(journal->j_head == journal->j_tail);
        J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence);
        spin_unlock(&journal->j_state_lock);
diff -X 2.6.13-mm1/Documentation/dontdiff -Nurp 
2.6.13-mm1.old/fs/jbd/transaction.c 2.6.13-mm1/fs/jbd/transaction.c
--- 2.6.13-mm1.old/fs/jbd/transaction.c 2005-09-04 23:31:47.000000000 +0900
+++ 2.6.13-mm1/fs/jbd/transaction.c     2005-09-04 23:33:19.000000000 +0900
@@ -59,6 +59,7 @@ get_transaction(journal_t *journal, tran
        INIT_LIST_HEAD(&transaction->t_io_list);
        INIT_LIST_HEAD(&transaction->t_shadow_list);
        INIT_LIST_HEAD(&transaction->t_logctl_list);
+       INIT_LIST_HEAD(&transaction->t_cplist);
 
        /* Set up the commit timer for the new transaction. */
        journal->j_commit_timer->expires = transaction->t_expires;
diff -X 2.6.13-mm1/Documentation/dontdiff -Nurp 
2.6.13-mm1.old/include/linux/jbd.h 2.6.13-mm1/include/linux/jbd.h
--- 2.6.13-mm1.old/include/linux/jbd.h  2005-09-04 23:32:35.000000000 +0900
+++ 2.6.13-mm1/include/linux/jbd.h      2005-09-04 23:33:15.000000000 +0900
@@ -545,7 +545,7 @@ struct transaction_s 
         * Forward and backward links for the circular list of all transactions
         * awaiting checkpoint. [j_list_lock]
         */
-       transaction_t           *t_cpnext, *t_cpprev;
+       struct list_head        t_cplist;
 
        /*
         * When will the transaction expire (become due for commit), in jiffies?
@@ -667,7 +667,7 @@ struct journal_s
         * ... and a linked circular list of all transactions waiting for
         * checkpointing. [j_list_lock]
         */
-       transaction_t           *j_checkpoint_transactions;
+       struct list_head        j_checkpoint_transactions;
 
        /*
         * Wait queue for waiting for a locked transaction to start committing,
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to