All of lore.kernel.org
 help / color / mirror / Atom feed
From: Akinobu Mita <mita@miraclelinux.com>
To: linux-kernel@vger.kernel.org
Cc: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com,
	ext3-users@redhat.com
Subject: [-mm PATCH 6/6] jbd: use list_head for a transaction checkpoint list
Date: Fri, 9 Sep 2005 17:50:07 +0900	[thread overview]
Message-ID: <20050909085007.GH14205@miraclelinux.com> (raw)
In-Reply-To: <20050909084214.GB14205@miraclelinux.com>

use struct list_head for doubly-linked list of buffers still remaining to be
flushed before an old transaction can be checkpointed.

Signed-off-by: Akinobu Mita <mita@miraclelinux.com>

---

 fs/jbd/checkpoint.c          |  119 +++++++------------------------------------
 fs/jbd/commit.c              |    4 -
 fs/jbd/journal.c             |    1 
 fs/jbd/transaction.c         |    2 
 include/linux/jbd.h          |    4 -
 include/linux/journal-head.h |    2 
 6 files changed, 30 insertions(+), 102 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-05 03:21:20.000000000 +0900
+++ 2.6.13-mm1/fs/jbd/checkpoint.c	2005-09-05 03:21:33.000000000 +0900
@@ -22,71 +22,7 @@
 #include <linux/jbd.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-
-/*
- * Unlink a buffer from a transaction checkpoint list.
- *
- * Called with j_list_lock held.
- */
-
-static void __buffer_unlink_first(struct journal_head *jh)
-{
-	transaction_t *transaction;
-
-	transaction = jh->b_cp_transaction;
-
-	jh->b_cpnext->b_cpprev = jh->b_cpprev;
-	jh->b_cpprev->b_cpnext = jh->b_cpnext;
-	if (transaction->t_checkpoint_list == jh) {
-		transaction->t_checkpoint_list = jh->b_cpnext;
-		if (transaction->t_checkpoint_list == jh)
-			transaction->t_checkpoint_list = NULL;
-	}
-}
-
-/*
- * Unlink a buffer from a transaction checkpoint(io) list.
- *
- * Called with j_list_lock held.
- */
-
-static inline void __buffer_unlink(struct journal_head *jh)
-{
-	transaction_t *transaction;
-
-	transaction = jh->b_cp_transaction;
-
-	__buffer_unlink_first(jh);
-	if (transaction->t_checkpoint_io_list == jh) {
-		transaction->t_checkpoint_io_list = jh->b_cpnext;
-		if (transaction->t_checkpoint_io_list == jh)
-			transaction->t_checkpoint_io_list = NULL;
-	}
-}
-
-/*
- * Move a buffer from the checkpoint list to the checkpoint io list
- *
- * Called with j_list_lock held
- */
-
-static inline void __buffer_relink_io(struct journal_head *jh)
-{
-	transaction_t *transaction;
-
-	transaction = jh->b_cp_transaction;
-	__buffer_unlink_first(jh);
-
-	if (!transaction->t_checkpoint_io_list) {
-		jh->b_cpnext = jh->b_cpprev = jh;
-	} else {
-		jh->b_cpnext = transaction->t_checkpoint_io_list;
-		jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev;
-		jh->b_cpprev->b_cpnext = jh;
-		jh->b_cpnext->b_cpprev = jh;
-	}
-	transaction->t_checkpoint_io_list = jh;
-}
+#include <linux/list.h>
 
 /*
  * Try to release a checkpointed buffer from its transaction.
@@ -185,8 +121,9 @@ restart:
 			t_cplist) != transaction ||
 	    transaction->t_tid != this_tid)
 		return;
-	while (!released && transaction->t_checkpoint_io_list) {
-		jh = transaction->t_checkpoint_io_list;
+	while (!released && !list_empty(&transaction->t_checkpoint_io_list)) {
+		jh = list_entry(transaction->t_checkpoint_io_list.next,
+				struct journal_head, b_cplist);
 		bh = jh2bh(jh);
 		if (!jbd_trylock_bh_state(bh)) {
 			jbd_sync_bh(journal, bh);
@@ -288,7 +225,9 @@ static int __process_buffer(journal_t *j
 		J_ASSERT_BH(bh, !buffer_jwrite(bh));
 		set_buffer_jwrite(bh);
 		bhs[*batch_count] = bh;
-		__buffer_relink_io(jh);
+		list_del(&jh->b_cplist);
+		list_add(&jh->b_cplist,
+			 &jh->b_cp_transaction->t_checkpoint_io_list);
 		jbd_unlock_bh_state(bh);
 		(*batch_count)++;
 		if (*batch_count == NR_BATCH) {
@@ -350,10 +289,11 @@ restart:
 		struct journal_head *jh;
 		int retry = 0;
 
-		while (!retry && transaction->t_checkpoint_list) {
+		while (!retry && !list_empty(&transaction->t_checkpoint_list)) {
 			struct buffer_head *bh;
 
-			jh = transaction->t_checkpoint_list;
+			jh = list_entry(transaction->t_checkpoint_list.next,
+					struct journal_head, b_cplist);
 			bh = jh2bh(jh);
 			if (!jbd_trylock_bh_state(bh)) {
 				jbd_sync_bh(journal, bh);
@@ -488,20 +428,14 @@ int cleanup_journal_tail(journal_t *jour
  * Returns number of bufers reaped (for debug)
  */
 
-static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
+static int journal_clean_one_cp_list(struct list_head *head, int *released)
 {
-	struct journal_head *last_jh;
-	struct journal_head *next_jh = jh;
+	struct journal_head *jh, *next_jh;
 	int ret, freed = 0;
 
 	*released = 0;
-	if (!jh)
-		return 0;
 
- 	last_jh = jh->b_cpprev;
-	do {
-		jh = next_jh;
-		next_jh = jh->b_cpnext;
+	list_for_each_entry_safe(jh, next_jh, head, b_cplist) {
 		/* Use trylock because of the ranking */
 		if (jbd_trylock_bh_state(jh2bh(jh))) {
 			ret = __try_to_free_cp_buf(jh);
@@ -520,7 +454,7 @@ static int journal_clean_one_cp_list(str
 		 */
 		if (need_resched())
 			return freed;
-	} while (jh != last_jh);
+	}
 
 	return freed;
 }
@@ -542,7 +476,7 @@ int __journal_clean_checkpoint_list(jour
 
 	list_for_each_entry_safe(transaction, next_transaction,
 				&journal->j_checkpoint_transactions, t_cplist) {
-		ret += journal_clean_one_cp_list(transaction->
+		ret += journal_clean_one_cp_list(&transaction->
 				t_checkpoint_list, &released);
 		if (need_resched())
 			goto out;
@@ -553,7 +487,7 @@ int __journal_clean_checkpoint_list(jour
 		 * t_checkpoint_list with removing the buffer from the list as
 		 * we can possibly see not yet submitted buffers on io_list
 		 */
-		ret += journal_clean_one_cp_list(transaction->
+		ret += journal_clean_one_cp_list(&transaction->
 				t_checkpoint_io_list, &released);
 		if (need_resched())
 			goto out;
@@ -596,11 +530,11 @@ int __journal_remove_checkpoint(struct j
 	}
 	journal = transaction->t_journal;
 
-	__buffer_unlink(jh);
+	list_del(&jh->b_cplist);
 	jh->b_cp_transaction = NULL;
 
-	if (transaction->t_checkpoint_list != NULL ||
-	    transaction->t_checkpoint_io_list != NULL)
+	if (!list_empty(&transaction->t_checkpoint_list) ||
+	    !list_empty(&transaction->t_checkpoint_io_list))
 		goto out;
 	JBUFFER_TRACE(jh, "transaction has no more buffers");
 
@@ -648,16 +582,7 @@ void __journal_insert_checkpoint(struct 
 	J_ASSERT_JH(jh, jh->b_cp_transaction == NULL);
 
 	jh->b_cp_transaction = transaction;
-
-	if (!transaction->t_checkpoint_list) {
-		jh->b_cpnext = jh->b_cpprev = jh;
-	} else {
-		jh->b_cpnext = transaction->t_checkpoint_list;
-		jh->b_cpprev = transaction->t_checkpoint_list->b_cpprev;
-		jh->b_cpprev->b_cpnext = jh;
-		jh->b_cpnext->b_cpprev = jh;
-	}
-	transaction->t_checkpoint_list = jh;
+	list_add(&jh->b_cplist, &transaction->t_checkpoint_list);
 }
 
 /*
@@ -682,8 +607,8 @@ void __journal_drop_transaction(journal_
 	J_ASSERT(list_empty(&transaction->t_io_list));
 	J_ASSERT(list_empty(&transaction->t_shadow_list));
 	J_ASSERT(list_empty(&transaction->t_logctl_list));
-	J_ASSERT(transaction->t_checkpoint_list == NULL);
-	J_ASSERT(transaction->t_checkpoint_io_list == NULL);
+	J_ASSERT(list_empty(&transaction->t_checkpoint_list));
+	J_ASSERT(list_empty(&transaction->t_checkpoint_io_list));
 	J_ASSERT(transaction->t_updates == 0);
 	J_ASSERT(journal->j_committing_transaction != transaction);
 	J_ASSERT(journal->j_running_transaction != transaction);
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-05 03:21:20.000000000 +0900
+++ 2.6.13-mm1/fs/jbd/commit.c	2005-09-05 03:21:33.000000000 +0900
@@ -714,7 +714,7 @@ wait_for_iobuf:
 
 	J_ASSERT(list_empty(&commit_transaction->t_syncdata_list));
 	J_ASSERT(list_empty(&commit_transaction->t_metadata_list));
-	J_ASSERT(commit_transaction->t_checkpoint_list == NULL);
+	J_ASSERT(list_empty(&commit_transaction->t_checkpoint_list));
 	J_ASSERT(list_empty(&commit_transaction->t_io_list));
 	J_ASSERT(list_empty(&commit_transaction->t_shadow_list));
 	J_ASSERT(list_empty(&commit_transaction->t_logctl_list));
@@ -832,7 +832,7 @@ restart_loop:
 	journal->j_committing_transaction = NULL;
 	spin_unlock(&journal->j_state_lock);
 
-	if (commit_transaction->t_checkpoint_list == NULL) {
+	if (list_empty(&commit_transaction->t_checkpoint_list)) {
 		__journal_drop_transaction(journal, commit_transaction);
 	} else {
 		list_add_tail(&commit_transaction->t_cplist,
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-05 03:21:20.000000000 +0900
+++ 2.6.13-mm1/fs/jbd/journal.c	2005-09-05 03:21:36.000000000 +0900
@@ -1763,6 +1763,7 @@ repeat:
 		bh->b_private = jh;
 		jh->b_bh = bh;
 		INIT_LIST_HEAD(&jh->b_list);
+		INIT_LIST_HEAD(&jh->b_cplist);
 		get_bh(bh);
 		BUFFER_TRACE(bh, "added journal_head");
 	}
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-05 03:21:20.000000000 +0900
+++ 2.6.13-mm1/fs/jbd/transaction.c	2005-09-05 03:21:36.000000000 +0900
@@ -60,6 +60,8 @@ get_transaction(journal_t *journal, tran
 	INIT_LIST_HEAD(&transaction->t_shadow_list);
 	INIT_LIST_HEAD(&transaction->t_logctl_list);
 	INIT_LIST_HEAD(&transaction->t_cplist);
+	INIT_LIST_HEAD(&transaction->t_checkpoint_list);
+	INIT_LIST_HEAD(&transaction->t_checkpoint_io_list);
 
 	/* 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-05 03:21:20.000000000 +0900
+++ 2.6.13-mm1/include/linux/jbd.h	2005-09-05 03:21:33.000000000 +0900
@@ -497,13 +497,13 @@ struct transaction_s 
 	 * Doubly-linked circular list of all buffers still to be flushed before
 	 * this transaction can be checkpointed. [j_list_lock]
 	 */
-	struct journal_head	*t_checkpoint_list;
+	struct list_head	t_checkpoint_list;
 
 	/*
 	 * Doubly-linked circular list of all buffers submitted for IO while
 	 * checkpointing. [j_list_lock]
 	 */
-	struct journal_head	*t_checkpoint_io_list;
+	struct list_head	t_checkpoint_io_list;
 
 	/*
 	 * Doubly-linked circular list of temporary buffers currently undergoing
diff -X 2.6.13-mm1/Documentation/dontdiff -Nurp 2.6.13-mm1.old/include/linux/journal-head.h 2.6.13-mm1/include/linux/journal-head.h
--- 2.6.13-mm1.old/include/linux/journal-head.h	2005-09-05 03:20:41.000000000 +0900
+++ 2.6.13-mm1/include/linux/journal-head.h	2005-09-05 03:21:33.000000000 +0900
@@ -86,7 +86,7 @@ struct journal_head {
 	 * before an old transaction can be checkpointed.
 	 * [j_list_lock]
 	 */
-	struct journal_head *b_cpnext, *b_cpprev;
+	struct list_head b_cplist;
 };
 
 #endif		/* JOURNAL_HEAD_H_INCLUDED */

  parent reply	other threads:[~2005-09-09  8:53 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-09-09  8:42 [PATCH 0/6] jbd cleanup Akinobu Mita
2005-09-09  8:43 ` [PATCH 1/6] jbd: remove duplicated debug print Akinobu Mita
2005-09-09 18:16   ` Theodore Ts'o
2005-09-10 14:36     ` Akinobu Mita
2005-09-09  8:44 ` [PATCH 2/6] jbd: use hlist for the revoke tables Akinobu Mita
2005-09-09  8:46 ` [PATCH 3/6] jbd: cleanup for initializing/destroying " Akinobu Mita
2005-09-09  8:47 ` [PATCH 4/6] jbd: use list_head for the list of buffers on a transaction's data Akinobu Mita
2005-09-09  8:48 ` [-mm PATCH 5/6] jbd: use list_head for the list of all transactions waiting for Akinobu Mita
2005-09-09  8:50 ` Akinobu Mita [this message]
2005-09-09  9:15 ` [PATCH 0/6] jbd cleanup Andrew Morton
2005-09-10 14:55   ` Akinobu Mita
2005-09-10 21:58     ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050909085007.GH14205@miraclelinux.com \
    --to=mita@miraclelinux.com \
    --cc=adilger@clusterfs.com \
    --cc=akpm@osdl.org \
    --cc=ext3-users@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sct@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.